@kirrosh/zond 0.22.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.
- package/CHANGELOG.md +811 -0
- package/README.md +59 -6
- package/package.json +9 -7
- package/src/CLAUDE.md +112 -0
- package/src/cli/argv.ts +122 -0
- package/src/cli/commands/add-api.ts +146 -0
- package/src/cli/commands/api/annotate/idempotency.ts +59 -0
- package/src/cli/commands/api/annotate/index.ts +880 -0
- package/src/cli/commands/api/annotate/lifecycle.ts +74 -0
- package/src/cli/commands/api/annotate/overlay.ts +206 -0
- package/src/cli/commands/api/annotate/pagination.ts +64 -0
- package/src/cli/commands/api/annotate/prompts.ts +220 -0
- package/src/cli/commands/api/annotate/readback.ts +58 -0
- package/src/cli/commands/api/annotate/resources.ts +91 -0
- package/src/cli/commands/api/annotate/seed-bodies.ts +61 -0
- package/src/cli/commands/audit.ts +786 -0
- package/src/cli/commands/catalog.ts +35 -0
- package/src/cli/commands/check.ts +361 -0
- package/src/cli/commands/checks.ts +1072 -0
- package/src/cli/commands/ci-init.ts +43 -0
- package/src/cli/commands/clean.ts +212 -0
- package/src/cli/commands/cleanup.ts +236 -0
- package/src/cli/commands/completions.ts +16 -0
- package/src/cli/commands/coverage.ts +823 -132
- package/src/cli/commands/db.ts +486 -12
- package/src/cli/commands/describe.ts +37 -2
- package/src/cli/commands/discover.ts +1356 -0
- package/src/cli/commands/doctor.ts +661 -0
- package/src/cli/commands/fixtures.ts +402 -0
- package/src/cli/commands/generate.ts +438 -47
- package/src/cli/commands/init/bootstrap.ts +34 -2
- package/src/cli/commands/{init.ts → init/index.ts} +99 -5
- package/src/cli/commands/init/skills.ts +99 -3
- package/src/cli/commands/init/templates/agents.md +77 -64
- package/src/cli/commands/init/templates/skills/warm-up-target.md +122 -0
- package/src/cli/commands/init/templates/skills/zond-checks.md +621 -0
- package/src/cli/commands/init/templates/skills/zond-seed.md +114 -0
- package/src/cli/commands/init/templates/skills/zond-triage.md +272 -0
- package/src/cli/commands/init/templates/skills/zond.md +802 -125
- package/src/cli/commands/init/templates/zond-config.yml +8 -9
- package/src/cli/commands/prepare-fixtures.ts +97 -0
- package/src/cli/commands/probe/_seed-bodies.ts +52 -0
- package/src/cli/commands/probe/mass-assignment.ts +594 -0
- package/src/cli/commands/probe/security.ts +537 -0
- package/src/cli/commands/probe/static.ts +255 -0
- package/src/cli/commands/probe/webhooks.ts +163 -0
- package/src/cli/commands/probe.ts +535 -0
- package/src/cli/commands/reference.ts +87 -0
- package/src/cli/commands/refresh-api.ts +227 -0
- package/src/cli/commands/remove-api.ts +150 -0
- package/src/cli/commands/report-bundle.ts +310 -0
- package/src/cli/commands/report.ts +241 -0
- package/src/cli/commands/request.ts +495 -4
- package/src/cli/commands/run.ts +870 -53
- package/src/cli/commands/schema-from-runs.ts +128 -0
- package/src/cli/commands/secrets.ts +133 -0
- package/src/cli/commands/session.ts +244 -0
- package/src/cli/commands/use.ts +18 -1
- package/src/cli/index.ts +20 -3
- package/src/cli/json-envelope.ts +92 -3
- package/src/cli/json-schemas.ts +314 -0
- package/src/cli/output.ts +17 -1
- package/src/cli/program.ts +199 -635
- package/src/cli/resolve.ts +105 -0
- package/src/cli/safe-live.ts +24 -0
- package/src/cli/status-filter.ts +114 -0
- package/src/cli/util/api-context.ts +85 -0
- package/src/cli/version.ts +5 -0
- package/src/core/audit/persist.ts +183 -0
- package/src/core/checks/budget.ts +59 -0
- package/src/core/checks/checks/_crud-helpers.ts +133 -0
- package/src/core/checks/checks/_negative_mutator.ts +133 -0
- package/src/core/checks/checks/_readback-helpers.ts +133 -0
- package/src/core/checks/checks/content_type_conformance.ts +39 -0
- package/src/core/checks/checks/cross_call_references.ts +147 -0
- package/src/core/checks/checks/cursor_boundary_fuzzing.ts +219 -0
- package/src/core/checks/checks/ensure_resource_availability.ts +62 -0
- package/src/core/checks/checks/idempotency_replay.ts +242 -0
- package/src/core/checks/checks/ignored_auth.ts +254 -0
- package/src/core/checks/checks/index.ts +68 -0
- package/src/core/checks/checks/lifecycle_transitions.ts +416 -0
- package/src/core/checks/checks/missing_required_header.ts +40 -0
- package/src/core/checks/checks/negative_data_rejection.ts +148 -0
- package/src/core/checks/checks/not_a_server_error.ts +35 -0
- package/src/core/checks/checks/open_cors_on_sensitive.ts +160 -0
- package/src/core/checks/checks/pagination_invariants.ts +419 -0
- package/src/core/checks/checks/positive_data_acceptance.ts +33 -0
- package/src/core/checks/checks/rate_limit_headers_absent.ts +77 -0
- package/src/core/checks/checks/response_headers_conformance.ts +74 -0
- package/src/core/checks/checks/response_schema_conformance.ts +30 -0
- package/src/core/checks/checks/status_code_conformance.ts +132 -0
- package/src/core/checks/checks/unsupported_method.ts +63 -0
- package/src/core/checks/checks/use_after_free.ts +78 -0
- package/src/core/checks/index.ts +30 -0
- package/src/core/checks/mode.ts +82 -0
- package/src/core/checks/recommended-action.ts +68 -0
- package/src/core/checks/registry.ts +78 -0
- package/src/core/checks/runner.ts +1461 -0
- package/src/core/checks/sarif.ts +230 -0
- package/src/core/checks/spec-findings.ts +308 -0
- package/src/core/checks/stateful.ts +121 -0
- package/src/core/checks/types.ts +305 -0
- package/src/core/checks/zond-extensions.ts +73 -0
- package/src/core/classifier/recommended-action.ts +251 -0
- package/src/core/context/current.ts +22 -6
- package/src/core/context/session.ts +78 -0
- package/src/core/coverage/loader.ts +216 -0
- package/src/core/coverage/reasons.ts +300 -0
- package/src/core/diagnostics/db-analysis.ts +293 -59
- package/src/core/diagnostics/failure-class.ts +140 -0
- package/src/core/diagnostics/failure-hints.ts +88 -89
- package/src/core/diagnostics/spec-pointer.ts +99 -0
- package/src/core/diagnostics/suggested-fixes.ts +155 -0
- package/src/core/exporter/case-study/index.ts +270 -0
- package/src/core/exporter/curl.ts +40 -0
- package/src/core/exporter/exporter.ts +48 -0
- package/src/core/exporter/html-report/escape.ts +24 -0
- package/src/core/exporter/html-report/index.ts +479 -0
- package/src/core/exporter/html-report/script.ts +100 -0
- package/src/core/exporter/html-report/styles.ts +408 -0
- package/src/core/generator/chunker.ts +38 -19
- package/src/core/generator/coverage-phase.ts +0 -0
- package/src/core/generator/data-factory.ts +586 -22
- package/src/core/generator/describe.ts +1 -1
- package/src/core/generator/fixtures-builder.ts +332 -0
- package/src/core/generator/index.ts +5 -5
- package/src/core/generator/openapi-reader.ts +135 -7
- package/src/core/generator/path-param-disambig.ts +140 -0
- package/src/core/generator/resources-builder.ts +898 -0
- package/src/core/generator/schema-utils.ts +33 -3
- package/src/core/generator/serializer.ts +103 -13
- package/src/core/generator/suite-generator.ts +583 -122
- package/src/core/generator/types.ts +14 -0
- package/src/core/identity/identity-file.ts +0 -0
- package/src/core/lint/affects.ts +28 -0
- package/src/core/lint/config.ts +96 -0
- package/src/core/lint/format.ts +42 -0
- package/src/core/lint/index.ts +94 -0
- package/src/core/lint/reporter.ts +128 -0
- package/src/core/lint/rules/consistency.ts +158 -0
- package/src/core/lint/rules/heuristics.ts +97 -0
- package/src/core/lint/rules/strictness.ts +109 -0
- package/src/core/lint/types.ts +96 -0
- package/src/core/lint/walker.ts +248 -0
- package/src/core/meta/meta-store.ts +6 -73
- package/src/core/output/README.md +73 -0
- package/src/core/output/index.ts +13 -0
- package/src/core/output/run.ts +91 -0
- package/src/core/output/types.ts +122 -0
- package/src/core/parser/dynamic-values.ts +160 -0
- package/src/core/parser/env-interpolation.ts +104 -0
- package/src/core/parser/filter.ts +57 -0
- package/src/core/parser/schema.ts +129 -4
- package/src/core/parser/types.ts +19 -1
- package/src/core/parser/variables.ts +0 -0
- package/src/core/parser/yaml-parser.ts +58 -12
- package/src/core/probe/bootstrap.ts +34 -0
- package/src/core/probe/dry-run-envelope.ts +61 -0
- package/src/core/probe/mass-assignment/classify.ts +175 -0
- package/src/core/probe/mass-assignment/cleanup.ts +52 -0
- package/src/core/probe/mass-assignment/digest.ts +114 -0
- package/src/core/probe/mass-assignment/orchestrator.ts +459 -0
- package/src/core/probe/mass-assignment/regression.ts +141 -0
- package/src/core/probe/mass-assignment/suspects.ts +92 -0
- package/src/core/probe/mass-assignment/types.ts +135 -0
- package/src/core/probe/mass-assignment-probe-class.ts +198 -0
- package/src/core/probe/mass-assignment-probe.ts +27 -0
- package/src/core/probe/mass-assignment-template.ts +240 -0
- package/src/core/probe/method-probe.ts +43 -76
- package/src/core/probe/method-shared.ts +69 -0
- package/src/core/probe/negative-probe.ts +183 -149
- package/src/core/probe/orphan-tracker.ts +188 -0
- package/src/core/probe/path-discovery.ts +439 -0
- package/src/core/probe/probe-harness.ts +119 -0
- package/src/core/probe/registry.ts +89 -0
- package/src/core/probe/runner.ts +136 -0
- package/src/core/probe/security/baseline.ts +174 -0
- package/src/core/probe/security/classify.ts +341 -0
- package/src/core/probe/security/cleanup.ts +125 -0
- package/src/core/probe/security/detectors.ts +71 -0
- package/src/core/probe/security/digest.ts +104 -0
- package/src/core/probe/security/orchestrator.ts +398 -0
- package/src/core/probe/security/regression.ts +103 -0
- package/src/core/probe/security/types.ts +151 -0
- package/src/core/probe/security-probe-class.ts +207 -0
- package/src/core/probe/security-probe.ts +32 -0
- package/src/core/probe/shared.ts +531 -0
- package/src/core/probe/static-probe-class.ts +125 -0
- package/src/core/probe/types.ts +165 -0
- package/src/core/probe/verdict-aggregator.ts +33 -0
- package/src/core/probe/webhooks-probe.ts +282 -0
- package/src/core/reporter/console.ts +41 -2
- package/src/core/reporter/index.ts +2 -3
- package/src/core/reporter/json.ts +11 -1
- package/src/core/reporter/junit.ts +27 -12
- package/src/core/reporter/ndjson.ts +37 -0
- package/src/core/reporter/types.ts +3 -0
- package/src/core/runner/assertions.ts +59 -2
- package/src/core/runner/async-pool.ts +108 -0
- package/src/core/runner/auth-path.ts +8 -0
- package/src/core/runner/ci-context.ts +72 -0
- package/src/core/runner/executor.ts +265 -36
- package/src/core/runner/form-encode.ts +41 -0
- package/src/core/runner/http-client.ts +112 -2
- package/src/core/runner/learn-drift.ts +293 -0
- package/src/core/runner/preflight-vars.ts +153 -0
- package/src/core/runner/progress-tracker.ts +73 -0
- package/src/core/runner/rate-limiter.ts +87 -33
- package/src/core/runner/run-kind.ts +45 -0
- package/src/core/runner/schema-validator.ts +308 -0
- package/src/core/runner/send-request.ts +158 -20
- package/src/core/runner/types.ts +44 -0
- package/src/core/secrets/registry.ts +164 -0
- package/src/core/secrets/secrets-file.ts +115 -0
- package/src/core/selectors/operation-filter.ts +144 -0
- package/src/core/setup-api.ts +457 -20
- package/src/core/severity/category.ts +94 -0
- package/src/core/severity/index.ts +58 -0
- package/src/core/spec/infer-schema.ts +102 -0
- package/src/core/spec/layers.ts +154 -0
- package/src/core/spec/merge-specs.ts +156 -0
- package/src/core/spec/schema-from-runs.ts +117 -0
- package/src/core/spec/schema-overlay.ts +130 -0
- package/src/core/util/ajv.ts +13 -0
- package/src/core/util/format-eta.ts +21 -0
- package/src/core/util/headers.ts +9 -0
- package/src/core/util/url.ts +24 -0
- package/src/core/utils.ts +5 -1
- package/src/core/workspace/config.ts +129 -0
- package/src/core/workspace/fixture-gap-report.ts +84 -0
- package/src/core/workspace/fixture-gaps.ts +71 -0
- package/src/core/workspace/manifest.ts +283 -0
- package/src/core/workspace/output-rotation.ts +62 -0
- package/src/core/workspace/root.ts +13 -11
- package/src/core/workspace/triage-path.ts +87 -0
- package/src/db/lint-runs.ts +47 -0
- package/src/db/migrate.ts +128 -0
- package/src/db/migrations/0001_run_kind.sql +25 -0
- package/src/db/migrations/0002_run_kind_request.sql +59 -0
- package/src/db/migrations/sql.d.ts +4 -0
- package/src/db/queries/collections.ts +133 -0
- package/src/db/queries/coverage.ts +9 -0
- package/src/db/queries/dashboard.ts +59 -0
- package/src/db/queries/results.ts +216 -0
- package/src/db/queries/runs.ts +289 -0
- package/src/db/queries/sessions.ts +42 -0
- package/src/db/queries/settings.ts +28 -0
- package/src/db/queries/types.ts +172 -0
- package/src/db/queries.ts +75 -802
- package/src/db/schema.ts +178 -50
- package/src/cli/commands/export.ts +0 -144
- package/src/cli/commands/guide.ts +0 -127
- package/src/cli/commands/init/templates/skills/scenarios.md +0 -97
- package/src/cli/commands/probe-methods.ts +0 -108
- package/src/cli/commands/probe-validation.ts +0 -124
- package/src/cli/commands/serve.ts +0 -114
- package/src/cli/commands/sync.ts +0 -268
- package/src/cli/commands/update.ts +0 -189
- package/src/cli/commands/validate.ts +0 -34
- package/src/core/diagnostics/render-md.ts +0 -112
- package/src/core/exporter/postman.ts +0 -963
- package/src/core/generator/guide-builder.ts +0 -253
- package/src/core/meta/types.ts +0 -19
- package/src/core/parser/index.ts +0 -21
- package/src/core/runner/execute-run.ts +0 -132
- package/src/core/runner/index.ts +0 -12
- package/src/core/sync/spec-differ.ts +0 -38
- package/src/web/data/collection-state.ts +0 -362
- package/src/web/routes/api.ts +0 -314
- package/src/web/routes/dashboard.ts +0 -350
- package/src/web/routes/runs.ts +0 -64
- package/src/web/schemas.ts +0 -121
- package/src/web/server.ts +0 -134
- package/src/web/static/htmx.min.cjs +0 -1
- package/src/web/static/style.css +0 -1148
- package/src/web/views/endpoints-tab.ts +0 -174
- package/src/web/views/explorer-tab.ts +0 -402
- package/src/web/views/health-strip.ts +0 -92
- package/src/web/views/layout.ts +0 -48
- package/src/web/views/results.ts +0 -210
- package/src/web/views/runs-tab.ts +0 -126
- package/src/web/views/suites-tab.ts +0 -181
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: zond-seed
|
|
3
|
+
description: |
|
|
4
|
+
Agent-orchestrated auto-seed: create the fixtures a deep audit needs from
|
|
5
|
+
what the API itself offers, so CRUD depth stops being gated by hand-seeded
|
|
6
|
+
`{{account}}`/`{{customer}}`/… ids. Use when `prepare-fixtures` reports
|
|
7
|
+
`unseededRoots`, when `db diagnose` shows `cascade_skips`, or the user asks
|
|
8
|
+
to "seed fixtures", "create test data", "un-skip the CRUD chains", "raise
|
|
9
|
+
depth". YOU reason (read the API graph, author create-bodies, order them,
|
|
10
|
+
read the 4xx and fix it); zond only EXECUTES (POST + capture id into
|
|
11
|
+
`.env.yaml`). Sibling `zond` runs the full audit; hand back to it once
|
|
12
|
+
fixtures are seeded.
|
|
13
|
+
allowed-tools: [Read, Write, Edit, Bash(zond *), Bash(bunx zond *)]
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
# zond-seed — agent-orchestrated fixture creation
|
|
17
|
+
|
|
18
|
+
The m-24 endgame: an autonomous seed loop where the DECISION is yours and the
|
|
19
|
+
EXECUTION is zond's. This is **not** a revert of ARV-336 (the blind recursive
|
|
20
|
+
cascade zond removed — 1% success on Stripe). The difference is the feedback
|
|
21
|
+
loop: you read the spec + resource graph, author a create-body, POST it, and
|
|
22
|
+
when the server says 400 you read *why* and fix the body. That is exactly why
|
|
23
|
+
it works where the heuristic engine failed.
|
|
24
|
+
|
|
25
|
+
## Iron rules (read once, apply always)
|
|
26
|
+
|
|
27
|
+
- **You reason, zond executes.** You author every create-body and pick the
|
|
28
|
+
order; zond only POSTs and captures the returned id. Never ask zond to
|
|
29
|
+
"figure out" a body — that heuristic engine was deleted (ARV-336, m-24) and
|
|
30
|
+
must not grow back. There is no `zond seed` command by design.
|
|
31
|
+
- **No blind cascade — one create at a time, with a feedback loop.** POST a
|
|
32
|
+
body, read the response. On 4xx, read the error message, revise the *specific*
|
|
33
|
+
field it names, retry. Cap at **~3 attempts per resource**, then mark it
|
|
34
|
+
un-seedable and move on. Never fire a chain of creates without reading each
|
|
35
|
+
reply.
|
|
36
|
+
- **Seed only what the API can self-serve.** Fixtures needing external input —
|
|
37
|
+
KYC-verified accounts, verified bank accounts, webhook signing secrets,
|
|
38
|
+
paid-plan / SCIM / TOS-gated resources, or ids that only exist after a real
|
|
39
|
+
event (`issue_id`, `file_id`, `integration_id`) — are **reported, not
|
|
40
|
+
invented** (pairs with `prepare-fixtures` `unseededRoots` and ARV-349/350).
|
|
41
|
+
Guessing a value here just 422s and lies about coverage. Hand those to the
|
|
42
|
+
**`warm-up-target`** skill, which warms them via the target's own SDK/CLI.
|
|
43
|
+
- **Live + throwaway/sandbox + cleanup only.** Never seed against production or
|
|
44
|
+
shared data. Confirm `base_url` is a sandbox/test account first. Track every
|
|
45
|
+
id you create and DELETE it at the end (or seed inside a disposable account /
|
|
46
|
+
Stripe test-clock). If you cannot guarantee cleanup, ask before creating.
|
|
47
|
+
- **Honor prose exclusion.** Specs document mutual exclusion in `description`,
|
|
48
|
+
not machine-readable `oneOf` (Stripe: "You may only specify one of A, B").
|
|
49
|
+
If a 400 says that, drop one member and retry (folded from ARV-347).
|
|
50
|
+
|
|
51
|
+
## Inputs — what to seed
|
|
52
|
+
|
|
53
|
+
| Signal | Command | Field |
|
|
54
|
+
|---|---|---|
|
|
55
|
+
| Chain-heads gating suites | `zond prepare-fixtures --api <name> --json` | `summary.fixtureGaps.unseededRoots[]` |
|
|
56
|
+
| Empty captures from last run | `zond db diagnose --json` | `cascade_skips[].capture_var` |
|
|
57
|
+
| Dependency order | `apis/<name>/.api-resources.yaml` | each resource's `fkDependencies` |
|
|
58
|
+
| Body schema + last server reply | `zond api annotate dump --seed-bodies --with-last-attempt --api <name>` | `seed_body`, `last_attempt` |
|
|
59
|
+
|
|
60
|
+
`unseededRoots` is your worklist. `fkDependencies` gives the order: a resource
|
|
61
|
+
whose FK points at another must be created *after* its parent (parent id is
|
|
62
|
+
captured first, then referenced). Sort parent-before-child yourself; skip
|
|
63
|
+
cycles and resources whose only dep is external input.
|
|
64
|
+
|
|
65
|
+
**miss-no-list `candidates` (ARV-382):** when prepare-fixtures can't confidently
|
|
66
|
+
derive the owner list for a fixture var, the item carries a `candidates[]` of
|
|
67
|
+
plausible GET/list endpoints (ranked by structural proximity; deprecated ones
|
|
68
|
+
marked `(deprecated)`). zond does NOT pick — that's your call: `zond request`
|
|
69
|
+
the top candidate, read a record, `zond fixtures add <var>=<id>`. An empty
|
|
70
|
+
`candidates` (and no owner) is an honest dead-end: no listable source exists —
|
|
71
|
+
create the resource or obtain the id from a parent flow.
|
|
72
|
+
|
|
73
|
+
## The loop
|
|
74
|
+
|
|
75
|
+
For each root, parent-first:
|
|
76
|
+
|
|
77
|
+
1. **Author the body.** `zond api annotate dump --seed-bodies --with-last-attempt`
|
|
78
|
+
gives the schema, a rationale, and `last_attempt` (what zond last POSTed and
|
|
79
|
+
how the server replied). Fill required fields with real-looking values;
|
|
80
|
+
reference already-captured parents as `{{parent_var}}`.
|
|
81
|
+
|
|
82
|
+
2. **Create + capture** — one command, deterministic:
|
|
83
|
+
```bash
|
|
84
|
+
zond request POST /v1/accounts --api <name> \
|
|
85
|
+
--body '{"type":"custom","country":"US","capabilities":{...}}' \
|
|
86
|
+
--json-path id --capture account
|
|
87
|
+
```
|
|
88
|
+
On 2xx zond writes `account=<id>` into `apis/<name>/.env.yaml` (with a
|
|
89
|
+
`.bak` backup) and prints `captured account=<id>`. On non-2xx it writes
|
|
90
|
+
nothing and prints `--capture account skipped — … status=400 …`.
|
|
91
|
+
|
|
92
|
+
3. **Feedback on failure.** Read the response body. Common fixes:
|
|
93
|
+
- "Missing required field X" → add X.
|
|
94
|
+
- "You may only specify one of A, B" → drop one (prose exclusion).
|
|
95
|
+
- "Invalid <field>" / 422 on an id → the value is external-input; stop
|
|
96
|
+
retrying this root and mark it un-seedable.
|
|
97
|
+
Revise the `--body`, retry. Cap ~3 attempts.
|
|
98
|
+
|
|
99
|
+
4. **Cascade.** Once a parent id is captured, its children unblock — their
|
|
100
|
+
`{{parent_var}}` now resolves. Walk down the dependency chain.
|
|
101
|
+
|
|
102
|
+
5. **Verify.** Re-run `zond prepare-fixtures --api <name> --json` — the roots
|
|
103
|
+
you seeded should drop out of `unseededRoots`.
|
|
104
|
+
|
|
105
|
+
## Cleanup & report
|
|
106
|
+
|
|
107
|
+
- DELETE every id you created (reverse order — children first), or confirm the
|
|
108
|
+
seed account is disposable.
|
|
109
|
+
- Report: **seeded** (var → id), **un-seedable** (var → reason: external input
|
|
110
|
+
/ gated / no create endpoint). The un-seedable list is the honest ceiling —
|
|
111
|
+
hand it to the user; do not paper over it with invented values.
|
|
112
|
+
|
|
113
|
+
Hand back to `zond` for the full audit once depth is unblocked. Measure the
|
|
114
|
+
lift: test coverage before vs after seeding.
|
|
@@ -0,0 +1,272 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: zond-triage
|
|
3
|
+
description: |
|
|
4
|
+
Last-run triage. Use when the user asks "что упало в последнем run", "почему
|
|
5
|
+
красное", "что с ralph-loop'ом сделать", "summary последнего прогона",
|
|
6
|
+
"explain failures", "что мне сейчас править". Reads `recommended_action`
|
|
7
|
+
enum from `zond db diagnose`, `zond check spec`, and `zond probe <class>` JSON
|
|
8
|
+
artifacts and emits an actionable summary grouped by next-step. No LLM
|
|
9
|
+
classification — every line is routed by the enum value emitted by zond.
|
|
10
|
+
allowed-tools: [Read, Bash(zond *), Bash(bunx zond *), Bash(jq *)]
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
# zond-triage — last-run summary
|
|
14
|
+
|
|
15
|
+
Narrow skill: the user already has a finished run (or a recent
|
|
16
|
+
`probe <class>` / `check spec` artifact) and wants to know **what failed and
|
|
17
|
+
what to do next**. Sibling `zond` does the full audit + writes
|
|
18
|
+
scenarios; this one only reads.
|
|
19
|
+
|
|
20
|
+
## Iron rules
|
|
21
|
+
|
|
22
|
+
- **Route on `recommended_action`, not on the message string.** Every zond
|
|
23
|
+
artifact stamps a closed enum: `report_backend_bug | fix_test_logic |
|
|
24
|
+
fix_auth_config | fix_network_config | fix_env | fix_spec |
|
|
25
|
+
fix_fixture | regenerate_suite | tighten_validation | add_required_header |
|
|
26
|
+
wontfix_known_limitation`. The last three (m-15 ARV-11) carry
|
|
27
|
+
depth-check findings from `zond checks run`; `regenerate_suite`
|
|
28
|
+
(m-16 ARV-42) means the failing YAML was emitted by `zond generate`
|
|
29
|
+
and editing it would be clobbered — re-run `zond generate --api
|
|
30
|
+
<name>` (or refine `.api-resources.yaml`) instead. Same triage rules
|
|
31
|
+
apply across the board: route by enum value. Group by enum, then
|
|
32
|
+
summarise. Never re-classify with prose heuristics.
|
|
33
|
+
- **One actionable line per group.** The agent-directive *is* the next
|
|
34
|
+
command — don't pad with "consider checking...".
|
|
35
|
+
- **`report_backend_bug` / 5xx → STOP, surface, do not edit `expect:`.**
|
|
36
|
+
Same iron rule as the parent `zond` skill.
|
|
37
|
+
- **Never read raw response bodies past 8 KB.** The diagnose envelope
|
|
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
|
|
40
|
+
triaging body-shape bugs.
|
|
41
|
+
- **Никогда не выдавать абстрактные «проверьте логи» / «уточните у
|
|
42
|
+
команды».** Если в enum-группе нет конкретного действия — пометить
|
|
43
|
+
`<TODO: clarify>` и выйти, не маскировать пустоту.
|
|
44
|
+
|
|
45
|
+
## Sources & enum routing
|
|
46
|
+
|
|
47
|
+
| Source | How to read | Emits `recommended_action` for |
|
|
48
|
+
|---|---|---|
|
|
49
|
+
| `zond db diagnose <run-id> --json` | per-failure under `data.failures[]` | every fail/error in the run |
|
|
50
|
+
| `zond check spec --api <name> --json` | `data.issues[]` | every lint Issue (always `fix_spec`) |
|
|
51
|
+
| `zond probe mass-assignment --json` | `data.endpoints[]` (action under `findings[].evidence.recommended_action`) | per-endpoint verdicts (high/medium/inconclusive-5xx/inconclusive-baseline) |
|
|
52
|
+
| `zond probe security --json` | counts only — read the markdown digest | high / low findings (markdown table) |
|
|
53
|
+
| `zond probe static --json` | `data.files[]` (suite YAMLs to run) | findings surface only after `zond run` → routed via diagnose |
|
|
54
|
+
|
|
55
|
+
`probe security` does not expose findings in `--json`; treat its
|
|
56
|
+
markdown digest as the canonical source for that class and parse
|
|
57
|
+
HIGH/LOW rows by hand.
|
|
58
|
+
|
|
59
|
+
## Phase 1 — locate the run
|
|
60
|
+
|
|
61
|
+
If the user did not name a run id, the default of `zond db diagnose`
|
|
62
|
+
already targets the most recent failing run (TASK-266). Skip straight to
|
|
63
|
+
Phase 2 unless you specifically need an older run:
|
|
64
|
+
|
|
65
|
+
```bash
|
|
66
|
+
zond db runs --limit 5 --json # pick a non-default run id
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
If `trigger=ci`, mention the CI build in the summary. If the user said
|
|
70
|
+
"после моего фикса", take the second-most-recent and pair with
|
|
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.
|
|
82
|
+
|
|
83
|
+
## Phase 2 — pull the diagnose envelope
|
|
84
|
+
|
|
85
|
+
```bash
|
|
86
|
+
zond db diagnose --json # last failing run (default — TASK-266)
|
|
87
|
+
zond db diagnose <run-id> --json # explicit run
|
|
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
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
The shape (relevant fields only):
|
|
98
|
+
|
|
99
|
+
```jsonc
|
|
100
|
+
{
|
|
101
|
+
"ok": true,
|
|
102
|
+
"data": {
|
|
103
|
+
"run_id": 42,
|
|
104
|
+
"summary": { "passed": 18, "failed": 7, "errored": 1 },
|
|
105
|
+
"failures": [
|
|
106
|
+
{
|
|
107
|
+
"suite_name": "crud-projects",
|
|
108
|
+
"test_name": "create project",
|
|
109
|
+
"failure_type": "api_error",
|
|
110
|
+
"recommended_action": "report_backend_bug",
|
|
111
|
+
"request_method": "POST",
|
|
112
|
+
"request_url": "...",
|
|
113
|
+
"response_status": 500
|
|
114
|
+
}
|
|
115
|
+
]
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
Bucket every failure by `recommended_action`. Display order (highest
|
|
121
|
+
priority first):
|
|
122
|
+
|
|
123
|
+
1. `report_backend_bug` — 5xx / schema_violation / mass-assignment HIGH.
|
|
124
|
+
Bug. Surface excerpt; offer `zond report bundle --include case-study`.
|
|
125
|
+
2. `fix_spec` — emitted only by `zond check spec`. Edit OpenAPI source,
|
|
126
|
+
then `zond refresh-api <name>`.
|
|
127
|
+
3. `fix_auth_config` — 401/403 cluster. Check `auth_token` scope (or run
|
|
128
|
+
`zond doctor --api <name> --missing-only`).
|
|
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).
|
|
132
|
+
5. `fix_fixture` — `prepare-fixtures` miss-* or inconclusive-baseline
|
|
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.
|
|
138
|
+
6. `fix_network_config` — connect-refused / DNS / TLS. Check `base_url`
|
|
139
|
+
reachability; `--proxy` may be needed.
|
|
140
|
+
7. `regenerate_suite` (ARV-42) — 4xx (400/422) on a generator-emitted
|
|
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.
|
|
147
|
+
8. `fix_test_logic` — 4xx (400/422) on a manually-authored suite, or any
|
|
148
|
+
leftover assertion failure not absorbed by the buckets above. Phase 4a
|
|
149
|
+
of the `zond` skill: fixture pack first, typed generator second,
|
|
150
|
+
literal third.
|
|
151
|
+
|
|
152
|
+
Within each bucket, collapse by `(suite_name, response_status,
|
|
153
|
+
request_method, root_cause)` and report a count + 1-2 examples. Do
|
|
154
|
+
**not** dump every failure.
|
|
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
|
+
|
|
192
|
+
## Phase 3 — reconcile spec / probe sources
|
|
193
|
+
|
|
194
|
+
Run only what the user's question implies — don't fan out blindly.
|
|
195
|
+
|
|
196
|
+
```bash
|
|
197
|
+
# spec-level lint (only if user asked about spec drift / contract)
|
|
198
|
+
zond check spec --api <name> --json | jq '.data.issues | group_by(.rule)'
|
|
199
|
+
|
|
200
|
+
# mass-assignment digest (only if user mentioned mass-assign / privilege)
|
|
201
|
+
zond probe mass-assignment --api <name> --json
|
|
202
|
+
# verdicts with recommended_action != null are the actionable subset
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
For `probe security`, the digest is the source. Read the file the user
|
|
206
|
+
named (or `apis/<name>/probes/security-digest.md`) and pull HIGH rows
|
|
207
|
+
plus the `## ⚠️ Cleanup failures` section if present.
|
|
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
|
+
|
|
221
|
+
## Output template
|
|
222
|
+
|
|
223
|
+
Stay terse. Russian by default, mirror the user's language.
|
|
224
|
+
|
|
225
|
+
```
|
|
226
|
+
Run #<id> · <ts> · session=<id?> · trigger=<ci|manual>
|
|
227
|
+
Pass <N> Fail <M> Error <K> Coverage <pct>%
|
|
228
|
+
|
|
229
|
+
⛔ report_backend_bug ×<n>
|
|
230
|
+
· POST /v1/projects → 500 (×3) — TypeError: cannot read 'slug'
|
|
231
|
+
next: zond report bundle <id> --include case-study
|
|
232
|
+
🛠 fix_test_logic ×<n>
|
|
233
|
+
· POST /v1/audiences → 422 expected uuid (×2)
|
|
234
|
+
next: replace {{$randomString}} with {{$uuid}} in audiences.yaml
|
|
235
|
+
🔑 fix_auth_config ×<n>
|
|
236
|
+
· 4 suites all 401 — check auth_token scope
|
|
237
|
+
next: zond doctor --api <name> --missing-only
|
|
238
|
+
🌐 fix_env ×<n>
|
|
239
|
+
· base_url unset — request_url resolved to "/v1/projects"
|
|
240
|
+
next: edit apis/<name>/.env.yaml → base_url
|
|
241
|
+
📥 fix_fixture ×<n>
|
|
242
|
+
· {{audience_id}} unresolved
|
|
243
|
+
next: zond prepare-fixtures --api <name> (reports the gap; fill it via `fixtures add` / .env.yaml)
|
|
244
|
+
📜 fix_spec ×<n> (from check spec)
|
|
245
|
+
· A2 missing operationId on POST /webhooks
|
|
246
|
+
next: edit spec.json → operationId, then zond refresh-api <name>
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
Skip empty buckets. If `summary.failed + summary.errored == 0`, just
|
|
250
|
+
say "all green" and exit — don't invent work.
|
|
251
|
+
|
|
252
|
+
## When to escalate
|
|
253
|
+
|
|
254
|
+
- **Mixed recommended_action inside one suite (>3 distinct enums):**
|
|
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.
|
|
258
|
+
- **Cleanup failures from `probe security`:** call out at the **top** —
|
|
259
|
+
this means probe mutated state it could not restore. Treat as
|
|
260
|
+
blocking; do not run more probes against the same env until the
|
|
261
|
+
user confirms manual cleanup.
|
|
262
|
+
- **`recommended_action` missing on a verdict you expected to see:**
|
|
263
|
+
TASK-294 stamps it on every issue/finding emitted post-Done. If a
|
|
264
|
+
field is missing, you're probably reading a pre-TASK-294 artifact —
|
|
265
|
+
re-run the source command, don't infer.
|
|
266
|
+
|
|
267
|
+
## Hand-off back to `zond`
|
|
268
|
+
|
|
269
|
+
When the user wants to *act* on the summary (write a fix, file a
|
|
270
|
+
report, re-run the suite), hand off to the parent `zond` skill — it
|
|
271
|
+
owns the YAML edits, `zond report bundle` flow, and the re-run loop.
|
|
272
|
+
This skill stops at the summary.
|