@kirrosh/zond 0.23.0 → 0.26.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.
Files changed (158) hide show
  1. package/CHANGELOG.md +164 -1
  2. package/README.md +8 -7
  3. package/package.json +2 -3
  4. package/src/CLAUDE.md +112 -0
  5. package/src/cli/commands/add-api.ts +19 -7
  6. package/src/cli/commands/api/annotate/index.ts +359 -4
  7. package/src/cli/commands/api/annotate/lifecycle.ts +1 -1
  8. package/src/cli/commands/api/annotate/overlay.ts +1 -1
  9. package/src/cli/commands/api/annotate/pagination.ts +10 -6
  10. package/src/cli/commands/api/annotate/prompts.ts +39 -2
  11. package/src/cli/commands/audit.ts +360 -54
  12. package/src/cli/commands/check.ts +15 -2
  13. package/src/cli/commands/checks.ts +352 -36
  14. package/src/cli/commands/cleanup.ts +4 -30
  15. package/src/cli/commands/coverage.ts +275 -57
  16. package/src/cli/commands/db.ts +311 -8
  17. package/src/cli/commands/discover.ts +281 -161
  18. package/src/cli/commands/doctor.ts +57 -3
  19. package/src/cli/commands/fixtures.ts +1 -1
  20. package/src/cli/commands/generate.ts +24 -7
  21. package/src/cli/commands/init/bootstrap.ts +4 -1
  22. package/src/cli/commands/init/index.ts +2 -2
  23. package/src/cli/commands/init/skills.ts +43 -0
  24. package/src/cli/commands/init/templates/agents.md +12 -3
  25. package/src/cli/commands/init/templates/skills/warm-up-target.md +122 -0
  26. package/src/cli/commands/init/templates/skills/zond-checks.md +268 -44
  27. package/src/cli/commands/init/templates/skills/zond-seed.md +114 -0
  28. package/src/cli/commands/init/templates/skills/zond-triage.md +88 -26
  29. package/src/cli/commands/init/templates/skills/zond.md +274 -64
  30. package/src/cli/commands/init/templates/zond-config.yml +1 -1
  31. package/src/cli/commands/prepare-fixtures.ts +14 -52
  32. package/src/cli/commands/probe/_seed-bodies.ts +52 -0
  33. package/src/cli/commands/probe/mass-assignment.ts +101 -10
  34. package/src/cli/commands/probe/security.ts +95 -12
  35. package/src/cli/commands/probe/webhooks.ts +2 -0
  36. package/src/cli/commands/probe.ts +87 -11
  37. package/src/cli/commands/refresh-api.ts +59 -1
  38. package/src/cli/commands/report-bundle.ts +3 -11
  39. package/src/cli/commands/request.ts +116 -0
  40. package/src/cli/commands/run.ts +33 -5
  41. package/src/cli/commands/schema-from-runs.ts +128 -0
  42. package/src/cli/commands/secrets.ts +133 -0
  43. package/src/cli/json-envelope.ts +0 -20
  44. package/src/cli/json-schemas.ts +51 -0
  45. package/src/cli/output.ts +17 -1
  46. package/src/cli/program.ts +5 -4
  47. package/src/cli/safe-live.ts +24 -0
  48. package/src/cli/status-filter.ts +0 -10
  49. package/src/core/audit/persist.ts +183 -0
  50. package/src/core/checks/budget.ts +59 -0
  51. package/src/core/checks/checks/cross_call_references.ts +17 -4
  52. package/src/core/checks/checks/cursor_boundary_fuzzing.ts +219 -0
  53. package/src/core/checks/checks/idempotency_replay.ts +1 -5
  54. package/src/core/checks/checks/ignored_auth.ts +44 -1
  55. package/src/core/checks/checks/index.ts +3 -0
  56. package/src/core/checks/checks/lifecycle_transitions.ts +169 -26
  57. package/src/core/checks/checks/negative_data_rejection.ts +119 -16
  58. package/src/core/checks/checks/not_a_server_error.ts +8 -0
  59. package/src/core/checks/checks/open_cors_on_sensitive.ts +47 -18
  60. package/src/core/checks/checks/pagination_invariants.ts +298 -117
  61. package/src/core/checks/checks/positive_data_acceptance.ts +1 -4
  62. package/src/core/checks/checks/status_code_conformance.ts +78 -7
  63. package/src/core/checks/mode.ts +3 -0
  64. package/src/core/checks/recommended-action.ts +5 -1
  65. package/src/core/checks/runner.ts +614 -27
  66. package/src/core/checks/spec-findings.ts +308 -0
  67. package/src/core/checks/types.ts +117 -1
  68. package/src/core/checks/zond-extensions.ts +73 -0
  69. package/src/core/classifier/recommended-action.ts +35 -6
  70. package/src/core/coverage/loader.ts +31 -0
  71. package/src/core/diagnostics/db-analysis.ts +200 -106
  72. package/src/core/diagnostics/failure-class.ts +21 -1
  73. package/src/core/diagnostics/failure-hints.ts +4 -208
  74. package/src/core/diagnostics/suggested-fixes.ts +2 -3
  75. package/src/core/generator/chunker.ts +1 -8
  76. package/src/core/generator/data-factory.ts +199 -61
  77. package/src/core/generator/fixtures-builder.ts +38 -31
  78. package/src/core/generator/index.ts +0 -2
  79. package/src/core/generator/openapi-reader.ts +98 -4
  80. package/src/core/generator/path-param-disambig.ts +30 -4
  81. package/src/core/generator/resources-builder.ts +276 -26
  82. package/src/core/generator/schema-utils.ts +22 -0
  83. package/src/core/generator/suite-generator.ts +168 -15
  84. package/src/core/generator/types.ts +6 -0
  85. package/src/core/identity/identity-file.ts +0 -0
  86. package/src/core/output/README.md +11 -29
  87. package/src/core/output/index.ts +1 -1
  88. package/src/core/output/run.ts +0 -35
  89. package/src/core/output/types.ts +0 -7
  90. package/src/core/parser/dynamic-values.ts +160 -0
  91. package/src/core/parser/variables.ts +0 -0
  92. package/src/core/probe/dry-run-envelope.ts +4 -0
  93. package/src/core/probe/mass-assignment/classify.ts +175 -0
  94. package/src/core/probe/mass-assignment/cleanup.ts +52 -0
  95. package/src/core/probe/mass-assignment/digest.ts +114 -0
  96. package/src/core/probe/mass-assignment/orchestrator.ts +459 -0
  97. package/src/core/probe/mass-assignment/regression.ts +141 -0
  98. package/src/core/probe/mass-assignment/suspects.ts +92 -0
  99. package/src/core/probe/mass-assignment/types.ts +135 -0
  100. package/src/core/probe/mass-assignment-probe.ts +23 -1118
  101. package/src/core/probe/mass-assignment-template.ts +32 -4
  102. package/src/core/probe/path-discovery.ts +3 -4
  103. package/src/core/probe/probe-harness.ts +21 -22
  104. package/src/core/probe/security/baseline.ts +174 -0
  105. package/src/core/probe/security/classify.ts +341 -0
  106. package/src/core/probe/security/cleanup.ts +125 -0
  107. package/src/core/probe/security/detectors.ts +71 -0
  108. package/src/core/probe/security/digest.ts +104 -0
  109. package/src/core/probe/security/orchestrator.ts +398 -0
  110. package/src/core/probe/security/regression.ts +103 -0
  111. package/src/core/probe/security/types.ts +151 -0
  112. package/src/core/probe/security-probe-class.ts +8 -2
  113. package/src/core/probe/security-probe.ts +28 -1449
  114. package/src/core/probe/shared.ts +26 -0
  115. package/src/core/probe/webhooks-probe.ts +5 -7
  116. package/src/core/runner/assertions.ts +1 -1
  117. package/src/core/runner/executor.ts +3 -18
  118. package/src/core/runner/form-encode.ts +8 -18
  119. package/src/core/runner/http-client.ts +38 -1
  120. package/src/core/runner/preflight-vars.ts +19 -15
  121. package/src/core/runner/rate-limiter.ts +11 -29
  122. package/src/core/runner/run-kind.ts +7 -1
  123. package/src/core/runner/schema-validator.ts +2 -6
  124. package/src/core/runner/send-request.ts +11 -6
  125. package/src/core/runner/types.ts +6 -0
  126. package/src/core/setup-api.ts +53 -15
  127. package/src/core/severity/index.ts +0 -63
  128. package/src/core/spec/infer-schema.ts +102 -0
  129. package/src/core/spec/merge-specs.ts +156 -0
  130. package/src/core/spec/schema-from-runs.ts +117 -0
  131. package/src/core/spec/schema-overlay.ts +130 -0
  132. package/src/core/util/ajv.ts +13 -0
  133. package/src/core/util/headers.ts +9 -0
  134. package/src/core/util/url.ts +24 -0
  135. package/src/core/workspace/fixture-gap-report.ts +84 -0
  136. package/src/core/workspace/fixture-gaps.ts +71 -0
  137. package/src/core/workspace/root.ts +13 -11
  138. package/src/db/migrate.ts +2 -0
  139. package/src/db/migrations/0002_run_kind_request.sql +59 -0
  140. package/src/db/queries/collections.ts +2 -2
  141. package/src/db/queries/results.ts +88 -0
  142. package/src/db/queries/runs.ts +56 -2
  143. package/src/db/queries.ts +3 -0
  144. package/src/db/schema.ts +7 -7
  145. package/src/cli/commands/bootstrap.ts +0 -710
  146. package/src/core/anti-fp/bootstrap.ts +0 -34
  147. package/src/core/anti-fp/index.ts +0 -33
  148. package/src/core/anti-fp/registry.ts +0 -44
  149. package/src/core/anti-fp/rules/baseline-echo.ts +0 -74
  150. package/src/core/anti-fp/rules/schemathesis/body_negation_becomes_valid.ts +0 -52
  151. package/src/core/anti-fp/rules/schemathesis/coverage_phase_boundary_positive.ts +0 -38
  152. package/src/core/anti-fp/rules/schemathesis/has_unverifiable_mutations.ts +0 -35
  153. package/src/core/anti-fp/rules/schemathesis/index.ts +0 -24
  154. package/src/core/anti-fp/rules/schemathesis/string_type_mutation_becomes_valid.ts +0 -53
  155. package/src/core/anti-fp/rules/subscription-gated/index.ts +0 -11
  156. package/src/core/anti-fp/rules/subscription-gated/paid-plan-403.ts +0 -75
  157. package/src/core/anti-fp/types.ts +0 -68
  158. package/src/core/generator/create-body.ts +0 -89
@@ -34,11 +34,9 @@ scenarios; this one only reads.
34
34
  command — don't pad with "consider checking...".
35
35
  - **`report_backend_bug` / 5xx → STOP, surface, do not edit `expect:`.**
36
36
  Same iron rule as the parent `zond` skill.
37
- - **`fix_env` overrides `fix_test_logic` at the suite level.** `db
38
- diagnose` already does this collapse (TASK-70/98) — trust the field
39
- it returns, don't merge again client-side.
40
37
  - **Never read raw response bodies past 8 KB.** The diagnose envelope
41
- truncates by default; pass `--no-body-cap` only if the user is
38
+ truncates by default; to see full bodies, bundle the run instead
39
+ (`zond report bundle <id> --no-body-cap`) — only when the user is
42
40
  triaging body-shape bugs.
43
41
  - **Никогда не выдавать абстрактные «проверьте логи» / «уточните у
44
42
  команды».** Если в enum-группе нет конкретного действия — пометить
@@ -50,7 +48,7 @@ scenarios; this one only reads.
50
48
  |---|---|---|
51
49
  | `zond db diagnose <run-id> --json` | per-failure under `data.failures[]` | every fail/error in the run |
52
50
  | `zond check spec --api <name> --json` | `data.issues[]` | every lint Issue (always `fix_spec`) |
53
- | `zond probe mass-assignment --json` | `data.verdicts[]` | per-endpoint verdicts (high/medium/inconclusive-5xx/inconclusive-baseline) |
51
+ | `zond probe mass-assignment --json` | `data.endpoints[]` (action under `findings[].evidence.recommended_action`) | per-endpoint verdicts (high/medium/inconclusive-5xx/inconclusive-baseline) |
54
52
  | `zond probe security --json` | counts only — read the markdown digest | high / low findings (markdown table) |
55
53
  | `zond probe static --json` | `data.files[]` (suite YAMLs to run) | findings surface only after `zond run` → routed via diagnose |
56
54
 
@@ -70,7 +68,17 @@ zond db runs --limit 5 --json # pick a non-default run id
70
68
 
71
69
  If `trigger=ci`, mention the CI build in the summary. If the user said
72
70
  "после моего фикса", take the second-most-recent and pair with
73
- `zond db compare <prev> <curr> --json` for a regression diff.
71
+ `zond db compare <prev> <curr> --json` for a regression diff. Besides
72
+ status transitions, the payload carries `.data.body_changes[]` (ARV-339) —
73
+ per-test field-level response-shape diff (`added` / `removed` /
74
+ `type_changed`), i.e. how the contract moved even where status stayed green.
75
+ Each change carries `scope` (ARV-352): `container` = response envelope /
76
+ pagination skeleton (real drift), `element` = a field inside a collection
77
+ item (path crosses `[]`). On list/log endpoints two runs return DIFFERENT
78
+ objects, so `element`-scoped changes are schema-of-union variance across the
79
+ re-sampled set — NOT contract drift. `summary.bodyChangesContainer` /
80
+ `bodyChangesElement` split the count so you can tell "12 field diffs, all
81
+ element-scope on /v1/events" (data variance) from real envelope drift.
74
82
 
75
83
  ## Phase 2 — pull the diagnose envelope
76
84
 
@@ -78,6 +86,12 @@ If `trigger=ci`, mention the CI build in the summary. If the user said
78
86
  zond db diagnose --json # last failing run (default — TASK-266)
79
87
  zond db diagnose <run-id> --json # explicit run
80
88
  zond db diagnose --latest --json # last run, even if it passed
89
+ zond db diagnose --report yaml # same payload as YAML (ARV-338) — for run snapshots you keep/diff as text
90
+ # ARV-380: aggregate by_recommended_action across a run SET (same --union
91
+ # vocabulary as `zond coverage`) instead of looping per run and merging:
92
+ zond db diagnose --union session --json # all runs in the active session
93
+ zond db diagnose --union since:2h --api <name> --json # runs in a time window (scoped to a collection)
94
+ zond db diagnose --union runs:263,266,269 --json # an explicit run-id set
81
95
  ```
82
96
 
83
97
  The shape (relevant fields only):
@@ -88,7 +102,6 @@ The shape (relevant fields only):
88
102
  "data": {
89
103
  "run_id": 42,
90
104
  "summary": { "passed": 18, "failed": 7, "errored": 1 },
91
- "env_issue": { "scope": "suite", "affected_suites": [...], "message": "..." },
92
105
  "failures": [
93
106
  {
94
107
  "suite_name": "crud-projects",
@@ -97,9 +110,7 @@ The shape (relevant fields only):
97
110
  "recommended_action": "report_backend_bug",
98
111
  "request_method": "POST",
99
112
  "request_url": "...",
100
- "response_status": 500,
101
- "hint": "...",
102
- "schema_hint": "..."
113
+ "response_status": 500
103
114
  }
104
115
  ]
105
116
  }
@@ -115,21 +126,24 @@ priority first):
115
126
  then `zond refresh-api <name>`.
116
127
  3. `fix_auth_config` — 401/403 cluster. Check `auth_token` scope (or run
117
128
  `zond doctor --api <name> --missing-only`).
118
- 4. `fix_env` — env_issue cluster. Print `env_issue.message` verbatim;
119
- point at `.env.yaml` (path is in the envelope).
129
+ 4. `fix_env` — unresolved variables / broken base_url. Point at
130
+ `.env.yaml` and the failing `request_url` values (unresolved
131
+ `{{var}}` placeholders are visible right in them).
120
132
  5. `fix_fixture` — `prepare-fixtures` miss-* or inconclusive-baseline
121
- from mass-assignment. Run
122
- `zond prepare-fixtures --api <name> --apply [--cascade [--seed]]`. If
123
- the run was post-probe and IDs may be stale, prefer
124
- `prepare-fixtures --refresh` (TASK-281) and follow with `zond cleanup
125
- --orphans` (TASK-278) before retrying.
133
+ from mass-assignment. Run `zond prepare-fixtures --api <name> --apply`
134
+ (single-pass); fill any remaining gaps by hand (`fixtures add` /
135
+ editing `.env.yaml`). If the run was post-probe and IDs may be stale,
136
+ prefer `prepare-fixtures --refresh` (TASK-281) and follow with `zond
137
+ cleanup --orphans` (TASK-278) before retrying.
126
138
  6. `fix_network_config` — connect-refused / DNS / TLS. Check `base_url`
127
139
  reachability; `--proxy` may be needed.
128
140
  7. `regenerate_suite` (ARV-42) — 4xx (400/422) on a generator-emitted
129
- suite under `apis/<name>/tests/`. Editing the YAML is wrong: the
130
- next `zond audit` overwrites it. Re-run `zond generate --api <name>`
131
- so newer heuristics apply (e.g. ARV-38 default-string), or refine
132
- `.api-resources.yaml` hints when the body shape can't be inferred.
141
+ suite under `apis/<name>/tests/`. Prefer re-running `zond generate
142
+ --api <name>` so newer generation applies (e.g. ARV-38 default-string),
143
+ or refine `.api-resources.yaml` hints when the body shape can't be
144
+ inferred. If you DO hand-edit the YAML, delete its `# Auto-generated`
145
+ header so regenerate preserves it (ARV-361) — otherwise a re-run
146
+ regenerates it; `--force` overwrites even header-stripped files.
133
147
  8. `fix_test_logic` — 4xx (400/422) on a manually-authored suite, or any
134
148
  leftover assertion failure not absorbed by the buckets above. Phase 4a
135
149
  of the `zond` skill: fixture pack first, typed generator second,
@@ -139,6 +153,42 @@ Within each bucket, collapse by `(suite_name, response_status,
139
153
  request_method, root_cause)` and report a count + 1-2 examples. Do
140
154
  **not** dump every failure.
141
155
 
156
+ ### Shortcut: `by_recommended_action` envelope (ARV-101/ARV-228)
157
+
158
+ `zond db diagnose --json` ships a pre-aggregated envelope keyed by the
159
+ `recommended_action` enum so triage agents skip the `jq | group_by`
160
+ step. Each bucket carries up to 5 examples with full request context
161
+ (method, path, status, trimmed reason) — enough to render the output
162
+ template below without re-fetching `failures[]`.
163
+
164
+ Shape (extracted from `.data.by_recommended_action`):
165
+
166
+ ```jsonc
167
+ {
168
+ "fix_auth_config": {
169
+ "count": 4,
170
+ "examples": [
171
+ {
172
+ "suite": "github-smoke",
173
+ "test": "GetNotifications",
174
+ "method": "GET",
175
+ "path": "/notifications",
176
+ "status": 401,
177
+ "reason": "expected 200, got 401"
178
+ }
179
+ // … up to 5 entries
180
+ ]
181
+ },
182
+ "report_backend_bug": { "count": 12, "examples": [ … ] }
183
+ }
184
+ ```
185
+
186
+ Iterate the priority order in the table above (`report_backend_bug` →
187
+ `fix_test_logic`); for each present key, `count + examples` is enough
188
+ to build the per-bucket section. Fall back to `failures[]` only when
189
+ you need details outside the example slice (full response body, the
190
+ 6th example, etc).
191
+
142
192
  ## Phase 3 — reconcile spec / probe sources
143
193
 
144
194
  Run only what the user's question implies — don't fan out blindly.
@@ -156,6 +206,18 @@ For `probe security`, the digest is the source. Read the file the user
156
206
  named (or `apis/<name>/probes/security-digest.md`) and pull HIGH rows
157
207
  plus the `## ⚠️ Cleanup failures` section if present.
158
208
 
209
+ ### Cross-phase double-emit (ARV-358)
210
+
211
+ A single backend defect surfaces in more than one phase stream, so a naive
212
+ HIGH count over-reports. The `checks` phase (`30-checks.ndjson`, e.g.
213
+ `not_a_server_error`) and the `stateful` phase (`40-stateful.ndjson`, e.g.
214
+ `cursor_boundary_fuzzing`) can both flag the *same* endpoint 5xx — that's
215
+ one defect counted 3–4×. zond does NOT dedup this for you: the check_ids
216
+ differ, so collapsing them is a "same root cause" judgment (attribution),
217
+ which is your job, not the tool's. When counting, **group by `(method,
218
+ path, status)` across phase streams**, not by raw finding count — one
219
+ `GET /v1/billing/alerts → 500` is one defect even if it appears 4 times.
220
+
159
221
  ## Output template
160
222
 
161
223
  Stay terse. Russian by default, mirror the user's language.
@@ -174,11 +236,11 @@ Pass <N> Fail <M> Error <K> Coverage <pct>%
174
236
  · 4 suites all 401 — check auth_token scope
175
237
  next: zond doctor --api <name> --missing-only
176
238
  🌐 fix_env ×<n>
177
- · base_url unset (env_issue.scope=run)
239
+ · base_url unset — request_url resolved to "/v1/projects"
178
240
  next: edit apis/<name>/.env.yaml → base_url
179
241
  📥 fix_fixture ×<n>
180
242
  · {{audience_id}} unresolved
181
- next: zond prepare-fixtures --api <name> --apply --cascade
243
+ next: zond prepare-fixtures --api <name> (reports the gap; fill it via `fixtures add` / .env.yaml)
182
244
  📜 fix_spec ×<n> (from check spec)
183
245
  · A2 missing operationId on POST /webhooks
184
246
  next: edit spec.json → operationId, then zond refresh-api <name>
@@ -190,9 +252,9 @@ say "all green" and exit — don't invent work.
190
252
  ## When to escalate
191
253
 
192
254
  - **Mixed recommended_action inside one suite (>3 distinct enums):**
193
- the run was probably aborted mid-setup. Check `env_issue` first; if
194
- not set, the run hit a fatal early failure — `zond db run <id>
195
- --status 500 --first-only --json` to find it.
255
+ the run was probably aborted mid-setup. Look for unresolved `{{var}}`
256
+ in `request_url` first; if none, the run hit a fatal early failure —
257
+ `zond db run <id> --status 500 --json` to find it.
196
258
  - **Cleanup failures from `probe security`:** call out at the **top** —
197
259
  this means probe mutated state it could not restore. Treat as
198
260
  blocking; do not run more probes against the same env until the