@lovrozagar/oat 0.9.1 → 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 +103 -32
- package/dist/cli.js +56 -14
- package/dist/config/define-config.d.ts +7 -1
- package/dist/config/define-config.d.ts.map +1 -1
- package/dist/config/define-config.js.map +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.js +1 -0
- package/dist/report/console.d.ts +2 -1
- package/dist/report/console.d.ts.map +1 -1
- package/dist/report/console.js +33 -1
- package/dist/report/console.js.map +1 -1
- package/dist/report/matrix.d.ts +8 -13
- package/dist/report/matrix.d.ts.map +1 -1
- package/dist/report/matrix.js +21 -10
- package/dist/report/matrix.js.map +1 -1
- package/dist/report/render.d.ts +8 -0
- package/dist/report/render.d.ts.map +1 -1
- package/dist/report/render.js +94 -1
- package/dist/report/render.js.map +1 -1
- package/dist/runtime/checks.d.ts +42 -1
- package/dist/runtime/checks.d.ts.map +1 -1
- package/dist/runtime/checks.js +190 -24
- package/dist/runtime/checks.js.map +1 -1
- package/dist/runtime/finding.d.ts +14 -1
- package/dist/runtime/finding.d.ts.map +1 -1
- package/dist/runtime/finding.js +25 -6
- package/dist/runtime/finding.js.map +1 -1
- package/dist/runtime/run.d.ts +17 -0
- package/dist/runtime/run.d.ts.map +1 -1
- package/dist/runtime/run.js +126 -66
- package/dist/runtime/run.js.map +1 -1
- package/dist/runtime/scope.d.ts +163 -0
- package/dist/runtime/scope.d.ts.map +1 -0
- package/dist/runtime/scope.js +423 -0
- package/dist/runtime/scope.js.map +1 -0
- package/dist/runtime/world.d.ts +7 -2
- package/dist/runtime/world.d.ts.map +1 -1
- package/dist/runtime/world.js +12 -6
- package/dist/runtime/world.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -40,6 +40,7 @@ This file is the operator manual. An agent that has read it can install oat, wri
|
|
|
40
40
|
- [Complete configs](#complete-configs)
|
|
41
41
|
- [Commands](#commands)
|
|
42
42
|
- [oat run](#oat-run)
|
|
43
|
+
- [Targeted runs (`--ops`)](#targeted-runs---ops)
|
|
43
44
|
- [oat doctor](#oat-doctor)
|
|
44
45
|
- [oat plan](#oat-plan)
|
|
45
46
|
- [oat serve](#oat-serve)
|
|
@@ -255,19 +256,20 @@ oat help
|
|
|
255
256
|
|
|
256
257
|
Requires `--config`. CLI flags override the same field in the config when both are set.
|
|
257
258
|
|
|
258
|
-
| flag | default | meaning
|
|
259
|
-
| ------------------------------------------ | -------------------------------- |
|
|
260
|
-
| `--config` | required | module or JSON file, default export
|
|
261
|
-
| `--base-url` | `config.baseUrl` | backend origin
|
|
262
|
-
| `--
|
|
263
|
-
| `--
|
|
264
|
-
| `--
|
|
265
|
-
| `--
|
|
266
|
-
| `--
|
|
267
|
-
| `--
|
|
268
|
-
| `--
|
|
269
|
-
|
|
270
|
-
|
|
259
|
+
| flag | default | meaning |
|
|
260
|
+
| ------------------------------------------ | -------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
261
|
+
| `--config` | required | module or JSON file, default export |
|
|
262
|
+
| `--base-url` | `config.baseUrl` | backend origin |
|
|
263
|
+
| `--ops` | `config.ops` or every operation | comma-separated operationIds to grade; everything else is support. `*` globs, `<originId>:` prefixes. See [Targeted runs](#targeted-runs---ops) |
|
|
264
|
+
| `--only` | `config.only` or all entities | comma-separated entity names as `oat plan` prints them (singularised); each grades every operation it owns. Joins `--ops` as a union |
|
|
265
|
+
| `--seed` | `config.seed` or `1` | fixture generation seed (reproducible) |
|
|
266
|
+
| `--out` | `config.outDir` or `./.oat/runs` | history root; each run writes `<out>/<datetime>/` and updates `latest` |
|
|
267
|
+
| `--max-in-flight` | `config.maxInFlight` or `4` | HTTP requests allowed at once |
|
|
268
|
+
| `--keep-fixtures` | `config.keepFixtures` or false | do not DELETE what the run created |
|
|
269
|
+
| `--quiet` | false | no stderr progress; files under `--out` still update |
|
|
270
|
+
| `--save-exchanges` / `--no-save-exchanges` | on unless `--profile cheap` | persist every HTTP exchange under the run dir (`exchanges.jsonl`, `exchanges/`, `blobs/`). Does **not** change in-memory transcript RAM |
|
|
271
|
+
|
|
272
|
+
**Exit codes:** `0` no defects, `1` at least one root-cause finding (`BACKEND_BUG`, `SPEC_BUG`, `SECURITY`, `AMBIGUITY`) **or** the run stopped because the network never came back **or**, on a targeted run, a target that did not end `held`, `2` usage error (missing `--config`, no principals, unknown flag, an `--ops` / `--only` name that matches nothing, a target the profile excludes). `COVERAGE_GAP` and `BLOCKED` do not fail a full run.
|
|
271
273
|
|
|
272
274
|
Example:
|
|
273
275
|
|
|
@@ -275,10 +277,47 @@ Example:
|
|
|
275
277
|
oat run --config oat.config.ts --only store,product --out .oat/runs/prod
|
|
276
278
|
```
|
|
277
279
|
|
|
278
|
-
`--only store,product` matches the **entity names** from `oat plan`, not path segments. `/v1/stores` is usually the entity `store`.
|
|
280
|
+
`--only store,product` matches the **entity names** from `oat plan`, not path segments. `/v1/stores` is usually the entity `store`. An unknown name exits `2` with the nearest names.
|
|
279
281
|
|
|
280
282
|
A run with no principals exits `2`. Isolation checks then need a second principal; they are skipped, not failed, when only one is present.
|
|
281
283
|
|
|
284
|
+
### Targeted runs (`--ops`)
|
|
285
|
+
|
|
286
|
+
A full run grades every operation. After changing two endpoints you usually want those two, not the whole API:
|
|
287
|
+
|
|
288
|
+
```bash
|
|
289
|
+
oat run --config oat.config.ts --ops table.create,row.list
|
|
290
|
+
oat run --config oat.config.ts --ops 'row.*' # glob within an operationId
|
|
291
|
+
oat run --config oat.config.ts --ops cdn:asset.get # an operation on the origin with id "cdn"
|
|
292
|
+
oat plan --config oat.config.ts --ops table.create # dry run: what would be graded, queued, called
|
|
293
|
+
```
|
|
294
|
+
|
|
295
|
+
**Targets** are graded: every check whose subjects include a target runs the full matrix against it. **Support** operations are called and never graded: principal sign-up, parent creates, the cohort create behind a list, reads used as an oracle, teardown deletes. A list route cannot be tested without rows in it, so its create still runs, but a defect in that create is out of this run's scope.
|
|
296
|
+
|
|
297
|
+
How the scope is decided:
|
|
298
|
+
|
|
299
|
+
- Every check declares its **subjects**, the operations whose contract it judges (`filter.*` judges the list route, `patch.minimality` the update, `effects.declared-effect-occurs` each `x-effects` operation). A check runs when one of its subjects is a target. Others are **out of scope**: not run, not skipped.
|
|
300
|
+
- An entity is seeded only when one of its checks grades a target. Declared edges pull in the other direction too: targeting a read route that another entity's create names in `x-invalidate` queues that entity, so its invalidation check grades the route.
|
|
301
|
+
- Checks that judge several operations (`effects.*`, `async.*`, `response.status-is-documented`, `schema.error-response-matches-document`, `invalidation.declared-route-changes`) invoke and judge only the targeted ones. An untargeted `x-effects` upload is never POSTed.
|
|
302
|
+
- Every finding names the operations it judges (`operations` in `oat-report.json`).
|
|
303
|
+
- An operation counts as graded only when a check exercised it. A check that judges after the fact (`response.status-is-documented` reads the transcript) grades only the operations it saw. A check that reports a coverage gap for an operation did not grade it. `--only <entity>` therefore surfaces every action no check can reach as `untested`.
|
|
304
|
+
|
|
305
|
+
Each target ends with one status:
|
|
306
|
+
|
|
307
|
+
| status | meaning |
|
|
308
|
+
| -------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
309
|
+
| `held` | at least one check graded it and none failed |
|
|
310
|
+
| `failed` | a defect finding is attributed to it |
|
|
311
|
+
| `inconclusive` | checks ran and none could decide |
|
|
312
|
+
| `blocked` | every check was suppressed, or a support operation it needed failed (named, with evidence) |
|
|
313
|
+
| `untested` | nothing exercised it. The reason says why (`unmodeled`, `entity-not-testable`, `coverage gap: …`, `no check applied: needs …`, `no check exercised it`) |
|
|
314
|
+
|
|
315
|
+
A targeted run exits `0` only when every target is `held`. A target nothing could grade must not read as a pass.
|
|
316
|
+
|
|
317
|
+
Validation happens before any principal signs up: a name that matches nothing exits `2` with the nearest operationIds; an exact target the active `--profile` excludes exits `2`; a glob or `--only` match the profile excludes is dropped and listed. An origin no target names is not run.
|
|
318
|
+
|
|
319
|
+
A targeted run is for iterating. It grades what you named and what those operations observably affect through declared edges. It does not catch a regression in an untargeted operation caused by shared code, so run the full suite before a release.
|
|
320
|
+
|
|
282
321
|
### `oat doctor`
|
|
283
322
|
|
|
284
323
|
Offline. Loads the document, builds the model, prints coverage.
|
|
@@ -337,6 +376,8 @@ store CLRU· id 2 route(s) (inferred)
|
|
|
337
376
|
|
|
338
377
|
`--json` is `{ entities, operations, roots }` — the full `SpecModel` maps, including conventions, query capability, async, invite, and path params. Use this when you need to know what oat will call something.
|
|
339
378
|
|
|
379
|
+
With `--ops` / `--only` (flag or config), `plan` prints the targeted scope instead: each target with its entity and the checks that would grade it, untestable targets with the reason, the entities that would be queued, and the support operations predicted from the graph. `--json` adds a `scope` object with the same fields. An unknown name exits `2`.
|
|
380
|
+
|
|
340
381
|
### `oat serve`
|
|
341
382
|
|
|
342
383
|
In-process demo API. Same fixture as conformance.
|
|
@@ -433,7 +474,8 @@ export default defineConfig({
|
|
|
433
474
|
seed: 42, // fixture generation; a failing run with the same seed is identical
|
|
434
475
|
cohortSize: 12, // records created per entity (default 7)
|
|
435
476
|
maxInFlight: 4, // HTTP in flight
|
|
436
|
-
|
|
477
|
+
ops: ["store.create", "product.*"], // grade only these operationIds; the rest is support
|
|
478
|
+
only: ["store", "product"], // grade every operation these entities own (union with ops)
|
|
437
479
|
keepFixtures: false,
|
|
438
480
|
outDir: "./.oat/runs",
|
|
439
481
|
saveExchanges: true, // default on unless --profile cheap; --quiet does not turn this off
|
|
@@ -483,7 +525,7 @@ export default defineConfig({
|
|
|
483
525
|
|
|
484
526
|
`spec` may be a path relative to `baseUrl` (`/v1/openapi/spec`) or an absolute URL or a file.
|
|
485
527
|
|
|
486
|
-
CLI `--base-url`, `--only`, `--seed`, `--out`, `--max-in-flight`, `--keep-fixtures`, `--save-exchanges` / `--no-save-exchanges` override these when passed.
|
|
528
|
+
CLI `--base-url`, `--ops`, `--only`, `--seed`, `--out`, `--max-in-flight`, `--keep-fixtures`, `--save-exchanges` / `--no-save-exchanges` override these when passed.
|
|
487
529
|
|
|
488
530
|
### Spec loading
|
|
489
531
|
|
|
@@ -1686,7 +1728,7 @@ Coverage is split **never** (zero entities could run it) vs **partial** (ran on
|
|
|
1686
1728
|
|
|
1687
1729
|
Cascade suppression is transitive: one root cause is one finding, not a page of consequences. A blocked check has **not** been verified; re-run after the cause is fixed.
|
|
1688
1730
|
|
|
1689
|
-
`oat run` exit `1` if any finding has a failing verdict. Gaps and blocked entries do not fail
|
|
1731
|
+
`oat run` exit `1` if any finding has a failing verdict. Gaps and blocked entries do not fail a full run. A targeted run (`--ops`) also exits `1` when any target did not end `held`.
|
|
1690
1732
|
|
|
1691
1733
|
Console (stdout) after a run:
|
|
1692
1734
|
|
|
@@ -1715,20 +1757,20 @@ Written under `--out` (default `./.oat/runs`). Each invocation creates a UTC tim
|
|
|
1715
1757
|
|
|
1716
1758
|
`--out` / `outDir` replace the root, not the leaf — `--out .oat/runs/prod` writes `.oat/runs/prod/<datetime>/`.
|
|
1717
1759
|
|
|
1718
|
-
| file |
|
|
1719
|
-
| ---------------------------- |
|
|
1720
|
-
| `oat-report.md` | human report: summary, findings with request/response excerpts, coverage, latency p50/p95/max
|
|
1721
|
-
| `oat-report.json` | same data for CI. Summary only — full exchanges are not inlined here
|
|
1722
|
-
| `matrix.html` | visual matrix of entities × checks
|
|
1723
|
-
| `matrix.json` | the same graph (AI-friendly), including a mermaid string
|
|
1724
|
-
| `issue-repro/*.sh` | one executable `curl` script per finding that has evidence. Directory is omitted when the run is clean
|
|
1725
|
-
| `progress.log` | logfmt, one event per line, never truncated
|
|
1726
|
-
| `progress.jsonl` | same events as JSON
|
|
1727
|
-
| `progress.tsv` | same columns, tab-separated. `req_id` is the join key to the exchange journal
|
|
1728
|
-
| `progress.json` | latest snapshot only (overwritten ~1s)
|
|
1729
|
-
| `exchanges.jsonl` | one line per request (`seq`, `requestId`, method, url, status, bytes, …). Greppable
|
|
1730
|
-
| `exchanges/<requestId>.json` | full exchange: status, headers, described bodies. Missing id → `seq-<n>.json`. Duplicate id → `-<seq>`
|
|
1731
|
-
| `blobs/<sha256>` | content-addressed file parts and oversized / binary bodies
|
|
1760
|
+
| file | |
|
|
1761
|
+
| ---------------------------- | -------------------------------------------------------------------------------------------------------------------------- |
|
|
1762
|
+
| `oat-report.md` | human report: scope, per-operation status, summary, findings with request/response excerpts, coverage, latency p50/p95/max |
|
|
1763
|
+
| `oat-report.json` | same data for CI. Summary only — full exchanges are not inlined here |
|
|
1764
|
+
| `matrix.html` | visual matrix of entities × checks |
|
|
1765
|
+
| `matrix.json` | the same graph (AI-friendly), including a mermaid string |
|
|
1766
|
+
| `issue-repro/*.sh` | one executable `curl` script per finding that has evidence. Directory is omitted when the run is clean |
|
|
1767
|
+
| `progress.log` | logfmt, one event per line, never truncated |
|
|
1768
|
+
| `progress.jsonl` | same events as JSON |
|
|
1769
|
+
| `progress.tsv` | same columns, tab-separated. `req_id` is the join key to the exchange journal |
|
|
1770
|
+
| `progress.json` | latest snapshot only (overwritten ~1s) |
|
|
1771
|
+
| `exchanges.jsonl` | one line per request (`seq`, `requestId`, method, url, status, bytes, …). Greppable |
|
|
1772
|
+
| `exchanges/<requestId>.json` | full exchange: status, headers, described bodies. Missing id → `seq-<n>.json`. Duplicate id → `-<seq>` |
|
|
1773
|
+
| `blobs/<sha256>` | content-addressed file parts and oversized / binary bodies |
|
|
1732
1774
|
|
|
1733
1775
|
The journal is oat `Exchange` JSON, not HAR (HAR export is out of scope). Default **on** unless `--profile cheap`. `--no-save-exchanges` skips `exchanges/` entirely. `--quiet` does not. **`--no-save-exchanges` does not reduce transcript RAM** — it only skips the disk journal. The in-memory transcript always drops live `FormData` / `Blob` / `ArrayBuffer` / multi-MiB strings after each hop, keeping citeable metadata and content-addressed body descriptors. Reconstruct bytes from `blobs/<sha256>` when a check genuinely needs them.
|
|
1734
1776
|
|
|
@@ -1739,6 +1781,8 @@ Redaction is on by default (not opt-in), applied on write:
|
|
|
1739
1781
|
- Headers: `authorization`, `cookie`, `set-cookie`, `proxy-authorization`, and any `x-*-key` / `x-*-secret` / `x-ia-tester-key` (case-insensitive).
|
|
1740
1782
|
- JSON bodies, any depth: `access_token`, `refresh_token`, `id_token`, `password`, `token`, `secret`, `api_key` → `"<redacted>"`.
|
|
1741
1783
|
|
|
1784
|
+
Every report names its scope. The console prints `scope: full · 141 of 212 operations graded` or `scope: targeted · 2 operations (--ops …)` followed by one line per target. `oat-report.md` has a **Scope** line and an **Operations** table: on a full run, every operation in the document with its status (so operations no check ever grades are visible); on a targeted run, the targets only, followed by **Support operations** with call and non-2xx counts. In `matrix.html` / `matrix.json` a check a targeted run did not ask for is `out-of-scope`, distinct from `skipped` (not applicable).
|
|
1785
|
+
|
|
1742
1786
|
Join `progress.tsv` `req_id` to `exchanges.jsonl` `requestId` (response `x-request-id` / `request-id` / `x-correlation-id` / `correlation-id` wins; else what oat sent). `oat-report.md` includes one line such as `1841 exchanges → exchanges/`.
|
|
1743
1787
|
|
|
1744
1788
|
### `oat-report.json`
|
|
@@ -1750,6 +1794,30 @@ Join `progress.tsv` `req_id` to `exchanges.jsonl` `requestId` (response `x-reque
|
|
|
1750
1794
|
"durationMs": 41200,
|
|
1751
1795
|
"requests": 842,
|
|
1752
1796
|
"entitiesTested": ["store", "product"],
|
|
1797
|
+
"scope": {
|
|
1798
|
+
"mode": "targeted",
|
|
1799
|
+
"requested": { "ops": ["product.update"], "only": [] },
|
|
1800
|
+
"operations": [
|
|
1801
|
+
{
|
|
1802
|
+
"operationId": "product.update",
|
|
1803
|
+
"entity": "product",
|
|
1804
|
+
"status": "failed",
|
|
1805
|
+
"checks": {
|
|
1806
|
+
"held": ["concurrency.no-lost-update"],
|
|
1807
|
+
"failed": ["patch.minimality"],
|
|
1808
|
+
"suppressed": [],
|
|
1809
|
+
"inconclusive": [],
|
|
1810
|
+
"gaps": []
|
|
1811
|
+
},
|
|
1812
|
+
"findings": 1,
|
|
1813
|
+
"reason": null
|
|
1814
|
+
}
|
|
1815
|
+
],
|
|
1816
|
+
"support": [{ "operationId": "product.create", "calls": 9, "non2xx": 0 }],
|
|
1817
|
+
"excluded": [],
|
|
1818
|
+
"originsSkipped": []
|
|
1819
|
+
},
|
|
1820
|
+
"checksOutOfScope": [{ "check": "filter.in-is-union-of-eq", "entity": "product" }],
|
|
1753
1821
|
"checksRun": ["list.read-after-write", "patch.minimality"],
|
|
1754
1822
|
"checksSkipped": [{ "check": "async.reaches-terminal-state", "entity": "store", "needs": "…" }],
|
|
1755
1823
|
"checksSuppressed": [{ "check": "query.axes-compose", "entity": "store", "because": "list.read-after-write" }],
|
|
@@ -1918,7 +1986,9 @@ const result = await run({
|
|
|
1918
1986
|
})
|
|
1919
1987
|
|
|
1920
1988
|
// result.findings, result.checksSkipped, result.checksSuppressed,
|
|
1921
|
-
// result.inconclusive, result.entitiesTested, result.teardown, result.created
|
|
1989
|
+
// result.inconclusive, result.entitiesTested, result.teardown, result.created,
|
|
1990
|
+
// result.scope (per-operation status), result.checksOutOfScope
|
|
1991
|
+
// pass `ops: ["product.update"]` to run() for a targeted run; ScopeError on an unknown name
|
|
1922
1992
|
```
|
|
1923
1993
|
|
|
1924
1994
|
`loadConfig(path)` loads `.ts` / `.js` / `.mjs` / `.json` the same way the CLI does. The CLI then expands `${NAME}` in every string. `defineConfig` is an identity function for typing; it does not interpolate. If you call `run()` with an in-process object, resolve secrets yourself (template literals, `process.env`) before passing it.
|
|
@@ -2058,6 +2128,7 @@ These are deliberate. An agent should not invent a flag for them.
|
|
|
2058
2128
|
- **`or()` is postgrest-only.**
|
|
2059
2129
|
- **Leftover rows on a shared DB** poison numeric and filter checks. Wipe between runs.
|
|
2060
2130
|
- **`--only` uses plan names** (`store`, not `stores` or `/v1/stores`).
|
|
2131
|
+
- **`--ops` trusts support operations.** A targeted green means the targets held, given that what they needed worked. A defect in an untargeted operation is out of scope, even when a target called it.
|
|
2061
2132
|
- **Default cohort is 7.** `pagination.limit-respects-documented-max` needs `cohortSize > maxLimit`.
|
|
2062
2133
|
- **First principal is the writer.** Extra principals are peers / lattice, not a pool of writers.
|
|
2063
2134
|
|
package/dist/cli.js
CHANGED
|
@@ -10,6 +10,7 @@ import { ISSUE_REPRO_DIR, renderConsole, renderJson, renderMarkdown, renderRepro
|
|
|
10
10
|
import { createProgressPump, createStderrProgress, formatProgressJsonl, formatProgressLine, formatProgressTsv, PROGRESS_GLOSSARY, PROGRESS_TSV_HEADER, } from "./runtime/progress.js";
|
|
11
11
|
import { resolveSaveExchanges } from "./runtime/exchanges.js";
|
|
12
12
|
import { allocateRunDir, DEFAULT_RUNS_ROOT } from "./runtime/runs.js";
|
|
13
|
+
import { authStepOperationIds, planScope, resolveTargetScope, ScopeError } from "./runtime/scope.js";
|
|
13
14
|
import { renderTeardown } from "./runtime/teardown.js";
|
|
14
15
|
import { buildModel } from "./spec/graph.js";
|
|
15
16
|
import { dereference, loadSpec } from "./spec/load.js";
|
|
@@ -19,6 +20,7 @@ export const KNOWN_FLAGS = new Set([
|
|
|
19
20
|
"spec",
|
|
20
21
|
"base-url",
|
|
21
22
|
"only",
|
|
23
|
+
"ops",
|
|
22
24
|
"profile",
|
|
23
25
|
"seed",
|
|
24
26
|
"out",
|
|
@@ -74,7 +76,8 @@ Flags
|
|
|
74
76
|
--config oat config module (.ts/.js/.mjs/.json) with a default export
|
|
75
77
|
--spec OpenAPI document, http(s) URL or filesystem path
|
|
76
78
|
--base-url backend under test, overriding the config
|
|
77
|
-
--
|
|
79
|
+
--ops comma-separated operationIds to grade (row.*, cdn:asset.get); the rest is support
|
|
80
|
+
--only comma-separated entity names; each grades every operation it owns
|
|
78
81
|
--profile named profile gating which operations run (built-in: full, cheap)
|
|
79
82
|
--seed integer seed for fixture generation (default 1)
|
|
80
83
|
--out history root; each run is <out>/<datetime>/ (default ./.oat/runs)
|
|
@@ -97,6 +100,26 @@ function str(flags, key) {
|
|
|
97
100
|
const value = flags[key];
|
|
98
101
|
return typeof value === "string" ? value : undefined;
|
|
99
102
|
}
|
|
103
|
+
function list(flags, key) {
|
|
104
|
+
return str(flags, key)
|
|
105
|
+
?.split(",")
|
|
106
|
+
.map((s) => s.trim())
|
|
107
|
+
.filter(Boolean);
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Exit code for a finished run. Root causes fail it, not raw findings: gaps and blocked entries
|
|
111
|
+
* are information. A targeted run also fails unless every target held — under `--ops` a target
|
|
112
|
+
* nothing graded must not read as a pass.
|
|
113
|
+
*/
|
|
114
|
+
export function exitCode(result) {
|
|
115
|
+
if (result.network?.incomplete === true)
|
|
116
|
+
return 1;
|
|
117
|
+
if (result.findings.some((f) => f.verdict !== "COVERAGE_GAP" && f.verdict !== "BLOCKED"))
|
|
118
|
+
return 1;
|
|
119
|
+
if (result.scope.mode === "targeted" && result.scope.operations.some((op) => op.status !== "held"))
|
|
120
|
+
return 1;
|
|
121
|
+
return 0;
|
|
122
|
+
}
|
|
100
123
|
async function commandRun(flags) {
|
|
101
124
|
const configPath = str(flags, "config");
|
|
102
125
|
if (configPath === undefined) {
|
|
@@ -107,11 +130,8 @@ async function commandRun(flags) {
|
|
|
107
130
|
const config = interpolate(await loadConfig(configPath));
|
|
108
131
|
const baseUrl = str(flags, "base-url") ?? config.baseUrl;
|
|
109
132
|
const seedFlag = str(flags, "seed");
|
|
110
|
-
const
|
|
111
|
-
|
|
112
|
-
.map((s) => s.trim())
|
|
113
|
-
.filter(Boolean);
|
|
114
|
-
const only = onlyFromFlag ?? config.only?.filter((name) => name.trim() !== "");
|
|
133
|
+
const only = list(flags, "only") ?? config.only?.filter((name) => name.trim() !== "");
|
|
134
|
+
const ops = list(flags, "ops") ?? config.ops?.filter((name) => name.trim() !== "");
|
|
115
135
|
const profile = str(flags, "profile") ?? config.profile;
|
|
116
136
|
const saveExchanges = resolveSaveExchanges({
|
|
117
137
|
...(flags["no-save-exchanges"] === true ? { flag: false } : flags["save-exchanges"] === true ? { flag: true } : {}),
|
|
@@ -169,6 +189,7 @@ async function commandRun(flags) {
|
|
|
169
189
|
...(config.roots === undefined ? {} : { roots: config.roots }),
|
|
170
190
|
...(config.cohortSize === undefined ? {} : { cohortSize: config.cohortSize }),
|
|
171
191
|
...(only === undefined || only.length === 0 ? {} : { only }),
|
|
192
|
+
...(ops === undefined || ops.length === 0 ? {} : { ops }),
|
|
172
193
|
...(profile === undefined ? {} : { profile }),
|
|
173
194
|
...(config.profiles === undefined ? {} : { profiles: config.profiles }),
|
|
174
195
|
...(config.rateLimits === undefined ? {} : { rateLimits: config.rateLimits }),
|
|
@@ -184,6 +205,12 @@ async function commandRun(flags) {
|
|
|
184
205
|
...(config.network === undefined ? {} : { network: config.network }),
|
|
185
206
|
});
|
|
186
207
|
}
|
|
208
|
+
catch (error) {
|
|
209
|
+
if (!(error instanceof ScopeError))
|
|
210
|
+
throw error;
|
|
211
|
+
process.stderr.write(`${error.message}\n`);
|
|
212
|
+
return 2;
|
|
213
|
+
}
|
|
187
214
|
finally {
|
|
188
215
|
stderrProgress?.stop();
|
|
189
216
|
fileProgress.stop();
|
|
@@ -205,6 +232,7 @@ async function commandRun(flags) {
|
|
|
205
232
|
model: result.model,
|
|
206
233
|
profile: result.profile,
|
|
207
234
|
profileExclusions: result.profileExclusions,
|
|
235
|
+
scope: result.scope,
|
|
208
236
|
startedAt,
|
|
209
237
|
...(result.exchanges === undefined ? {} : { exchanges: result.exchanges }),
|
|
210
238
|
...(result.network === undefined ? {} : { network: result.network }),
|
|
@@ -237,11 +265,7 @@ async function commandRun(flags) {
|
|
|
237
265
|
process.stdout.write(` network: ${result.network.kind} — run incomplete\n`);
|
|
238
266
|
}
|
|
239
267
|
process.stdout.write(` latest: ${allocated.latest}\n\n`);
|
|
240
|
-
|
|
241
|
-
* not failures, and a CI gate should react to defects only. */
|
|
242
|
-
if (result.network?.incomplete === true)
|
|
243
|
-
return 1;
|
|
244
|
-
return result.findings.filter((f) => f.verdict !== "COVERAGE_GAP" && f.verdict !== "BLOCKED").length > 0 ? 1 : 0;
|
|
268
|
+
return exitCode(result);
|
|
245
269
|
}
|
|
246
270
|
export async function main() {
|
|
247
271
|
const { command, flags } = parseArgs(process.argv.slice(2));
|
|
@@ -436,7 +460,8 @@ export async function main() {
|
|
|
436
460
|
return commandRun(flags);
|
|
437
461
|
const specFlag = str(flags, "spec");
|
|
438
462
|
const configPath = str(flags, "config");
|
|
439
|
-
const
|
|
463
|
+
const loaded = configPath === undefined ? undefined : await loadConfig(configPath);
|
|
464
|
+
const specSource = specFlag ?? loaded?.spec;
|
|
440
465
|
if (specSource === undefined) {
|
|
441
466
|
process.stderr.write("oat: --spec (or --config) is required\n\n" + USAGE);
|
|
442
467
|
return 2;
|
|
@@ -454,9 +479,26 @@ export async function main() {
|
|
|
454
479
|
throw error;
|
|
455
480
|
}
|
|
456
481
|
switch (command) {
|
|
457
|
-
case "plan":
|
|
458
|
-
|
|
482
|
+
case "plan": {
|
|
483
|
+
const ops = list(flags, "ops") ?? loaded?.ops;
|
|
484
|
+
const only = list(flags, "only") ?? loaded?.only;
|
|
485
|
+
let scope;
|
|
486
|
+
try {
|
|
487
|
+
scope = planScope(model, resolveTargetScope(model, {
|
|
488
|
+
...(ops === undefined ? {} : { ops }),
|
|
489
|
+
...(only === undefined ? {} : { only }),
|
|
490
|
+
authCreates: authStepOperationIds(loaded?.principals ?? []),
|
|
491
|
+
}));
|
|
492
|
+
}
|
|
493
|
+
catch (error) {
|
|
494
|
+
if (!(error instanceof ScopeError))
|
|
495
|
+
throw error;
|
|
496
|
+
process.stderr.write(`${error.message}\n`);
|
|
497
|
+
return 2;
|
|
498
|
+
}
|
|
499
|
+
process.stdout.write(report.plan(model, flags.json === true, scope.mode === "targeted" ? scope : undefined));
|
|
459
500
|
return 0;
|
|
501
|
+
}
|
|
460
502
|
case "doctor": {
|
|
461
503
|
const config = configPath === undefined ? undefined : interpolate(await loadConfig(configPath));
|
|
462
504
|
const output = report.doctor(model, externalRefs, flags.json === true, config === undefined
|
|
@@ -395,8 +395,14 @@ export interface OatConfig {
|
|
|
395
395
|
cohortSize?: number;
|
|
396
396
|
/** Requests allowed in flight at once. Past a server's comfort this makes runs slower. */
|
|
397
397
|
maxInFlight?: number;
|
|
398
|
-
/**
|
|
398
|
+
/** Grade every operation these entities own, and nothing else. Joins `ops` as a union. */
|
|
399
399
|
only?: string[];
|
|
400
|
+
/**
|
|
401
|
+
* Grade only these operationIds; every other operation is support — called to reach or observe
|
|
402
|
+
* a target, never graded. `*` globs within an id (`row.*`); `<originId>:<operationId>` targets a
|
|
403
|
+
* secondary origin. `--ops` on the CLI replaces this list.
|
|
404
|
+
*/
|
|
405
|
+
ops?: string[];
|
|
400
406
|
/**
|
|
401
407
|
* Named profiles this run can select between, keyed by name. `"full"` and `"cheap"` exist
|
|
402
408
|
* implicitly and need no entry here; add one only for a profile a cost band can't express.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"define-config.d.ts","sourceRoot":"","sources":["../../src/config/define-config.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"define-config.d.ts","sourceRoot":"","sources":["../../src/config/define-config.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"define-config.js","sourceRoot":"","sources":["../../src/config/define-config.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAwIH,MAAM,UAAU,UAAU,CAAC,IAAmB;IAC7C,OAAO,UAAU,IAAI,IAAI,IAAI,OAAO,IAAI,CAAC,QAAQ,KAAK,QAAQ,IAAI,CAAC,CAAC,OAAO,IAAI,IAAI,CAAC,CAAA;AACrF,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,IAAmB;IAC7C,OAAO,OAAO,IAAI,IAAI,CAAA;AACvB,CAAC;
|
|
1
|
+
{"version":3,"file":"define-config.js","sourceRoot":"","sources":["../../src/config/define-config.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAwIH,MAAM,UAAU,UAAU,CAAC,IAAmB;IAC7C,OAAO,UAAU,IAAI,IAAI,IAAI,OAAO,IAAI,CAAC,QAAQ,KAAK,QAAQ,IAAI,CAAC,CAAC,OAAO,IAAI,IAAI,CAAC,CAAA;AACrF,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,IAAmB;IAC7C,OAAO,OAAO,IAAI,IAAI,CAAA;AACvB,CAAC;AAkWD;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,YAAY,CAAC,MAAiB;IAC7C,OAAO,MAAM,CAAA;AACd,CAAC"}
|
package/dist/index.d.ts
CHANGED
|
@@ -17,6 +17,8 @@ export { NetworkError, classifyNetworkError, isNetworkError } from "./runtime/ne
|
|
|
17
17
|
export type { NetworkKind } from "./runtime/network.ts";
|
|
18
18
|
export { run } from "./runtime/run.ts";
|
|
19
19
|
export type { RunOptions, RunResult } from "./runtime/run.ts";
|
|
20
|
+
export { planScope, resolveTargetScope, ScopeError } from "./runtime/scope.ts";
|
|
21
|
+
export type { OperationCoverage, OperationStatus, ScopePlan, ScopeReport, SupportUse, TargetScope, } from "./runtime/scope.ts";
|
|
20
22
|
export type { Actor } from "./runtime/checks.ts";
|
|
21
23
|
export type { Finding, Verdict } from "./runtime/finding.ts";
|
|
22
24
|
export { buildMatrixGraph, matrixViewFromReport, renderMatrixGraph, renderMatrixHtml } from "./report/matrix.ts";
|
package/dist/index.js
CHANGED
|
@@ -9,6 +9,7 @@ export { dereference, loadSpec, normalisePath, parseRouteRef } from "./spec/load
|
|
|
9
9
|
export { AuthRefreshRequiredError } from "./runtime/auth.js";
|
|
10
10
|
export { NetworkError, classifyNetworkError, isNetworkError } from "./runtime/network.js";
|
|
11
11
|
export { run } from "./runtime/run.js";
|
|
12
|
+
export { planScope, resolveTargetScope, ScopeError } from "./runtime/scope.js";
|
|
12
13
|
export { buildMatrixGraph, matrixViewFromReport, renderMatrixGraph, renderMatrixHtml } from "./report/matrix.js";
|
|
13
14
|
export { coverageByCheck, renderConsole, renderJson, renderMarkdown, renderRepros } from "./report/render.js";
|
|
14
15
|
//# sourceMappingURL=index.js.map
|
package/dist/report/console.d.ts
CHANGED
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
*/
|
|
8
8
|
import type { EntityConfig, OatConfig, QueryCapabilities } from "../config/define-config.ts";
|
|
9
9
|
import type { SpecModel } from "../spec/graph.ts";
|
|
10
|
+
import { type ScopePlan } from "../runtime/scope.ts";
|
|
10
11
|
export interface DoctorConfig {
|
|
11
12
|
query?: QueryCapabilities;
|
|
12
13
|
entities?: Record<string, EntityConfig>;
|
|
@@ -27,7 +28,7 @@ export interface DoctorConfig {
|
|
|
27
28
|
* not apply.
|
|
28
29
|
*/
|
|
29
30
|
export declare const TAG_UNLOCKS: Record<string, readonly string[]>;
|
|
30
|
-
declare function plan(model: SpecModel, asJson: boolean): string;
|
|
31
|
+
declare function plan(model: SpecModel, asJson: boolean, scope?: ScopePlan): string;
|
|
31
32
|
declare function doctor(model: SpecModel, externalRefs: string[], asJson: boolean, config?: DoctorConfig): {
|
|
32
33
|
text: string;
|
|
33
34
|
blocking: number;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"console.d.ts","sourceRoot":"","sources":["../../src/report/console.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,SAAS,EAAE,iBAAiB,EAAE,MAAM,4BAA4B,CAAA;AAE5F,OAAO,KAAK,EAAe,SAAS,EAAE,MAAM,kBAAkB,CAAA;
|
|
1
|
+
{"version":3,"file":"console.d.ts","sourceRoot":"","sources":["../../src/report/console.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,SAAS,EAAE,iBAAiB,EAAE,MAAM,4BAA4B,CAAA;AAE5F,OAAO,KAAK,EAAe,SAAS,EAAE,MAAM,kBAAkB,CAAA;AAC9D,OAAO,EAAqB,KAAK,SAAS,EAAE,MAAM,qBAAqB,CAAA;AAUvE,MAAM,WAAW,YAAY;IAC5B,KAAK,CAAC,EAAE,iBAAiB,CAAA;IACzB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,YAAY,CAAC,CAAA;IACvC,KAAK,CAAC,EAAE,IAAI,CAAC,WAAW,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,EAAE,0BAA0B,CAAC,CAAA;CACzE;AAED;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CA+BzD,CAAA;AA0CD,iBAAS,IAAI,CAAC,KAAK,EAAE,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,CAAC,EAAE,SAAS,GAAG,MAAM,CAuE1E;AA2MD,iBAAS,MAAM,CACd,KAAK,EAAE,SAAS,EAChB,YAAY,EAAE,MAAM,EAAE,EACtB,MAAM,EAAE,OAAO,EACf,MAAM,CAAC,EAAE,YAAY,GACnB;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,CA8OpC;AAED,eAAO,MAAM,MAAM;;;CAAmB,CAAA"}
|
package/dist/report/console.js
CHANGED
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
* and work the list down.
|
|
7
7
|
*/
|
|
8
8
|
import { formatUniqueSets } from "../spec/extensions.js";
|
|
9
|
+
import { describeRequested } from "../runtime/scope.js";
|
|
9
10
|
import { canWriteFilterOp } from "../spec/conventions.js";
|
|
10
11
|
import { anyFieldAllows, fieldAllowsNulls, mergeQueryCapabilities, opsAreClosed, } from "../spec/query-capabilities.js";
|
|
11
12
|
/**
|
|
@@ -89,17 +90,20 @@ function lifecycleGlyphs(entity) {
|
|
|
89
90
|
];
|
|
90
91
|
return slots.map(([letter, opId]) => (opId === undefined ? "·" : letter)).join("");
|
|
91
92
|
}
|
|
92
|
-
function plan(model, asJson) {
|
|
93
|
+
function plan(model, asJson, scope) {
|
|
93
94
|
if (asJson) {
|
|
94
95
|
return `${JSON.stringify({
|
|
95
96
|
entities: [...model.entities.values()],
|
|
96
97
|
operations: model.operations,
|
|
97
98
|
roots: model.roots,
|
|
99
|
+
...(scope === undefined ? {} : { scope }),
|
|
98
100
|
unique: [...model.entities.values()]
|
|
99
101
|
.filter((entity) => entity.unique !== null)
|
|
100
102
|
.map((entity) => ({ entity: entity.name, unique: entity.unique })),
|
|
101
103
|
}, null, 2)}\n`;
|
|
102
104
|
}
|
|
105
|
+
if (scope !== undefined)
|
|
106
|
+
return planScopeText(scope);
|
|
103
107
|
const lines = [];
|
|
104
108
|
const entities = [...model.entities.values()].sort((a, b) => a.name.localeCompare(b.name));
|
|
105
109
|
lines.push("");
|
|
@@ -147,6 +151,34 @@ function plan(model, asJson) {
|
|
|
147
151
|
lines.push("");
|
|
148
152
|
return lines.join("\n");
|
|
149
153
|
}
|
|
154
|
+
/** What a targeted run would grade, queue and call — the dry run behind `oat plan --ops`. */
|
|
155
|
+
function planScopeText(scope) {
|
|
156
|
+
const lines = ["", ` scope: targeted (${describeRequested(scope.requested)})`, ""];
|
|
157
|
+
const width = Math.max(12, ...[...scope.targets, ...scope.untestable].map((t) => t.operationId.length)) + 2;
|
|
158
|
+
lines.push(" targets");
|
|
159
|
+
if (scope.targets.length === 0)
|
|
160
|
+
lines.push(" — none gradable");
|
|
161
|
+
for (const target of scope.targets) {
|
|
162
|
+
lines.push(` ${target.operationId.padEnd(width)}entity ${(target.entity ?? "—").padEnd(14)}${target.checks.length} check(s)`);
|
|
163
|
+
}
|
|
164
|
+
if (scope.untestable.length > 0) {
|
|
165
|
+
lines.push(" untestable — a run reports these untested and exits 1");
|
|
166
|
+
for (const item of scope.untestable)
|
|
167
|
+
lines.push(` ${item.operationId.padEnd(width)}${item.reason}`);
|
|
168
|
+
}
|
|
169
|
+
if (scope.excluded.length > 0) {
|
|
170
|
+
lines.push(" excluded by the profile");
|
|
171
|
+
for (const item of scope.excluded)
|
|
172
|
+
lines.push(` ${item.operationId.padEnd(width)}${item.reason}`);
|
|
173
|
+
}
|
|
174
|
+
for (const [origin, ops] of Object.entries(scope.origins)) {
|
|
175
|
+
lines.push(` origin ${origin}: ${ops.join(", ")}`);
|
|
176
|
+
}
|
|
177
|
+
lines.push(` entities queued: ${scope.entities.length === 0 ? "none" : scope.entities.join(", ")}`);
|
|
178
|
+
lines.push(` support (called, never graded): ${scope.support.length === 0 ? "none" : scope.support.join(", ")}`);
|
|
179
|
+
lines.push("");
|
|
180
|
+
return lines.join("\n");
|
|
181
|
+
}
|
|
150
182
|
function inviteAcceptMode(spec) {
|
|
151
183
|
if (spec === null)
|
|
152
184
|
return "—";
|