specguard-mcp 0.1.41 → 0.1.42
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 +117 -20
- package/dist/src/tools/near-duplicate-clusters.d.ts +41 -20
- package/dist/src/tools/near-duplicate-clusters.js +123 -33
- package/dist/src/tools/near-duplicate-clusters.js.map +1 -1
- package/dist/src/tools/repository-overview.js +110 -28
- package/dist/src/tools/repository-overview.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -193,13 +193,13 @@ before any request is made.
|
|
|
193
193
|
| argument | |
|
|
194
194
|
| --- | --- |
|
|
195
195
|
| `repository` | ask about THIS repository (its numeric id from `list_repositories`) under the **agent key** (`SPECGUARD_AGENT_API_KEY`, `sga_…`), or — when no agent key is set — the **user key** (`SPECGUARD_USER_API_KEY`, `sgu_…`), instead of the one the `sgk_…` key resolves to — omit it for the default, `sgk_`-keyed call |
|
|
196
|
-
| `branch` | narrow the run **history** to one branch, for a real growth series — and unlock `unstable_tests` and `directory_growth`, which read the same window |
|
|
196
|
+
| `branch` | narrow the run **history** to one branch, for a real growth series — and unlock `unstable_tests`, `slowest_tests` (with `slowest_tests_window`) and `directory_growth`, which read the same window |
|
|
197
197
|
| `spec_directory` | open ONE of the heaviest directories and list the spec files inside it |
|
|
198
198
|
| `spec_file` | open ONE of the heaviest spec files and list the individual examples inside it |
|
|
199
199
|
| `repeated_description` | open ONE repeated description and list the examples that all share it |
|
|
200
200
|
| `unstable_test` | open ONE flaky test and list its outcome run by run across the window, newest run first (needs `branch`) |
|
|
201
201
|
| `commit_sha` | anchor the answer on ONE named run instead of the repository's newest one — every run-grain block moves with it, `history` does not |
|
|
202
|
-
| `layer` | narrow
|
|
202
|
+
| `layer` | narrow `latest_run.slowest_examples` — and, when `branch` is also asked, the cross-run `slowest_tests` — to one declared layer (`unit`, `integration`, `request`, `system` or `undeclared`) — see below |
|
|
203
203
|
| `unannotated_examples` | `true` to list the individual tests carrying no `@intent` — the examples behind the annotated ratio, each labelled with what SpecGuard reads of it — and, in the same answer, which areas carry the most of them |
|
|
204
204
|
|
|
205
205
|
`branch` narrows `history` only — `latest_run` always names the repository's newest run, which on a
|
|
@@ -221,12 +221,13 @@ bookmark, a pruned run, a commit whose CI never reported — does not error: the
|
|
|
221
221
|
falls back to the newest run and says so, so read `run_anchor.resolved` rather than trusting that a
|
|
222
222
|
successful response is about the commit you named.
|
|
223
223
|
|
|
224
|
-
`branch` is also the gate on the
|
|
225
|
-
it: `unstable_tests` (which tests failed intermittently across the window rather than consistently)
|
|
226
|
-
|
|
224
|
+
`branch` is also the gate on the three blocks read over that same window, and they are `null` without
|
|
225
|
+
it: `unstable_tests` (which tests failed intermittently across the window rather than consistently),
|
|
226
|
+
`slowest_tests` with its `slowest_tests_window` (which durable tests cost the most wall clock across
|
|
227
|
+
the window) and `directory_growth` (how each area moved between the two **endpoints** of the window). The
|
|
227
228
|
per-area comparisons against the **previous run** — `directory_run_growth` at the example-count
|
|
228
229
|
grain, `directory_runtime_growth` at the runtime grain, and `layer_run_growth` for the declared-layer
|
|
229
|
-
mix — are a different question and take no branch at all: they scope to the latest run's own branch by construction, so a plain unparameterised
|
|
230
|
+
mix, and `layer_runtime_growth` for the time each declared layer accounts for — are a different question and take no branch at all: they scope to the latest run's own branch by construction, so a plain unparameterised
|
|
230
231
|
call already carries them. The two grains are independent, which is why both ship: making an
|
|
231
232
|
existing spec slow adds zero examples and shows up only in the runtime pair, and splitting one slow
|
|
232
233
|
spec into four fast ones is `+3` examples and *less* time.
|
|
@@ -247,7 +248,8 @@ since the previous run, and `directory_runtime_file_growth` for which of them ch
|
|
|
247
248
|
two are the answer to the question the area-grain comparisons dead-end on — `spec/models 412 → 459
|
|
248
249
|
(+47)`, but *which files did that* — so they need no second parameter.
|
|
249
250
|
|
|
250
|
-
`spec_files` ranks the heaviest files
|
|
251
|
+
`spec_files` ranks the heaviest files (each row: `path`, `total_seconds`, `recorded_count`,
|
|
252
|
+
`timed_count`, `layer_counts`) but stops at the file grain, so it says *which files* cost the
|
|
251
253
|
most and not *which examples* inside them spent it. `spec_file` is the next question: pass a path
|
|
252
254
|
exactly as served in `latest_run.spec_files.rows[].path` and `latest_run.spec_file_examples` opens
|
|
253
255
|
with up to 50 of that file's individual examples, cut by **duration** (`name`, `file_path`,
|
|
@@ -259,7 +261,8 @@ key is `null`, meaning *you did not ask*; a path that matched nothing answers `r
|
|
|
259
261
|
an error, so a renamed or deleted spec file and a stale bookmark are empty results and not failures.
|
|
260
262
|
|
|
261
263
|
`repeated_descriptions` ranks the descriptions carried by the most examples — the overcoverage
|
|
262
|
-
ranking
|
|
264
|
+
ranking; each row: `name`, `total_seconds`, `recorded_count`, `timed_count`, `files_seen`,
|
|
265
|
+
`layer_counts` — but names the description and the files it was seen in, not *which* examples say the same
|
|
263
266
|
thing. `repeated_description` is the next question: pass a description exactly as served in
|
|
264
267
|
`latest_run.repeated_descriptions.rows[].name` and `latest_run.repeated_description_examples` opens
|
|
265
268
|
with up to 25 of that group's members (the same eight fields), plus the **group's** own
|
|
@@ -309,6 +312,33 @@ and never off its index: a run that recorded nothing under the description contr
|
|
|
309
312
|
description carried by two examples in one run contributes two, so `rows` is not one entry per run
|
|
310
313
|
and its length is not the window's `run_count`.
|
|
311
314
|
|
|
315
|
+
`slowest_tests_window` + `slowest_tests` are the cross-run runtime ranking, a top-level pair beside
|
|
316
|
+
`unstable_tests`: one row per **durable test** (a moved or renamed test keeps its history), ranked by
|
|
317
|
+
its window `total_seconds`, nulls last. It is a different grain from `latest_run.slowest_examples`,
|
|
318
|
+
which is one run at coordinate grain (file and line). Both keys are `null` without `branch`
|
|
319
|
+
(`slowest_tests_window.grouped` is true exactly when `slowest_tests` is non-null), so `branch` is a
|
|
320
|
+
hard prerequisite here as it is for `unstable_test`. Add `layer` to narrow it to one declared layer (echoed as `slowest_tests_window.layer`).
|
|
321
|
+
|
|
322
|
+
`slowest_tests.state` is four-way and only the last value is a result: `no_runs` (the window is
|
|
323
|
+
empty), `unrecorded` (the anchor run wrote no per-example rows), `unresolved` (it wrote rows and none
|
|
324
|
+
has been matched to a durable test yet — the ordinary state for the seconds after an ingest, since
|
|
325
|
+
identity resolution is asynchronous) and `ranked`. Only `ranked` with `rows: []` means nothing in the
|
|
326
|
+
suite is slow. `anchor_run` (`test_run_id`, `commit_sha`, `branch`, `ingested_at`; `null` only in
|
|
327
|
+
`no_runs`) names the run that decided membership: candidates are the **newest** run's slowest tests
|
|
328
|
+
and the window only supplies their history, so a test that ran earlier in the window but not in the
|
|
329
|
+
newest run is not listed. `truncated`, `unexamined_count` and `limit` disclose the candidate cap. `recorded`, `resolved`,
|
|
330
|
+
`excluded_unresolved_rows`, `untimed_count`, `complete` and `run_count` are the booleans and operands
|
|
331
|
+
beside them.
|
|
332
|
+
`recorded_count`, `unresolved_count`, `candidate_count`, `resolved_count` and `timed_count` are
|
|
333
|
+
`null` — not `0` — in every state that returned before the read that would have produced them; a `0`
|
|
334
|
+
is a measured zero.
|
|
335
|
+
|
|
336
|
+
Each `slowest_tests.rows[]` row carries `spec_identity_id`, `total_seconds` / `slowest_seconds`
|
|
337
|
+
(`null` when untimed, never a zero), `moved` / `renamed` with their operands `files_seen` /
|
|
338
|
+
`descriptions`, and `declared_layers` — the sorted distinct set of `@intent layer:` values the test
|
|
339
|
+
declared in the window. `[]` means none declared; it is declared-only, never inferred from the spec
|
|
340
|
+
path.
|
|
341
|
+
|
|
312
342
|
`annotated_ratio` is the product's adoption metric and it was the one population on this endpoint
|
|
313
343
|
you could not walk down: the dashboard printed *"SpecGuard cannot see the other N tests"* and could
|
|
314
344
|
not name one of them either, so an agent told to raise annotation coverage learned how far it had to
|
|
@@ -343,11 +373,20 @@ real denominator for any average. The whole key is `null` when the run stored no
|
|
|
343
373
|
a **sum** of example durations — machine time and **not wall clock** — so it can exceed
|
|
344
374
|
`duration_seconds` on a parallel or sharded run. The layer is **declared only**, never inferred from the
|
|
345
375
|
path, and the operands carry no pyramid verdict. **Which tests those are**: pass `layer`
|
|
346
|
-
(`unit`, `integration`, `request`, `system` or `undeclared`) to narrow `latest_run.slowest_examples`
|
|
347
|
-
|
|
348
|
-
asked, `
|
|
349
|
-
|
|
350
|
-
|
|
376
|
+
(`unit`, `integration`, `request`, `system` or `undeclared`) to narrow `latest_run.slowest_examples` (run
|
|
377
|
+
grain, moves with `commit_sha`, echoed as `slowest_examples.layer`) **and**, only when `branch` is also
|
|
378
|
+
asked, the cross-run `slowest_tests` (window grain, does **not** move with `commit_sha`, echoed as
|
|
379
|
+
`slowest_tests_window.layer`, which is absent when `branch` is not asked or the value is malformed) to one
|
|
380
|
+
declared layer. On `slowest_tests` the candidate step is narrowed (at least one anchor-run example in the
|
|
381
|
+
layer) while row totals stay the whole durable test's, so `declared_layers` may list several layers;
|
|
382
|
+
`resolved_count`, `candidate_count`, `timed_count` and `untimed_count` become the layer's anchor-run
|
|
383
|
+
figures while `recorded_count` and `unresolved_count` stay whole-run; a layer the anchor never declared
|
|
384
|
+
answers `state: "ranked"` with `rows: []` — not "nothing is slow". It does not narrow `spec_file_examples`,
|
|
385
|
+
`spec_directory_files`, `unannotated_examples` or `repeated_description_examples`. Each echo is present only
|
|
386
|
+
when a layer was asked, `slowest_examples.layer` `recorded_count`/`timed_count`/`reported_outcome_count`
|
|
387
|
+
become that layer's own counts, any other value is read by the server as no ask (so it is forwarded
|
|
388
|
+
unvalidated — verify **both** echoes), and `rows: []` with `recorded_count: 0` means that layer has no
|
|
389
|
+
examples while `slowest_examples: null` means the run
|
|
351
390
|
recorded nothing. **How the declared-layer mix moved since the previous
|
|
352
391
|
run** is `layer_run_growth`, with its contract block `layer_run_growth_window` — both **top-level
|
|
353
392
|
siblings of `directory_run_growth`**, not inside `latest_run` (the delta is not in
|
|
@@ -364,9 +403,31 @@ blocks. `layer_run_growth` is `null` in **every** non-comparable state — **nev
|
|
|
364
403
|
`request`, `system` and `undeclared`, each `{baseline_count, anchor_count, change}`. A layer that did not
|
|
365
404
|
move reads `change: 0` — a **measured zero**, not an absence — and the five `change` values sum to
|
|
366
405
|
`anchor_recorded_count` minus `baseline_recorded_count`. The layers are **declared only**, never inferred
|
|
367
|
-
from the path, `undeclared` is **not** `unreadable`, and the operands carry no pyramid verdict.
|
|
406
|
+
from the path, `undeclared` is **not** `unreadable`, and the operands carry no pyramid verdict.
|
|
407
|
+
**How the time each declared layer accounts for moved since the previous run** is `layer_runtime_growth`,
|
|
408
|
+
with its contract block `layer_runtime_growth_window` — both **top-level siblings of
|
|
409
|
+
`directory_run_growth`**, not inside `latest_run`, exactly as the count pair is. It answers "did my push
|
|
410
|
+
make the request layer N seconds slower?", which `layer_run_growth` (counts) and
|
|
411
|
+
`directory_runtime_growth` (per path) cannot. They compare the latest run with the previous run **on the
|
|
412
|
+
latest run's own branch**, so no `branch` is needed, and `commit_sha` re-anchors them.
|
|
413
|
+
`layer_runtime_growth` is `null` in **every** non-comparable state — **never a block of zeros** — and
|
|
414
|
+
`layer_runtime_growth_window.state` names why: the `layer_run_growth` states (`latest_unmeasured`,
|
|
415
|
+
`previous_unmeasured`, `assembled_differently`, `neither_recorded`, `previous_unrecorded`,
|
|
416
|
+
`latest_unrecorded`), plus `neither_timed`, `previous_untimed` and `latest_untimed` (a run recorded
|
|
417
|
+
example rows but timed none of them), `comparable`, `no_latest_run` and `no_previous_run`.
|
|
418
|
+
`layer_runtime_growth_window.comparable` is true exactly when `layer_runtime_growth` is non-null; the
|
|
419
|
+
window also carries `basis`, `branch`, `anchor_commit_sha` and `baseline_commit_sha`. When comparable,
|
|
420
|
+
`layer_runtime_growth` is `{layers}`, where `layers` holds `unit`, `integration`, `request`, `system` and
|
|
421
|
+
`undeclared`, each `{baseline_seconds, anchor_seconds, baseline_timed_count, anchor_timed_count,
|
|
422
|
+
baseline_count, anchor_count, change}`. `change` is anchor minus baseline in seconds and is `null` —
|
|
423
|
+
**not** `0` — when either side's layer was untimed; a layer timed on both sides that did not move reads
|
|
424
|
+
`change: 0`. It is a **sum of machine time**, not wall clock; layers are **declared only**, a test
|
|
425
|
+
changing its declared `@intent` layer reads as one layer gaining time and another losing it, and no
|
|
426
|
+
verdict is given. The same
|
|
368
427
|
`layer_counts` rides each row of
|
|
369
|
-
`spec_directories`,
|
|
428
|
+
`spec_directories`, each row of `spec_files` and each row of `repeated_descriptions` (the same five
|
|
429
|
+
operands, **declared only** and never inferred from the path, measured zeros, summing to that row's
|
|
430
|
+
`recorded_count`), the `spec_directory_files` area block and each of its file rows, and every
|
|
370
431
|
per-example row of `slowest_examples`, `spec_file_examples` and `repeated_description_examples`
|
|
371
432
|
carries `intent_layer` and `declared_intent` (`{entity, action, behavior}` or `null`, declared only).
|
|
372
433
|
|
|
@@ -703,14 +764,40 @@ never fit this bridge's 30-second deadline. The opt-in ask is unchanged wire con
|
|
|
703
764
|
`near_duplicates: null` without it, and `get_repository_overview` never sends the ask). Calling
|
|
704
765
|
this tool **is** the ask.
|
|
705
766
|
|
|
706
|
-
|
|
707
|
-
every run
|
|
708
|
-
*present* — `=false` would open it too — so there is no value for
|
|
709
|
-
|
|
767
|
+
By default one call returns the **whole** census — the clusters are the repository's, computed over
|
|
768
|
+
every run, with every cluster's member list. (The server reads only that the `near_duplicates` key
|
|
769
|
+
is *present* — `=false` would open it too — so there is no value for that default ask to carry.)
|
|
770
|
+
Two optional arguments bound the view instead (SPGD-1714, over the platform's SPGD-1712), and
|
|
771
|
+
`repository` chooses which **repository** is censused:
|
|
710
772
|
|
|
711
773
|
| argument | |
|
|
712
774
|
| --- | --- |
|
|
713
775
|
| `repository` | census THIS repository (its numeric id from `list_repositories`) under the **agent key** (`SPECGUARD_AGENT_API_KEY`, `sga_…`), or — when no agent key is set — the **user key** (`SPECGUARD_USER_API_KEY`, `sgu_…`), instead of the one the `sgk_…` key resolves to — omit it for the default, `sgk_`-keyed census |
|
|
776
|
+
| `summary` | `true` asks for the bounded **summary** view — the `near_duplicates_summary` block: the ranking with no member lists. `false` or omitted sends nothing (the server treats any value as an ask, so `false` is never sent) |
|
|
777
|
+
| `cluster` | an integer ≥ 1: ask for ONE cluster by its `rank` — the `near_duplicate_cluster` block, members listed once. Not range-checked by the bridge; the server answers an out-of-range rank with `cluster: null` |
|
|
778
|
+
|
|
779
|
+
**Start with `summary`, drill in with `cluster`.** With neither argument the request is exactly the
|
|
780
|
+
one this tool has always made (`?near_duplicates=true`). With `summary` and/or `cluster`, **only**
|
|
781
|
+
the asks named are sent — the whole-census `near_duplicates` block is not also opened; supplying
|
|
782
|
+
both sends both keys, once each. Argument shapes are validated before any request is made
|
|
783
|
+
(`cluster` must be an integer of at least 1; `0`, `-1`, `2.5` and `"3"` are refused).
|
|
784
|
+
|
|
785
|
+
The bounded view's response keys:
|
|
786
|
+
|
|
787
|
+
- `near_duplicates_summary` — the ranking, **head keys first**, then one entry per cluster carrying
|
|
788
|
+
`rank`, `files_seen`, `file_count`, `declared_layers` and `overlap_kind` — and **no member lists**.
|
|
789
|
+
- `near_duplicate_cluster` — one cluster: `requested` (the rank you asked for, echoed), `rank`,
|
|
790
|
+
`cluster_count`, `weighed_run_id`, `computed_at`, `member_listing` (`members` or `layer_groups` —
|
|
791
|
+
which of the two member shapes `cluster` carries) and `cluster` itself.
|
|
792
|
+
- **Ranks are positions in a snapshot** — read `computed_at` before reusing a rank: an ingest or a
|
|
793
|
+
run deletion recomputes the census, and the same rank can then name a different cluster. A rank
|
|
794
|
+
past `cluster_count` is not an error: the key is present with `cluster: null` and `requested`
|
|
795
|
+
echoing the ask.
|
|
796
|
+
- A deployment that predates the bounded view silently ignores the ask. When an ask was sent and
|
|
797
|
+
its matching key is **absent** from the body (absent, not `null` — a present `null` passes
|
|
798
|
+
through), the tool fails naming the missing key rather than returning a body that lacks it.
|
|
799
|
+
|
|
800
|
+
The tool stays a pass-through: no reshaping, filtering or ranking.
|
|
714
801
|
|
|
715
802
|
The credential changes with `repository`, exactly as on `get_repository_overview`: the plural
|
|
716
803
|
endpoint answers **either member credential**, whichever is set — the agent key preferred (its
|
|
@@ -725,6 +812,16 @@ Read the response with its own rules in mind:
|
|
|
725
812
|
|
|
726
813
|
- `similarity_floor` and `similarity_basis` sit **first** in the block and qualify every figure
|
|
727
814
|
below them — a cluster count without what "similar" meant is a count you cannot act on.
|
|
815
|
+
- `ranking_basis` sits in the head of the block (after `layer_source`) and states the order the
|
|
816
|
+
clusters are ranked in: clusters spanning more than one spec file first, then by summed wall
|
|
817
|
+
clock, single-file groups following. So the top row is the costliest **multi-file** cluster, not
|
|
818
|
+
necessarily the costliest overall. Present on current deployments; an absent `ranking_basis`
|
|
819
|
+
means the census was stored under the older cost-only order (costliest first) — not an error.
|
|
820
|
+
- `overlap_kind` on each cluster (and on every summary row) is `multi_file` or `single_file`,
|
|
821
|
+
naming which kind of group the cluster is. It describes where the members' last-known paths sit;
|
|
822
|
+
it is not a verdict (the census says "read as similar", never "duplicate"), and it is
|
|
823
|
+
independent of `layer_redundancy` — a two-file group whose members declared different layers is
|
|
824
|
+
both `multi_file` and `cross_layer`. Absent on older stored censuses.
|
|
728
825
|
- `computed_at` is when the stored census was taken and `weighed_run_id` is the run its weight
|
|
729
826
|
figures are from — read the stamp before acting on the figures. A census read shortly after an
|
|
730
827
|
ingest **or a run deletion** may be the **previous** artifact, carrying its own stamp, while the
|
|
@@ -762,7 +859,7 @@ Read the response with its own rules in mind:
|
|
|
762
859
|
|
|
763
860
|
Without `repository`, same credential and endpoint as `get_repository_overview`'s default
|
|
764
861
|
(`sgk_…` repository key on `GET /api/v1/repository`); the response is that body with the
|
|
765
|
-
`near_duplicates`
|
|
862
|
+
asked-for block opened (`near_duplicates` by default), passed through unmodified. With `repository`, the plural endpoint
|
|
766
863
|
answers either member credential, exactly as on `get_repository_overview` — and carries that
|
|
767
864
|
path's one deliberate omission: `api_key` is **absent** from the plural body rather than nulled,
|
|
768
865
|
because the block describes the credential that made the request and no member credential is a
|
|
@@ -44,33 +44,54 @@ import type { ToolDefinition } from "./types.js";
|
|
|
44
44
|
* run deletion) the stored census is exactly what a live computation would
|
|
45
45
|
* return: the inputs change only there.
|
|
46
46
|
*
|
|
47
|
-
* == The ask is always sent, and always spelled `"true"`
|
|
47
|
+
* == The default ask is always sent, and always spelled `"true"`
|
|
48
48
|
*
|
|
49
49
|
* The server reads only whether the parameter is PRESENT
|
|
50
50
|
* (`RequestedNearDuplicatesParam`): `?near_duplicates=false` opens the block
|
|
51
51
|
* exactly as `=true` does, and a non-String shape is read as no ask at all.
|
|
52
|
-
* There is no "off" value for a client to send, so
|
|
53
|
-
*
|
|
54
|
-
*
|
|
55
|
-
*
|
|
56
|
-
*
|
|
57
|
-
*
|
|
58
|
-
*
|
|
59
|
-
*
|
|
60
|
-
*
|
|
61
|
-
*
|
|
62
|
-
*
|
|
63
|
-
*
|
|
64
|
-
*
|
|
65
|
-
*
|
|
66
|
-
*
|
|
67
|
-
*
|
|
68
|
-
*
|
|
52
|
+
* There is no "off" value for a client to send, so a call with no `summary`
|
|
53
|
+
* and no `cluster` sends `near_duplicates=true` and gets the whole census.
|
|
54
|
+
* What IS choosable is WHICH REPOSITORY is censused (SPGD-953): an optional
|
|
55
|
+
* `repository` argument (a numeric id from `list_repositories`) moves the call
|
|
56
|
+
* to the plural endpoint `GET /api/v1/repositories/:id` under either member
|
|
57
|
+
* credential, whichever is set — the AGENT key preferred, and the USER key (a
|
|
58
|
+
* person credential, whose accessible set is the boundary the id is resolved
|
|
59
|
+
* inside) when no agent key is set; SPGD-1106 widened the plural arm from
|
|
60
|
+
* agent-only, on the same agent-wins/user-fallback terms every
|
|
61
|
+
* either-credential tool answers by. Same body (minus the `api_key` block,
|
|
62
|
+
* which is ABSENT on that surface rather than nulled — see
|
|
63
|
+
* `repository-overview.ts` for why the omission is the server's, deliberately),
|
|
64
|
+
* same ask, same cost gate. Without it the request is byte-for-byte the
|
|
65
|
+
* singular, `sgk_`-bound one this tool has always made — and the cost argument
|
|
66
|
+
* above is exactly why the argument is OPTIONAL rather than required: an agent
|
|
67
|
+
* that has only ever had one reachable repository should not be asked to learn
|
|
68
|
+
* a second credential to keep reading it.
|
|
69
69
|
*
|
|
70
|
-
*
|
|
70
|
+
* == SPGD-1714: the bounded view (`summary`, `cluster`)
|
|
71
|
+
*
|
|
72
|
+
* The platform half (SPGD-1712) serves two further asks on the same endpoints:
|
|
73
|
+
* `?near_duplicates_summary=` (the ranking, head keys first, no member lists)
|
|
74
|
+
* and `?near_duplicate_cluster=<rank>` (ONE cluster, members once). Like the
|
|
75
|
+
* default ask, the server reads only that the summary key is PRESENT, so
|
|
76
|
+
* `summary: false` sends NOTHING rather than `=false` — "off" is spelled by
|
|
77
|
+
* omission. When either bounded ask is made, ONLY the asks named are sent (not
|
|
78
|
+
* also `near_duplicates=true`: that would open the whole census beside the
|
|
79
|
+
* bounded view the caller chose it to avoid). `cluster` is not range-checked
|
|
80
|
+
* here: an out-of-range rank is the server's to answer (a `null` cluster with
|
|
81
|
+
* the ask echoed).
|
|
82
|
+
*
|
|
83
|
+
* Because a deployment that predates SPGD-1712 would silently ignore an
|
|
84
|
+
* unknown parameter and answer 200 with the plain overview, an ask whose
|
|
85
|
+
* matching key is ABSENT from the body (absent, not `null` — a present `null`
|
|
86
|
+
* is the server's own "asked, nothing there") is turned into an error naming
|
|
87
|
+
* the key. Otherwise "asked for the bounded view, got nothing" and "the
|
|
88
|
+
* deployment ignored the ask" would share one wire shape. Nothing else is
|
|
89
|
+
* inspected: the tool stays a pass-through.
|
|
90
|
+
*
|
|
91
|
+
* Every key is built conditionally rather than stringified for the same
|
|
71
92
|
* reason `repository-overview.ts` builds its `unannotated_examples` key:
|
|
72
93
|
* `getJson` omits only `undefined`, so a conditional send is the only honest
|
|
73
|
-
* way to spell "
|
|
94
|
+
* way to spell "only when asked". The schema stays CLOSED around its arguments:
|
|
74
95
|
* `server.ts` forwards `arguments` unvalidated, and an open schema would let an
|
|
75
96
|
* invented argument ride through and be silently dropped (see
|
|
76
97
|
* `registrable-repositories.ts` for the same call).
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
+
import { ApiError } from "../errors.js";
|
|
1
2
|
import { getJsonObject, repositoryTarget } from "../support/specguard-api.js";
|
|
2
|
-
import { optionalString } from "./args.js";
|
|
3
|
+
import { optionalBoolean, optionalPositiveInteger, optionalString } from "./args.js";
|
|
3
4
|
/**
|
|
4
5
|
* `GET /api/v1/repository?near_duplicates=` as a tool — shipped in the
|
|
5
6
|
* platform by SPGD-703 (`specguard` `c43dc19`, 2026-08-28), which added the
|
|
@@ -45,33 +46,54 @@ import { optionalString } from "./args.js";
|
|
|
45
46
|
* run deletion) the stored census is exactly what a live computation would
|
|
46
47
|
* return: the inputs change only there.
|
|
47
48
|
*
|
|
48
|
-
* == The ask is always sent, and always spelled `"true"`
|
|
49
|
+
* == The default ask is always sent, and always spelled `"true"`
|
|
49
50
|
*
|
|
50
51
|
* The server reads only whether the parameter is PRESENT
|
|
51
52
|
* (`RequestedNearDuplicatesParam`): `?near_duplicates=false` opens the block
|
|
52
53
|
* exactly as `=true` does, and a non-String shape is read as no ask at all.
|
|
53
|
-
* There is no "off" value for a client to send, so
|
|
54
|
-
*
|
|
55
|
-
*
|
|
56
|
-
*
|
|
57
|
-
*
|
|
58
|
-
*
|
|
59
|
-
*
|
|
60
|
-
*
|
|
61
|
-
*
|
|
62
|
-
*
|
|
63
|
-
*
|
|
64
|
-
*
|
|
65
|
-
*
|
|
66
|
-
*
|
|
67
|
-
*
|
|
68
|
-
*
|
|
69
|
-
*
|
|
54
|
+
* There is no "off" value for a client to send, so a call with no `summary`
|
|
55
|
+
* and no `cluster` sends `near_duplicates=true` and gets the whole census.
|
|
56
|
+
* What IS choosable is WHICH REPOSITORY is censused (SPGD-953): an optional
|
|
57
|
+
* `repository` argument (a numeric id from `list_repositories`) moves the call
|
|
58
|
+
* to the plural endpoint `GET /api/v1/repositories/:id` under either member
|
|
59
|
+
* credential, whichever is set — the AGENT key preferred, and the USER key (a
|
|
60
|
+
* person credential, whose accessible set is the boundary the id is resolved
|
|
61
|
+
* inside) when no agent key is set; SPGD-1106 widened the plural arm from
|
|
62
|
+
* agent-only, on the same agent-wins/user-fallback terms every
|
|
63
|
+
* either-credential tool answers by. Same body (minus the `api_key` block,
|
|
64
|
+
* which is ABSENT on that surface rather than nulled — see
|
|
65
|
+
* `repository-overview.ts` for why the omission is the server's, deliberately),
|
|
66
|
+
* same ask, same cost gate. Without it the request is byte-for-byte the
|
|
67
|
+
* singular, `sgk_`-bound one this tool has always made — and the cost argument
|
|
68
|
+
* above is exactly why the argument is OPTIONAL rather than required: an agent
|
|
69
|
+
* that has only ever had one reachable repository should not be asked to learn
|
|
70
|
+
* a second credential to keep reading it.
|
|
70
71
|
*
|
|
71
|
-
*
|
|
72
|
+
* == SPGD-1714: the bounded view (`summary`, `cluster`)
|
|
73
|
+
*
|
|
74
|
+
* The platform half (SPGD-1712) serves two further asks on the same endpoints:
|
|
75
|
+
* `?near_duplicates_summary=` (the ranking, head keys first, no member lists)
|
|
76
|
+
* and `?near_duplicate_cluster=<rank>` (ONE cluster, members once). Like the
|
|
77
|
+
* default ask, the server reads only that the summary key is PRESENT, so
|
|
78
|
+
* `summary: false` sends NOTHING rather than `=false` — "off" is spelled by
|
|
79
|
+
* omission. When either bounded ask is made, ONLY the asks named are sent (not
|
|
80
|
+
* also `near_duplicates=true`: that would open the whole census beside the
|
|
81
|
+
* bounded view the caller chose it to avoid). `cluster` is not range-checked
|
|
82
|
+
* here: an out-of-range rank is the server's to answer (a `null` cluster with
|
|
83
|
+
* the ask echoed).
|
|
84
|
+
*
|
|
85
|
+
* Because a deployment that predates SPGD-1712 would silently ignore an
|
|
86
|
+
* unknown parameter and answer 200 with the plain overview, an ask whose
|
|
87
|
+
* matching key is ABSENT from the body (absent, not `null` — a present `null`
|
|
88
|
+
* is the server's own "asked, nothing there") is turned into an error naming
|
|
89
|
+
* the key. Otherwise "asked for the bounded view, got nothing" and "the
|
|
90
|
+
* deployment ignored the ask" would share one wire shape. Nothing else is
|
|
91
|
+
* inspected: the tool stays a pass-through.
|
|
92
|
+
*
|
|
93
|
+
* Every key is built conditionally rather than stringified for the same
|
|
72
94
|
* reason `repository-overview.ts` builds its `unannotated_examples` key:
|
|
73
95
|
* `getJson` omits only `undefined`, so a conditional send is the only honest
|
|
74
|
-
* way to spell "
|
|
96
|
+
* way to spell "only when asked". The schema stays CLOSED around its arguments:
|
|
75
97
|
* `server.ts` forwards `arguments` unvalidated, and an open schema would let an
|
|
76
98
|
* invented argument ride through and be silently dropped (see
|
|
77
99
|
* `registrable-repositories.ts` for the same call).
|
|
@@ -114,18 +136,44 @@ const nearDuplicateClusters = {
|
|
|
114
136
|
"been computed for the repository yet — a repository that has never ingested, read in the window " +
|
|
115
137
|
"before its first computation lands. It is never a live computation and never zeros: a repository " +
|
|
116
138
|
"whose every test reads differently serves a stored block with `clusters: []` and real counts. " +
|
|
117
|
-
"Calling this tool IS the ask;
|
|
118
|
-
"
|
|
119
|
-
"
|
|
139
|
+
"Calling this tool IS the ask; by default one call returns the whole census — the clusters are " +
|
|
140
|
+
"the repository's, computed over every run. Two optional arguments bound the view instead (below). " +
|
|
141
|
+
"WHICH repository is censused: pass `repository` " +
|
|
120
142
|
"(a numeric id from `list_repositories`) to census that named repository under either member " +
|
|
121
143
|
"credential — the agent key preferred, the person key when no agent key is set — or omit it to " +
|
|
122
144
|
"census the repository the configured sgk_… key resolves to, exactly as before the argument " +
|
|
123
145
|
"existed. " +
|
|
146
|
+
"THE BOUNDED VIEW — START WITH `summary`, DRILL IN WITH `cluster`: the default call serves every " +
|
|
147
|
+
"cluster with its full member list, which on a large suite is a large body. `summary: true` asks " +
|
|
148
|
+
"for `near_duplicates_summary` instead: the ranking with the head keys first and, per cluster, " +
|
|
149
|
+
"`rank`, `files_seen`, `file_count`, `declared_layers` and `overlap_kind` — and NO member lists. Then pass " +
|
|
150
|
+
"`cluster: <rank>` to ask for `near_duplicate_cluster`: ONE cluster, members once, carrying " +
|
|
151
|
+
"`requested` (the rank you asked for, echoed), `rank`, `cluster_count`, `weighed_run_id`, " +
|
|
152
|
+
"`computed_at`, `member_listing` (`members` or `layer_groups` — which of the two member shapes " +
|
|
153
|
+
"the `cluster` carries) and `cluster` itself. When either argument is supplied ONLY the asks " +
|
|
154
|
+
"named are sent — the whole-census `near_duplicates` block is not also opened; send both and you " +
|
|
155
|
+
"get both keys. RANKS ARE POSITIONS IN A SNAPSHOT: read `computed_at` before reusing a rank, " +
|
|
156
|
+
"because an ingest or a run deletion recomputes the census and the same rank can then name a " +
|
|
157
|
+
"different cluster. A rank beyond `cluster_count` is not an error: the key is present with " +
|
|
158
|
+
"`cluster: null` and `requested` echoing your ask. A deployment that predates the bounded view " +
|
|
159
|
+
"ignores the ask; this tool then fails naming the missing key rather than returning a body that " +
|
|
160
|
+
"silently lacks it. " +
|
|
124
161
|
"READ THE DISCLOSURE KEYS BEFORE THE COUNT: `similarity_floor` and `similarity_basis` sit FIRST " +
|
|
125
|
-
"in the block and
|
|
126
|
-
"
|
|
162
|
+
"in the block, and `ranking_basis` sits in the head beside `layer_source`; they qualify every " +
|
|
163
|
+
"cluster below them — a cluster count without what 'similar' meant is a figure you cannot act on. " +
|
|
164
|
+
"`truncated: true` means the cluster list was cut at the " +
|
|
127
165
|
"cap while the counts above it (`cluster_count`, `identity_count`, `clustered_*`) describe the " +
|
|
128
166
|
"WHOLE census, so never fold `clusters` length as the total. " +
|
|
167
|
+
"READ THE RANKING BY ITS STATED BASIS, NOT AS \"COSTLIEST FIRST\": `ranking_basis` (in the head of " +
|
|
168
|
+
"the block) states the order — clusters spanning more than one spec file first, then by summed wall " +
|
|
169
|
+
"clock, with single-file groups following — and each cluster's `overlap_kind` (`multi_file` or " +
|
|
170
|
+
"`single_file`) names which kind it is, in the full census and in every summary row. So the top row " +
|
|
171
|
+
"is the costliest MULTI-FILE cluster, not necessarily the costliest overall. `overlap_kind` " +
|
|
172
|
+
"describes where the members' last-known paths sit; it is not a verdict (the census says 'read as " +
|
|
173
|
+
"similar', never 'duplicate'), and it is independent of `layer_redundancy`: a two-file group whose " +
|
|
174
|
+
"members declared different layers is both `multi_file` and `cross_layer`. Both keys are present on " +
|
|
175
|
+
"current deployments and absent on older stored censuses — an absent `ranking_basis` means the " +
|
|
176
|
+
"census was stored under the older cost-only order (costliest first), not an error. " +
|
|
129
177
|
"READ EVERY CLUSTER'S FIGURES AT THEIR OWN GRAIN: `member_count` counts texts in the REPOSITORY " +
|
|
130
178
|
"across every run, `example_count` counts examples in the ONE run `weighed_run_id` names — a " +
|
|
131
179
|
"three-example table-driven loop is ONE member and THREE examples, and those two numbers beside " +
|
|
@@ -162,7 +210,8 @@ const nearDuplicateClusters = {
|
|
|
162
210
|
"accessible set bounds the answer instead); with both set the agent key wins. The server " +
|
|
163
211
|
"owns the refusals on that path: a repository outside the presented credential's grant " +
|
|
164
212
|
"answers 404, person and agent alike. " +
|
|
165
|
-
"The response is the endpoint's full body with the
|
|
213
|
+
"The response is the endpoint's full body with the asked-for block OPENED (`near_duplicates` by " +
|
|
214
|
+
"default), passed " +
|
|
166
215
|
"through unmodified — with the one surface difference `get_repository_overview` documents " +
|
|
167
216
|
"for its own `repository` ask: on that plural path the `api_key` block is ABSENT from the " +
|
|
168
217
|
"body rather than nulled (it describes the credential that made the request, and no member " +
|
|
@@ -188,11 +237,48 @@ const nearDuplicateClusters = {
|
|
|
188
237
|
"Omit it — or pass a blank — and the call is byte-for-byte the singular one under " +
|
|
189
238
|
"SPECGUARD_API_KEY, exactly as before this argument existed.",
|
|
190
239
|
},
|
|
240
|
+
summary: {
|
|
241
|
+
type: "boolean",
|
|
242
|
+
description: "Ask for the BOUNDED census view: the `near_duplicates_summary` block — the ranking " +
|
|
243
|
+
"(head keys first, `ranking_basis` among them; per cluster `rank`, `files_seen`, `file_count`, " +
|
|
244
|
+
"`declared_layers`, `overlap_kind`) with " +
|
|
245
|
+
"NO member lists — instead of the whole census. `true` sends the ask; `false` or omitted " +
|
|
246
|
+
"sends nothing (the server treats any value as an ask, so `false` is never put on the " +
|
|
247
|
+
"wire). When supplied it REPLACES the default `near_duplicates` ask. Start here, then " +
|
|
248
|
+
"drill in with `cluster`.",
|
|
249
|
+
},
|
|
250
|
+
cluster: {
|
|
251
|
+
type: "integer",
|
|
252
|
+
minimum: 1,
|
|
253
|
+
description: "Ask for ONE cluster by its `rank` in the ranking (1-based): the " +
|
|
254
|
+
"`near_duplicate_cluster` block, members listed once. Take the rank from a `summary` " +
|
|
255
|
+
"call and read `computed_at` first — ranks are positions in a snapshot and shift when " +
|
|
256
|
+
"the census is recomputed. Not range-checked here: a rank past `cluster_count` is " +
|
|
257
|
+
"answered by the server with `cluster: null` and the ask echoed. When supplied it " +
|
|
258
|
+
"REPLACES the default `near_duplicates` ask; send it with `summary: true` to get both " +
|
|
259
|
+
"blocks.",
|
|
260
|
+
},
|
|
191
261
|
},
|
|
192
262
|
additionalProperties: false,
|
|
193
263
|
},
|
|
194
264
|
async run(args, context) {
|
|
265
|
+
// Argument shapes are checked FIRST, before any config is resolved or
|
|
266
|
+
// request made — the class of fault the agent can fix from the message.
|
|
195
267
|
const repository = optionalString(args["repository"], "repository");
|
|
268
|
+
const summary = optionalBoolean(args["summary"], "summary");
|
|
269
|
+
const cluster = optionalPositiveInteger(args["cluster"], "cluster");
|
|
270
|
+
// Only the asks NAMED are sent. With neither bounded ask this is exactly
|
|
271
|
+
// the request this tool has always made. `summary: false` is NO ask — the
|
|
272
|
+
// server reads only that the key is present, so `=false` would open it.
|
|
273
|
+
const asks = {};
|
|
274
|
+
if (summary === true)
|
|
275
|
+
asks["near_duplicates_summary"] = "true";
|
|
276
|
+
if (cluster !== undefined)
|
|
277
|
+
asks["near_duplicate_cluster"] = String(cluster);
|
|
278
|
+
const bounded = Object.keys(asks).length > 0;
|
|
279
|
+
// Always `"true"` on the default path — the server reads only that the key
|
|
280
|
+
// is present. See this file's header.
|
|
281
|
+
const query = bounded ? asks : { near_duplicates: "true" };
|
|
196
282
|
// WHICH ENDPOINT AND WHICH CREDENTIAL is one branch point over the one
|
|
197
283
|
// ask, and it is spelled once in `repositoryTarget`
|
|
198
284
|
// (`../support/specguard-api.js`): the pair (path, credential) must not
|
|
@@ -201,12 +287,16 @@ const nearDuplicateClusters = {
|
|
|
201
287
|
// decides what it asks — no repository named means the singular census,
|
|
202
288
|
// a name means the plural one under either member credential (SPGD-1106).
|
|
203
289
|
const { api, path } = repositoryTarget(context.config, repository);
|
|
204
|
-
const overview = await getJsonObject(api, path,
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
290
|
+
const overview = await getJsonObject(api, path, query, context.fetch);
|
|
291
|
+
// Old-server guard: an unknown parameter is silently ignored, so an ask
|
|
292
|
+
// whose key is ABSENT (not `null`) means the deployment predates it.
|
|
293
|
+
for (const key of Object.keys(asks)) {
|
|
294
|
+
if (!(key in overview)) {
|
|
295
|
+
throw new ApiError(`The response has no \`${key}\` key although it was asked for: this SpecGuard deployment ` +
|
|
296
|
+
"predates the bounded near-duplicate view and ignored the ask. Call this tool without " +
|
|
297
|
+
"`summary` and `cluster` for the whole census, or upgrade the deployment.");
|
|
298
|
+
}
|
|
299
|
+
}
|
|
210
300
|
return {
|
|
211
301
|
text: JSON.stringify(overview, null, 2),
|
|
212
302
|
structured: overview,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"near-duplicate-clusters.js","sourceRoot":"","sources":["../../../src/tools/near-duplicate-clusters.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,6BAA6B,CAAC;AAC9E,OAAO,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"near-duplicate-clusters.js","sourceRoot":"","sources":["../../../src/tools/near-duplicate-clusters.ts"],"names":[],"mappings":"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"}
|
|
@@ -480,16 +480,17 @@ const getRepositoryOverview = {
|
|
|
480
480
|
"which areas of the suite grew or shrank and which got slower or faster since the previous run " +
|
|
481
481
|
"on the same branch (the per-area comparisons, at BOTH the example-count grain and the " +
|
|
482
482
|
"runtime grain — an area where an existing spec was made slow gains no examples and appears " +
|
|
483
|
-
"only in the runtime one — and how the run-wide declared-layer mix moved, `layer_run_growth`), " +
|
|
483
|
+
"only in the runtime one — and how the run-wide declared-layer mix moved, `layer_run_growth` at the count grain and `layer_runtime_growth` at the time grain), " +
|
|
484
484
|
"the recent run history for growth over time, and the branches that have runs. " +
|
|
485
485
|
"Everything above is answered about ONE repository, and WHICH one has two spellings: by " +
|
|
486
486
|
"default it is the repository the configured sgk_… repository key resolves to, and passing " +
|
|
487
487
|
"`repository` (a numeric id from `list_repositories`) instead asks about that named " +
|
|
488
488
|
"repository under the agent key — one ask that changes the subject and nothing else, so " +
|
|
489
489
|
"every parameter below means the same thing either way. " +
|
|
490
|
-
"Pass `branch` for
|
|
491
|
-
"cross-run flakiness ranking)
|
|
492
|
-
"
|
|
490
|
+
"Pass `branch` for three more: which tests fail intermittently rather than consistently (the " +
|
|
491
|
+
"cross-run flakiness ranking), which DURABLE tests cost the most wall clock across the " +
|
|
492
|
+
"window (`slowest_tests`, below), and how the areas moved across the whole branch window " +
|
|
493
|
+
"rather than between the last two runs. " +
|
|
493
494
|
"Four of those rankings open: pass `spec_directory` to see the spec files inside one of the " +
|
|
494
495
|
"heaviest directories — and, in the same answer, which of those files grew and which got " +
|
|
495
496
|
"slower — `spec_file` to see the individual examples inside one of the heaviest files, " +
|
|
@@ -502,6 +503,39 @@ const getRepositoryOverview = {
|
|
|
502
503
|
"`unreadable`, and NOT a measured `unit`. A partially annotated test lists only what was " +
|
|
503
504
|
"declared, and more than one entry means the test changed layer mid-window. It is " +
|
|
504
505
|
"DECLARED-ONLY — the stored column, never inferred from the spec path or `files_seen`. " +
|
|
506
|
+
"`slowest_tests_window` + `slowest_tests` are the CROSS-RUN runtime ranking, a top-level " +
|
|
507
|
+
"pair beside `unstable_tests`: one row per DURABLE test (a moved or renamed test keeps its " +
|
|
508
|
+
"history), ranked by its window `total_seconds` descending, nulls last. It is a DIFFERENT " +
|
|
509
|
+
"GRAIN from `latest_run.slowest_examples`, which is ONE run at coordinate grain " +
|
|
510
|
+
"(file and line) and cannot be summed across responses without splitting a moved test in " +
|
|
511
|
+
"two. BOTH are `null` without `branch` (`slowest_tests_window.grouped` says so: it is true " +
|
|
512
|
+
"exactly when `slowest_tests` is non-null) — runtimes across branches are runtimes of " +
|
|
513
|
+
"different code, so an unfiltered window is refused rather than answered. " +
|
|
514
|
+
"`slowest_tests.state` is FOUR-WAY and only the last may be read as a result: `no_runs` " +
|
|
515
|
+
"(the window is empty), `unrecorded` (the anchor run wrote no per-example rows), " +
|
|
516
|
+
"`unresolved` (it wrote rows and none has been matched to a durable test yet — the " +
|
|
517
|
+
"ORDINARY state for the seconds after an ingest, because identity resolution is " +
|
|
518
|
+
"asynchronous) and `ranked`. Only `ranked` with `rows: []` means nothing in the suite is " +
|
|
519
|
+
"slow; an empty list in any other state is work not done. `anchor_run` " +
|
|
520
|
+
"(`test_run_id`, `commit_sha`, `branch`, `ingested_at`; `null` only in `no_runs`) names the " +
|
|
521
|
+
"run that decided MEMBERSHIP: the candidates are the NEWEST run's slowest tests and the " +
|
|
522
|
+
"window only supplies their history, so a test that ran earlier in the window but is absent " +
|
|
523
|
+
"from the newest run is NOT listed. `truncated` / `unexamined_count` / `limit` disclose the " +
|
|
524
|
+
"candidate cap, with `candidate_count` and the `rows` length as the operands — size the " +
|
|
525
|
+
"population from those, never from `rows.length`. `recorded_count`, `unresolved_count`, " +
|
|
526
|
+
"`candidate_count`, `resolved_count` and `timed_count` are `null` — NOT `0` — in every " +
|
|
527
|
+
"state that returned before the read that would have produced them; a `0` is a MEASURED " +
|
|
528
|
+
"zero (a window that excluded nothing). Alongside them: `recorded`, `resolved`, " +
|
|
529
|
+
"`excluded_unresolved_rows`, `untimed_count`, `complete` and `run_count`. Each " +
|
|
530
|
+
"`slowest_tests.rows[]` row carries `spec_identity_id` (the join key between responses), " +
|
|
531
|
+
"`total_seconds` and `slowest_seconds` (`null` when nothing was timed — never a zero), " +
|
|
532
|
+
"`moved` / `renamed` with their operands `files_seen` / `descriptions`, and " +
|
|
533
|
+
"`declared_layers` — the sorted DISTINCT set of `@intent layer:` values that test declared " +
|
|
534
|
+
"in the window; `[]` means none declared, and it is DECLARED-ONLY, never inferred from the " +
|
|
535
|
+
"spec path. " +
|
|
536
|
+
"Add `layer` (with `branch`) to ask for the slowest tests of ONE declared layer across the " +
|
|
537
|
+
"window — `layer` narrows `slowest_tests` as well as `slowest_examples`; the window echo " +
|
|
538
|
+
"is `slowest_tests_window.layer` (see `layer`). " +
|
|
505
539
|
"All of those describe the repository's NEWEST run, which on a busy repository may be another " +
|
|
506
540
|
"branch's: pass `commit_sha` to be answered about ONE named run instead — after pushing a " +
|
|
507
541
|
"commit and waiting for CI, say — then read `run_anchor` to confirm which run you were served, " +
|
|
@@ -549,8 +583,36 @@ const getRepositoryOverview = {
|
|
|
549
583
|
"zero, not an absence — and the five `change` values sum to `anchor_recorded_count` minus " +
|
|
550
584
|
"`baseline_recorded_count`. The layers are DECLARED only, never inferred from the path, and " +
|
|
551
585
|
"`undeclared` is NOT `unreadable`; the operands carry no pyramid verdict, so reading the shift is " +
|
|
552
|
-
"yours.
|
|
553
|
-
"
|
|
586
|
+
"yours. " +
|
|
587
|
+
"HOW THE TIME EACH DECLARED LAYER ACCOUNTS FOR MOVED SINCE THE PREVIOUS RUN is `layer_runtime_growth`, " +
|
|
588
|
+
"with its contract block `layer_runtime_growth_window` — both TOP-LEVEL siblings of " +
|
|
589
|
+
"`directory_run_growth`, NOT inside `latest_run`, exactly as the count pair is. It answers \"did my " +
|
|
590
|
+
"push make the request layer N seconds slower?\", which `layer_run_growth` (example counts) and " +
|
|
591
|
+
"`directory_runtime_growth` (per path, not per declared layer) cannot. They compare the latest run " +
|
|
592
|
+
"with the previous run ON THE LATEST RUN'S OWN BRANCH, so no `branch` is needed, and `commit_sha` " +
|
|
593
|
+
"re-anchors them with the rest of the run-grain blocks. `layer_runtime_growth` is `null` in EVERY " +
|
|
594
|
+
"non-comparable state — NEVER a block of zeros, so `null` is not \"no change\" — and " +
|
|
595
|
+
"`layer_runtime_growth_window.state` names why: the `layer_run_growth` states `latest_unmeasured`, " +
|
|
596
|
+
"`previous_unmeasured`, `assembled_differently`, `neither_recorded`, `previous_unrecorded` and " +
|
|
597
|
+
"`latest_unrecorded`, plus three about timing — `neither_timed`, `previous_untimed` and " +
|
|
598
|
+
"`latest_untimed` (a run recorded example rows but timed none of them, so there is nothing to " +
|
|
599
|
+
"subtract) — and `comparable`, `no_latest_run` (CI never reported) and `no_previous_run` (the first " +
|
|
600
|
+
"run on the branch). `layer_runtime_growth_window.comparable` is true exactly when " +
|
|
601
|
+
"`layer_runtime_growth` is non-null; the window also carries `basis`, `branch`, `anchor_commit_sha` " +
|
|
602
|
+
"and `baseline_commit_sha`. When comparable, `layer_runtime_growth` is `{layers}`, where `layers` " +
|
|
603
|
+
"holds `unit`, `integration`, `request`, `system` and `undeclared`, each `{baseline_seconds, " +
|
|
604
|
+
"anchor_seconds, baseline_timed_count, anchor_timed_count, baseline_count, anchor_count, change}`. " +
|
|
605
|
+
"`change` is anchor minus baseline in seconds and is `null` — NOT 0 — when either side's layer was " +
|
|
606
|
+
"untimed (a layer with no timed example is not a zero-second layer, and reading it as one would " +
|
|
607
|
+
"turn a telemetry gap into a speedup); a layer that was timed on both sides and did not move reads " +
|
|
608
|
+
"`change: 0`, a measured zero. The `*_timed_count` fields are the denominators the seconds were " +
|
|
609
|
+
"summed over. It is a SUM of machine time, NOT wall clock, so it can exceed `duration_seconds` on a " +
|
|
610
|
+
"parallel or sharded run. The layers are DECLARED only, never inferred from the path, and a test " +
|
|
611
|
+
"changing its declared `@intent` layer reads as one layer gaining time and another losing it; no " +
|
|
612
|
+
"verdict is given on a slow layer, so reading the shift is yours. The same " +
|
|
613
|
+
"`layer_counts` rides each row of `spec_directories`, each row of `spec_files` and each row of " +
|
|
614
|
+
"`repeated_descriptions` (the same five operands, DECLARED only and never inferred from the path, " +
|
|
615
|
+
"measured zeros, summing to that row's `recorded_count`), the `spec_directory_files` area block " +
|
|
554
616
|
"and each of its file rows, and every per-example row of `slowest_examples`, " +
|
|
555
617
|
"`spec_file_examples` and `repeated_description_examples` carries `intent_layer` and " +
|
|
556
618
|
"`declared_intent` (`{entity, action, behavior}` or `null`, declared only). " +
|
|
@@ -690,12 +752,15 @@ const getRepositoryOverview = {
|
|
|
690
752
|
"and must not be differenced). Narrows `history` ONLY: `latest_run` always names the " +
|
|
691
753
|
"repository's newest run, which on a busy repo may be on another branch. Use a name " +
|
|
692
754
|
"from `branches`; an unknown one returns an empty history rather than an error. " +
|
|
693
|
-
"It also UNLOCKS
|
|
755
|
+
"It also UNLOCKS three blocks that read the same window and are `null` without it: " +
|
|
694
756
|
"`unstable_tests` (which tests failed intermittently across the window rather than " +
|
|
695
|
-
"consistently)
|
|
696
|
-
"
|
|
697
|
-
"
|
|
698
|
-
"
|
|
757
|
+
"consistently), `slowest_tests` together with its `slowest_tests_window` (which durable " +
|
|
758
|
+
"tests cost the most wall clock across the window) and `directory_growth` (how each area " +
|
|
759
|
+
"moved between the two ENDPOINTS of that window). Add `layer` to narrow `slowest_tests` to " +
|
|
760
|
+
"one declared layer. The per-area comparisons against the PREVIOUS RUN — `directory_run_growth` " +
|
|
761
|
+
"and `directory_runtime_growth`, the declared-layer mix pair `layer_run_growth` / " +
|
|
762
|
+
"`layer_run_growth_window`, and the declared-layer time pair `layer_runtime_growth` / " +
|
|
763
|
+
"`layer_runtime_growth_window` — need no branch and take none; they scope to the latest " +
|
|
699
764
|
"run's own branch by construction, so a plain call already carries them.",
|
|
700
765
|
},
|
|
701
766
|
spec_directory: {
|
|
@@ -812,6 +877,9 @@ const getRepositoryOverview = {
|
|
|
812
877
|
"five RUN-GRAIN drill-ins (`spec_directory_files`, `spec_file_examples`, " +
|
|
813
878
|
"`repeated_description_examples`, `unannotated_examples` and `slowest_examples` — the " +
|
|
814
879
|
"block `layer` narrows), `shards`, both per-area growth windows and `previous_test_run`. " +
|
|
880
|
+
"The window-grain narrowing `layer` also applies to `slowest_tests` (with `branch`) does " +
|
|
881
|
+
"NOT move with it: that ranking is read over the branch window, anchored on its own " +
|
|
882
|
+
"newest run. " +
|
|
815
883
|
"`unstable_test_runs` is the one drill-in that does NOT move with " +
|
|
816
884
|
"it: it is read over the branch window rather than off the anchored run, so sending " +
|
|
817
885
|
"this with `unstable_test` still gives you that test across the whole window. " +
|
|
@@ -940,23 +1008,37 @@ const getRepositoryOverview = {
|
|
|
940
1008
|
},
|
|
941
1009
|
layer: {
|
|
942
1010
|
type: "string",
|
|
943
|
-
description: "Narrow
|
|
944
|
-
"run-wide slowest-examples ranking
|
|
945
|
-
"
|
|
946
|
-
"`
|
|
947
|
-
"
|
|
948
|
-
"
|
|
949
|
-
"
|
|
950
|
-
"
|
|
951
|
-
"
|
|
952
|
-
"
|
|
953
|
-
"`recorded_count
|
|
954
|
-
"
|
|
955
|
-
"`
|
|
956
|
-
"
|
|
957
|
-
"
|
|
958
|
-
"
|
|
959
|
-
"
|
|
1011
|
+
description: "Narrow to one DECLARED test layer. It narrows TWO blocks, at two different grains. " +
|
|
1012
|
+
"(1) `latest_run.slowest_examples` — the run-wide slowest-examples ranking, at RUN " +
|
|
1013
|
+
"GRAIN, so it moves with `commit_sha`; echoed as `slowest_examples.layer`. " +
|
|
1014
|
+
"(2) The cross-run `slowest_tests` ranking — but ONLY when `branch` is also asked, " +
|
|
1015
|
+
"because without `branch` that block is `null`. That one is at WINDOW GRAIN and does " +
|
|
1016
|
+
"NOT move with `commit_sha`; echoed as `slowest_tests_window.layer`. On `slowest_tests` " +
|
|
1017
|
+
"the CANDIDATE step is narrowed (a test is a candidate only if it has at least one " +
|
|
1018
|
+
"anchor-run example in the layer), while each row's totals stay the whole durable " +
|
|
1019
|
+
"test's — so a row's `declared_layers` may list several layers, not just the one you " +
|
|
1020
|
+
"asked for. `resolved_count`, `candidate_count`, `timed_count` and `untimed_count` " +
|
|
1021
|
+
"become the layer's anchor-run figures, while `recorded_count` and `unresolved_count` " +
|
|
1022
|
+
"stay WHOLE-RUN. A layer the anchor run never declared answers `state: \"ranked\"` " +
|
|
1023
|
+
"with `rows: []`: that is NOT \"nothing is slow\", it is \"nothing in that layer\". " +
|
|
1024
|
+
"It does NOT narrow `spec_file_examples`, `spec_directory_files`, " +
|
|
1025
|
+
"`unannotated_examples` or `repeated_description_examples`. " +
|
|
1026
|
+
"Use it after `latest_run.layer_durations` shows one layer holding most of the machine " +
|
|
1027
|
+
"time (say `request`) and you need to know WHICH tests — in this run, or (with " +
|
|
1028
|
+
"`branch`) across the window. Values: `unit`, `integration`, `request`, `system` or " +
|
|
1029
|
+
"`undeclared` (a test that declared no layer). Any other value is read by the server " +
|
|
1030
|
+
"as NO ASK — never a 400 or 404 — so it is forwarded unvalidated and a typo silently " +
|
|
1031
|
+
"returns the un-narrowed ranking: check that BOTH echoes come back — " +
|
|
1032
|
+
"`slowest_examples.layer` and, when `branch` was asked, `slowest_tests_window.layer`. " +
|
|
1033
|
+
"Each echo is present ONLY when a layer was asked and well-formed (the key is ABSENT " +
|
|
1034
|
+
"otherwise, and `slowest_tests_window.layer` is also ABSENT whenever `branch` was not " +
|
|
1035
|
+
"asked). With a layer asked, on `slowest_examples` `recorded_count`, `timed_count` and " +
|
|
1036
|
+
"`reported_outcome_count` are that LAYER's own counts (`recorded_count` equals " +
|
|
1037
|
+
"`layer_counts[layer]`, `timed_count` equals `layer_durations[layer].timed_count`), " +
|
|
1038
|
+
"not the run's. A layer with no examples answers `rows: []` and `recorded_count: 0`, " +
|
|
1039
|
+
"while `slowest_examples: null` still means the run recorded nothing at all. Layers " +
|
|
1040
|
+
"are DECLARED only (an `@intent` annotation said so), never inferred from the file " +
|
|
1041
|
+
"path. A blank value sends nothing.",
|
|
960
1042
|
},
|
|
961
1043
|
},
|
|
962
1044
|
additionalProperties: false,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"repository-overview.js","sourceRoot":"","sources":["../../../src/tools/repository-overview.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"repository-overview.js","sourceRoot":"","sources":["../../../src/tools/repository-overview.ts"],"names":[],"mappings":"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"}
|