specguard-mcp 0.1.39 → 0.1.41

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 CHANGED
@@ -40,7 +40,7 @@ refuses to boot and takes the tools that needed no configuration down with it.
40
40
  | `SPECGUARD_TIMEOUT_MS` | HTTP tools | `30000` | how long a call to SpecGuard may take |
41
41
 
42
42
  `SPECGUARD_ENDPOINT` and `SPECGUARD_API_KEY` are the same variables
43
- [`specguard-rspec`](https://github.com/yatfa-ai/specguard-rspec) uses to ship a run, so a repository
43
+ [`specguard-ruby`](https://github.com/yatfa-ai/specguard-ruby) uses to ship a run, so a repository
44
44
  that already posts telemetry to SpecGuard already has them. `SPECGUARD_USER_API_KEY` is **not** one
45
45
  of them — the gem has no notion of a user key — so that one is minted and set here for the first
46
46
  time.
@@ -199,14 +199,15 @@ before any request is made.
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 ONLY `latest_run.slowest_examples` to one declared layer (`unit`, `integration`, `request`, `system` or `undeclared`) — see below |
202
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 |
203
204
 
204
205
  `branch` narrows `history` only — `latest_run` always names the repository's newest run, which on a
205
206
  busy repo may be on another branch. That is a property of the endpoint, not of this bridge — and
206
207
  `commit_sha` is the remedy: it names WHICH RUN to describe, where `branch` asks about a series. Every
207
- run-grain block re-anchors together (`latest_run` and its rollups, the four run-grain drill-ins —
208
- `spec_directory_files`, `spec_file_examples`, `repeated_description_examples`, `unannotated_examples`
209
- — `shards`, both growth windows, `previous_test_run`); `history` does not, so the
208
+ run-grain block re-anchors together (`latest_run` and its rollups, the five run-grain drill-ins —
209
+ `spec_directory_files`, `spec_file_examples`, `repeated_description_examples`, `unannotated_examples`,
210
+ `slowest_examples` — `shards`, both growth windows, `previous_test_run`); `history` does not, so the
210
211
  `history[0] == latest_run` identity holds
211
212
  on a default call and is **not** expected to hold under an explicit ask. Nor does `unstable_test_runs`,
212
213
  which is read over the branch window rather than off the anchored run. (`unannotated_directories`,
@@ -224,8 +225,8 @@ successful response is about the commit you named.
224
225
  it: `unstable_tests` (which tests failed intermittently across the window rather than consistently)
225
226
  and `directory_growth` (how each area moved between the two **endpoints** of the window). The
226
227
  per-area comparisons against the **previous run** — `directory_run_growth` at the example-count
227
- grain and `directory_runtime_growth` at the runtime grain — are a different question and take no
228
- branch at all: they scope to the latest run's own branch by construction, so a plain unparameterised
228
+ 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
229
230
  call already carries them. The two grains are independent, which is why both ship: making an
230
231
  existing spec slow adds zero examples and shows up only in the runtime pair, and splitting one slow
231
232
  spec into four fast ones is `+3` examples and *less* time.
@@ -233,8 +234,8 @@ spec into four fast ones is `+3` examples and *less* time.
233
234
  `spec_directories` ranks the heaviest areas but stops at the area grain, so it says *where* the time
234
235
  went and not *which files* spent it. `spec_directory` is the next question: pass a path exactly as
235
236
  served in `latest_run.spec_directories.rows[].path` and `latest_run.spec_directory_files` opens with
236
- the files in that one directory (`total_seconds`, `recorded_count`, `timed_count` each), plus the
237
- **area's** own `file_count`/`recorded_count`/`timed_count` and the `limit` the row list was cut at —
237
+ the files in that one directory (`total_seconds`, `recorded_count`, `timed_count`, `layer_counts`
238
+ each), plus the **area's** own `layer_counts`, `file_count`/`recorded_count`/`timed_count` and the `limit` the row list was cut at —
238
239
  those totals describe the whole area, not the returned page, so don't re-derive them from `rows`.
239
240
  Omit the argument and the key is `null`, meaning *you did not ask*; an area the run recorded nothing
240
241
  for answers `rows: []` rather than an error, so a renamed or deleted directory is an empty result and
@@ -250,7 +251,8 @@ two are the answer to the question the area-grain comparisons dead-end on — `s
250
251
  most and not *which examples* inside them spent it. `spec_file` is the next question: pass a path
251
252
  exactly as served in `latest_run.spec_files.rows[].path` and `latest_run.spec_file_examples` opens
252
253
  with up to 50 of that file's individual examples, cut by **duration** (`name`, `file_path`,
253
- `line_number`, `spec_file_path`, `duration_seconds`, `outcome` each), plus the **file's** own
254
+ `line_number`, `spec_file_path`, `duration_seconds`, `outcome`, `intent_layer`, `declared_intent`
255
+ each — eight fields), plus the **file's** own
254
256
  `recorded_count`/`timed_count` and the `limit` the row list was cut at — those totals describe the
255
257
  whole file, not the returned page, so don't re-derive them from `rows`. Omit the argument and the
256
258
  key is `null`, meaning *you did not ask*; a path that matched nothing answers `rows: []` rather than
@@ -260,7 +262,7 @@ an error, so a renamed or deleted spec file and a stale bookmark are empty resul
260
262
  ranking — but names the description and the files it was seen in, not *which* examples say the same
261
263
  thing. `repeated_description` is the next question: pass a description exactly as served in
262
264
  `latest_run.repeated_descriptions.rows[].name` and `latest_run.repeated_description_examples` opens
263
- with up to 25 of that group's members (the same six fields), plus the **group's** own
265
+ with up to 25 of that group's members (the same eight fields), plus the **group's** own
264
266
  `recorded_count`/`timed_count` and the `limit` the row list was cut at — again totals for the whole
265
267
  group and not for the returned page. This is the **only** way to reach a group's members:
266
268
  `slowest_examples` is the run-wide top ten and rarely contains them, and walking `spec_file` over
@@ -281,6 +283,14 @@ description's rows run by run in window order, **newest run first**, up to 200 (
281
283
  `recorded_count`/`reported_outcome_count`/`unreported_outcome_count`, the window's `run_count` and
282
284
  the `limit` the row list was cut at.
283
285
 
286
+ Every row of `unstable_tests.rows[]` and of `unstable_tests.shared_description_rows[]` also carries
287
+ `declared_layers` — the sorted distinct set of `@intent layer:` values that test's examples declared
288
+ anywhere in the window. `[]` means no run in the window declared one: it is not `unreadable` and not
289
+ a measured `unit`. A partially annotated test lists only what was declared, and more than one entry
290
+ means the test changed layer mid-window. It is declared-only — the stored column, never inferred from
291
+ the spec path or `files_seen`. The `unstable_test_runs` drill-in rows do **not** carry a layer, so
292
+ read `declared_layers` off the ranking row.
293
+
284
294
  Note the two ways it differs from the drill-ins above. The answer lands **inside** the flakiness
285
295
  block — `unstable_tests.unstable_test_runs`, not under `latest_run.*` — and `branch` is a hard
286
296
  prerequisite rather than a suggestion: `unstable_tests` is `null` without it, so `unstable_test` sent
@@ -316,7 +326,51 @@ never render that subtraction as blindness. A derived reading is genuinely weake
316
326
  one — no preconditions, a behavior written for a test runner's output rather than declared, and a
317
327
  layer inferred from the directory — so report it as inferred and never as equivalent. And
318
328
  `authored` never replaces `annotated_ratio`: "how much of this suite has a human-written intent" is
319
- still that figure, off the run's own counters. It is the one argument
329
+ still that figure, off the run's own counters.
330
+
331
+ **Which layer the suite declares is a third, separate question**, answered on every response by
332
+ `latest_run.layer_counts`, a sibling of `intent_readings`: five operands — `unit`, `integration`,
333
+ `request`, `system` and `undeclared` — that sum to `intent_readings.recorded`. It is `null`, **not
334
+ five zeros**, when the run stored no per-example rows, because a zero would read as a measured none.
335
+ The layers are **declared only** — an `@intent` annotation said so — and **never inferred from the
336
+ directory path**: a test under `spec/models` that declared nothing is `undeclared`, and `undeclared`
337
+ is **not** `unreadable` (a test can be perfectly readable and declare no layer). The operands carry no
338
+ pyramid verdict; reading the mix is yours. **Where the machine time went by layer** is
339
+ `latest_run.layer_durations`, a sibling of `layer_counts` with the same five keys, each
340
+ `{total_seconds, timed_count}`. `total_seconds` is `null`, **not 0**, for a layer with no timed example,
341
+ so an untimed layer is not a free one; `timed_count` (at most that layer's `layer_counts` entry) is the
342
+ real denominator for any average. The whole key is `null` when the run stored no per-example rows. It is
343
+ a **sum** of example durations — machine time and **not wall clock** — so it can exceed
344
+ `duration_seconds` on a parallel or sharded run. The layer is **declared only**, never inferred from the
345
+ 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
+ — and only that block — to one declared layer; it is echoed as `slowest_examples.layer` only when
348
+ asked, `recorded_count`/`timed_count`/`reported_outcome_count` become that layer's own counts, any
349
+ other value is read by the server as no ask (so it is forwarded unvalidated), and `rows: []` with
350
+ `recorded_count: 0` means that layer has no examples while `slowest_examples: null` means the run
351
+ recorded nothing. **How the declared-layer mix moved since the previous
352
+ run** is `layer_run_growth`, with its contract block `layer_run_growth_window` — both **top-level
353
+ siblings of `directory_run_growth`**, not inside `latest_run` (the delta is not in
354
+ `latest_run.layer_counts`). They compare the latest run with the previous run **on the latest run's own
355
+ branch**, so no `branch` is needed, and `commit_sha` re-anchors them with the rest of the run-grain
356
+ blocks. `layer_run_growth` is `null` in **every** non-comparable state — **never a block of zeros**, so
357
+ `null` is not "no change" — and `layer_run_growth_window.state` names why: `latest_unmeasured`,
358
+ `previous_unmeasured`, `assembled_differently`, `neither_recorded`, `previous_unrecorded`,
359
+ `latest_unrecorded`, or `comparable`, plus `no_latest_run` (CI never reported) and `no_previous_run`
360
+ (the first run on the branch). `layer_run_growth_window.comparable` is true exactly when
361
+ `layer_run_growth` is non-null; the window also carries `basis`, `branch`, `anchor_commit_sha` and
362
+ `baseline_commit_sha`. When comparable, `layer_run_growth` is
363
+ `{layers, baseline_recorded_count, anchor_recorded_count}`, where `layers` holds `unit`, `integration`,
364
+ `request`, `system` and `undeclared`, each `{baseline_count, anchor_count, change}`. A layer that did not
365
+ move reads `change: 0` — a **measured zero**, not an absence — and the five `change` values sum to
366
+ `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. The same
368
+ `layer_counts` rides each row of
369
+ `spec_directories`, the `spec_directory_files` area block and each of its file rows, and every
370
+ per-example row of `slowest_examples`, `spec_file_examples` and `repeated_description_examples`
371
+ carries `intent_layer` and `declared_intent` (`{entity, action, behavior}` or `null`, declared only).
372
+
373
+ The `unannotated_examples` flag is the one argument
320
374
  here that is a **flag rather than a name** — pass `true`, not a value — because it opens a
321
375
  *population* rather than a pick: `total_specs` minus `annotated_specs` is a subtraction, and a
322
376
  subtraction has no line to name. Which population is still yours to choose: sent alone the flag
@@ -324,8 +378,8 @@ opens the whole run, and sent **together with** `spec_file` or `spec_directory`
324
378
  file, that area, or the AND of the two — those two keep opening their own blocks as well, so
325
379
  narrowing this one is additional rather than instead. `latest_run.unannotated_examples` opens with
326
380
  up to 100 of the unannotated examples **of whatever you asked for** (`name`, `file_path`,
327
- `line_number`, `spec_file_path`, `reading` and `derived_intent` each — six fields, and not the
328
- per-example drill-ins' six: no `duration_seconds` and no `outcome`), plus that
381
+ `line_number`, `spec_file_path`, `reading` and `derived_intent` each — six fields, unlike the
382
+ per-example drill-ins' eight: no `duration_seconds`, no `outcome`, no `intent_layer`), plus that
329
383
  same population's own `recorded_count`, `derived_count` and `unreadable_count`, the `limit` the row
330
384
  list was cut at, and
331
385
  `spec_file`/`spec_directory` **echoed back** as the server read them — `null` for each one you did
@@ -500,7 +554,7 @@ blank value is no ask: passing an empty string and omitting the argument make th
500
554
  | --- | --- |
501
555
  | `q` | keep only repositories whose `full_name` (`org/repo`) contains this substring, case-insensitively. A plain substring, not a pattern — the LIKE wildcards `%`/`_` are escaped server-side, so `org/my_repo` matches itself. A match-less ask is an empty list, not an error |
502
556
  | `role` | `"owned"` or `"shared"` — one half of the list's mix: the repositories this person owns, or the ones shared with them. Mind the spelling: the *ask* values are `owned`/`shared`, while each entry's `role` field reads `owner`/`member` — `role: "owner"` is not a valid ask and settles to no ask (full list, no error). Under the `sga_…` agent key the ask settles to no ask for every value: ownership is a person fact and the key speaks for nobody, so the full granted list is served |
503
- | `sort` | `"stale"` — re-order stalest-first: repositories CI has never ingested a run for first, then least-recently-ingested, with `full_name` breaking ties so two calls agree element for element. The same entries, a different order; the default order stays `full_name` ascending |
557
+ | `sort` | `"stale"` — re-order stalest-first: repositories CI has never ingested a run for first, then least-recently-ingested, with `full_name` breaking ties so two calls agree element for element. `"annotated"` — re-order least-annotated share first: a suite measured at 0-of-N leads, repositories with no run or an unmeasured suite come last (never ranked as 0%), and `full_name` breaks ties. The same entries, a different order; the default order stays `full_name` ascending |
504
558
 
505
559
  The body comes back as SpecGuard serves it — `{"repositories": […]}`, each entry carrying `id`,
506
560
  `full_name`, `name`, `registered_at`, `role`, `delivery_health` and `latest_run`, ordered by
@@ -726,6 +780,13 @@ its last-known path and the weight the latest run measured.
726
780
  | --- | --- |
727
781
  | `behavior` | **required** — the behavior phrase, in plain words (e.g. "rejects an expired password reset token"). Trimmed and sent as `near`. Blank or whitespace-only is refused before any request, and so is a phrase containing a NUL (`\u0000`) character: the server would read either as no ask and answer the whole overview with `near: null`, which would look like an answered ask |
728
782
  | `repository` | ask 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 ask |
783
+ | `limit` | optional integer page size, **1–50** — omit it for the default page of 10. Sent as `&limit=<n>` only when supplied, so an ask without it is the same request as before. The server clamps the ask to 50 and reports the value it applied as `limit` in the `near` block; a non-integer, zero or negative value is refused before any request |
784
+
785
+ **The answer is a page, not the set.** Read `truncated` and `limit` in the returned `near` block:
786
+ `limit` is the page size the server applied, and `truncated: true` means **more matches exist than
787
+ were returned** — a full page of 10 may be "10 of 37". When `truncated` is true, re-ask the **same
788
+ phrase** with a larger `limit` (max 50) before paraphrasing it: a repeated phrase is cache-served and
789
+ free, while each paraphrase is a novel phrase and one billed embed.
729
790
 
730
791
  **What the answer is not.** It ranks *stored* tests nearest the phrase and **never answers "is this
731
792
  already tested?"** — it never gates a write and never issues a verdict. A hit near the phrase is not
@@ -1194,7 +1255,7 @@ npm run typecheck # types only
1194
1255
  ## Related repositories
1195
1256
 
1196
1257
  - [`specguard`](https://github.com/yatfa-ai/specguard) — the platform: ingest API + Hotwire dashboard
1197
- - [`specguard-rspec`](https://github.com/yatfa-ai/specguard-rspec) — Ruby client (RSpec formatter + `@intent` linter)
1258
+ - [`specguard-ruby`](https://github.com/yatfa-ai/specguard-ruby) — Ruby client (RSpec formatter, Minitest reporter + `@intent` linter)
1198
1259
  - [`open-test-intent`](https://github.com/yatfa-ai/open-test-intent) — the annotation protocol SpecGuard consumes
1199
1260
 
1200
1261
  ## License
@@ -19,7 +19,7 @@
19
19
  *
20
20
  * == SPECGUARD_ENDPOINT, with SPECGUARD_URL as an accepted alias
21
21
  *
22
- * `SPECGUARD_ENDPOINT` is the name the shipped `specguard-rspec` gem already
22
+ * `SPECGUARD_ENDPOINT` is the name the shipped `specguard-ruby` gem already
23
23
  * reads, so a repository whose CI posts runs to SpecGuard has it set — that is
24
24
  * the whole reason this server borrows the name rather than coining one. The
25
25
  * SPGD-310 brief writes it as `SPECGUARD_URL`, so that spelling is accepted
@@ -222,7 +222,7 @@ export declare const REPOSITORY_CREDENTIAL: Credential;
222
222
  /**
223
223
  * The `sgu_` key: a person, and a variable nothing else in the toolchain reads.
224
224
  *
225
- * `specguard-rspec` ships runs with an `sgk_` key and has no notion of this one,
225
+ * `specguard-ruby` ships runs with an `sgk_` key and has no notion of this one,
226
226
  * so an operator who already has CI reporting to SpecGuard does NOT already
227
227
  * have this variable — which is why the message says where to mint one rather
228
228
  * than assuming it is lying around.
@@ -47,7 +47,7 @@ export const REPOSITORY_CREDENTIAL = {
47
47
  /**
48
48
  * The `sgu_` key: a person, and a variable nothing else in the toolchain reads.
49
49
  *
50
- * `specguard-rspec` ships runs with an `sgk_` key and has no notion of this one,
50
+ * `specguard-ruby` ships runs with an `sgk_` key and has no notion of this one,
51
51
  * so an operator who already has CI reporting to SpecGuard does NOT already
52
52
  * have this variable — which is why the message says where to mint one rather
53
53
  * than assuming it is lying around.
@@ -272,7 +272,7 @@ async function requestUserAgent() {
272
272
  * ONE TOTAL BUDGET, not one per phase. `requestTimeoutMs` bounds the whole call:
273
273
  * headers and body share it, so a response whose headers took 29s of a 30s
274
274
  * budget has 1s left in which to deliver its body. The sibling transport in
275
- * `specguard-rspec` (`lib/specguard/rspec/transport.rb`) gives each phase its own
275
+ * `specguard-ruby` (`lib/specguard/client/transport.rb`) gives each phase its own
276
276
  * full `@timeout` because `Net::HTTP` exposes exactly that knob and no other;
277
277
  * here the deadline is ours to place, and a single total is both stricter and
278
278
  * the thing an operator who set one number actually meant.
@@ -66,6 +66,17 @@ export declare function optionalString(value: unknown, field: string): string |
66
66
  */
67
67
  export declare function requireString(value: unknown, field: string): string;
68
68
  export declare function optionalBoolean(value: unknown, field: string): boolean | undefined;
69
+ /**
70
+ * A positive integer, or nothing.
71
+ *
72
+ * Accepts only a finite JSON number with no fractional part that is >= 1. A
73
+ * numeric string ("10"), a float (2.5), zero, a negative, NaN and Infinity all
74
+ * throw `ArgumentError` — the same class every other shape check here throws.
75
+ * No upper bound is applied: a ceiling is the callee's to own (the server
76
+ * clamps and reports the value it applied), and the one a tool's schema
77
+ * advertises is the schema's to declare, not this helper's to duplicate.
78
+ */
79
+ export declare function optionalPositiveInteger(value: unknown, field: string): number | undefined;
69
80
  /**
70
81
  * An optional array of non-blank strings, or nothing.
71
82
  *
@@ -93,6 +93,26 @@ export function optionalBoolean(value, field) {
93
93
  throw new ArgumentError(`\`${field}\` must be a boolean.`);
94
94
  return value;
95
95
  }
96
+ /**
97
+ * A positive integer, or nothing.
98
+ *
99
+ * Accepts only a finite JSON number with no fractional part that is >= 1. A
100
+ * numeric string ("10"), a float (2.5), zero, a negative, NaN and Infinity all
101
+ * throw `ArgumentError` — the same class every other shape check here throws.
102
+ * No upper bound is applied: a ceiling is the callee's to own (the server
103
+ * clamps and reports the value it applied), and the one a tool's schema
104
+ * advertises is the schema's to declare, not this helper's to duplicate.
105
+ */
106
+ export function optionalPositiveInteger(value, field) {
107
+ if (value === undefined || value === null)
108
+ return undefined;
109
+ if (typeof value !== "number" || !Number.isInteger(value)) {
110
+ throw new ArgumentError(`\`${field}\` must be an integer.`);
111
+ }
112
+ if (value < 1)
113
+ throw new ArgumentError(`\`${field}\` must be at least 1.`);
114
+ return value;
115
+ }
96
116
  /**
97
117
  * An optional array of non-blank strings, or nothing.
98
118
  *
@@ -1 +1 @@
1
- {"version":3,"file":"args.js","sourceRoot":"","sources":["../../../src/tools/args.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"args.js","sourceRoot":"","sources":["../../../src/tools/args.ts"],"names":[],"mappings":"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"}
@@ -1,6 +1,6 @@
1
1
  import { ArgumentError } from "../errors.js";
2
2
  import { getJsonObject, repositoryTarget } from "../support/specguard-api.js";
3
- import { optionalString, requireString } from "./args.js";
3
+ import { optionalPositiveInteger, optionalString, requireString } from "./args.js";
4
4
  /**
5
5
  * `GET /api/v1/repository?near=<behavior phrase>` as a tool — the bridge half
6
6
  * of roadmap SPGD-1102 ("Ask the suite map"), slice 3. The platform half
@@ -45,6 +45,12 @@ const findTestsNearBehavior = {
45
45
  "The server embeds your phrase and ranks the repository's stored test identities by similarity, " +
46
46
  "returning the top hits in the `near` block — each with its similarity, `signal_source`, last-known " +
47
47
  "path and the weight the latest run measured. " +
48
+ "THE ANSWER IS A PAGE, NOT THE SET: the default page is 10 hits. READ `truncated` AND `limit` in the " +
49
+ "returned `near` block — `limit` is the page size the server APPLIED (it clamps your ask to 50) and " +
50
+ "`truncated: true` means MORE matches exist than were returned, so a full page of 10 may be \"10 of " +
51
+ "37\". When `truncated` is true, re-ask the SAME phrase with a larger optional `limit` (max 50) " +
52
+ "BEFORE paraphrasing it: a repeated phrase is cache-served and free, while each paraphrase is a " +
53
+ "novel phrase and one billed embed. " +
48
54
  "WHAT THE ANSWER IS NOT: it ranks STORED tests nearest the phrase and NEVER answers \"is this " +
49
55
  "already tested?\". It never gates a write and never issues a verdict — a hit near the phrase is not " +
50
56
  "coverage, and an empty answer is not proof of absence. `similarity_floor` is the near-duplicate " +
@@ -108,6 +114,18 @@ const findTestsNearBehavior = {
108
114
  "indistinguishable from one that does not exist. " +
109
115
  "Omit it — or pass a blank — and the call is the singular one under SPECGUARD_API_KEY.",
110
116
  },
117
+ limit: {
118
+ type: "integer",
119
+ minimum: 1,
120
+ maximum: 50,
121
+ description: "OPTIONAL page size: how many hits to return in the `near` block. Omit it for the " +
122
+ "default page of 10. The server clamps the ask to 50 and reports the value it applied " +
123
+ "as `limit` in the `near` block, beside `truncated` — read both: `truncated: true` " +
124
+ "means more matches exist than were returned, and asking again with a larger `limit` " +
125
+ "(same phrase, so cache-served and free) is cheaper than paraphrasing it (a novel " +
126
+ "phrase, one billed embed). Must be an integer >= 1; anything else is refused before " +
127
+ "any request.",
128
+ },
111
129
  },
112
130
  required: ["behavior"],
113
131
  additionalProperties: false,
@@ -123,8 +141,15 @@ const findTestsNearBehavior = {
123
141
  "like an answered ask. Remove the character and send the phrase again.");
124
142
  }
125
143
  const repository = optionalString(args["repository"], "repository");
144
+ const limit = optionalPositiveInteger(args["limit"], "limit");
126
145
  const { api, path } = repositoryTarget(context.config, repository);
127
- const overview = await getJsonObject(api, path, { near: behavior }, context.fetch);
146
+ // `limit` rides the wire only when supplied, so an ask without it is
147
+ // byte-identical to the request this tool made before `limit` existed. The
148
+ // server owns the clamp (50) and reports the applied value in `near.limit`.
149
+ const query = { near: behavior };
150
+ if (limit !== undefined)
151
+ query["limit"] = String(limit);
152
+ const overview = await getJsonObject(api, path, query, context.fetch);
128
153
  return {
129
154
  text: JSON.stringify(overview, null, 2),
130
155
  structured: overview,
@@ -1 +1 @@
1
- {"version":3,"file":"find-tests-near-behavior.js","sourceRoot":"","sources":["../../../src/tools/find-tests-near-behavior.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAC7C,OAAO,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,6BAA6B,CAAC;AAC9E,OAAO,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAG1D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AACH,MAAM,qBAAqB,GAAmB;IAC5C,IAAI,EAAE,0BAA0B;IAEhC,KAAK,EAAE,4BAA4B;IAEnC,WAAW,EACT,mGAAmG;QACnG,iGAAiG;QACjG,qGAAqG;QACrG,+CAA+C;QAC/C,+FAA+F;QAC/F,sGAAsG;QACtG,kGAAkG;QAClG,oGAAoG;QACpG,sGAAsG;QACtG,uGAAuG;QACvG,0DAA0D;QAC1D,sGAAsG;QACtG,mGAAmG;QACnG,sGAAsG;QACtG,qGAAqG;QACrG,oGAAoG;QACpG,oGAAoG;QACpG,qFAAqF;QACrF,oGAAoG;QACpG,oGAAoG;QACpG,4EAA4E;QAC5E,iGAAiG;QACjG,kGAAkG;QAClG,kGAAkG;QAClG,mGAAmG;QACnG,sBAAsB;QACtB,kGAAkG;QAClG,mGAAmG;QACnG,sEAAsE;QACtE,mGAAmG;QACnG,oGAAoG;QACpG,oGAAoG;QACpG,mGAAmG;QACnG,mGAAmG;QACnG,8FAA8F;QAC9F,oGAAoG;QACpG,oGAAoG;QACpG,0DAA0D;QAC1D,qGAAqG;QACrG,oGAAoG;QACpG,oFAAoF;IAEtF,WAAW,EAAE;QACX,IAAI,EAAE,QAAQ;QACd,UAAU,EAAE;YACV,QAAQ,EAAE;gBACR,IAAI,EAAE,QAAQ;gBACd,WAAW,EACT,uFAAuF;oBACvF,uFAAuF;oBACvF,0FAA0F;oBAC1F,0FAA0F;oBAC1F,kFAAkF;oBAClF,oDAAoD;aACvD;YACD,UAAU,EAAE;gBACV,IAAI,EAAE,QAAQ;gBACd,WAAW,EACT,mFAAmF;oBACnF,iFAAiF;oBACjF,6CAA6C;oBAC7C,wFAAwF;oBACxF,6EAA6E;oBAC7E,+EAA+E;oBAC/E,qFAAqF;oBACrF,kFAAkF;oBAClF,2EAA2E;oBAC3E,kDAAkD;oBAClD,uFAAuF;aAC1F;SACF;QACD,QAAQ,EAAE,CAAC,UAAU,CAAC;QACtB,oBAAoB,EAAE,KAAK;KAC5B;IAED,KAAK,CAAC,GAAG,CAAC,IAAI,EAAE,OAAO;QACrB,uEAAuE;QACvE,oEAAoE;QACpE,gBAAgB;QAChB,MAAM,QAAQ,GAAG,aAAa,CAAC,IAAI,CAAC,UAAU,CAAC,EAAE,UAAU,CAAC,CAAC;QAC7D,IAAI,QAAQ,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC;YAChC,MAAM,IAAI,aAAa,CACrB,2FAA2F;gBACzF,2FAA2F;gBAC3F,uEAAuE,CAC1E,CAAC;QACJ,CAAC;QACD,MAAM,UAAU,GAAG,cAAc,CAAC,IAAI,CAAC,YAAY,CAAC,EAAE,YAAY,CAAC,CAAC;QACpE,MAAM,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,gBAAgB,CAAC,OAAO,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;QAEnE,MAAM,QAAQ,GAAG,MAAM,aAAa,CAAC,GAAG,EAAE,IAAI,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE,OAAO,CAAC,KAAK,CAAC,CAAC;QAEnF,OAAO;YACL,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC;YACvC,UAAU,EAAE,QAAQ;SACrB,CAAC;IACJ,CAAC;CACF,CAAC;AAEF,eAAe,qBAAqB,CAAC"}
1
+ {"version":3,"file":"find-tests-near-behavior.js","sourceRoot":"","sources":["../../../src/tools/find-tests-near-behavior.ts"],"names":[],"mappings":"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"}
@@ -12,7 +12,7 @@ import type { ToolDefinition } from "./types.js";
12
12
  * == What is in the bootstrap, and why only these two
13
13
  *
14
14
  * - `lint_intent_annotations` wraps `specguard-lint` (shipped:
15
- * `specguard-rspec/bin/specguard-lint`, SPGD-12 §1).
15
+ * `specguard-ruby/bin/specguard-lint`, SPGD-12 §1).
16
16
  * - `get_repository_overview` wraps `GET /api/v1/repository` (shipped:
17
17
  * `specguard/config/routes.rb`).
18
18
  *
@@ -32,7 +32,7 @@ import updateRepositoryMemberPermissions from "./update-repository-member-permis
32
32
  * == What is in the bootstrap, and why only these two
33
33
  *
34
34
  * - `lint_intent_annotations` wraps `specguard-lint` (shipped:
35
- * `specguard-rspec/bin/specguard-lint`, SPGD-12 §1).
35
+ * `specguard-ruby/bin/specguard-lint`, SPGD-12 §1).
36
36
  * - `get_repository_overview` wraps `GET /api/v1/repository` (shipped:
37
37
  * `specguard/config/routes.rb`).
38
38
  *
@@ -61,7 +61,9 @@ import type { ToolDefinition } from "./types.js";
61
61
  * and `?role=shared` (the exact partition of the accessible set into owned and
62
62
  * shared halves), and `?sort=stale` (never-ingested repositories first, then
63
63
  * least-recently-ingested, `github_full_name` breaking ties so the order is
64
- * deterministic). The concern's own comment says the endpoint reads them "for
64
+ * deterministic) or `?sort=annotated` (least-annotated share first; a
65
+ * repository with no run or an unmeasured suite last, never ranked as 0%; a
66
+ * suite measured at 0-of-N first; `github_full_name` breaking ties). The concern's own comment says the endpoint reads them "for
65
67
  * a machine" — and this bridge IS that machine, so they are forwarded here
66
68
  * rather than re-invented.
67
69
  *
@@ -159,8 +161,8 @@ import type { ToolDefinition } from "./types.js";
159
161
  * The order is `full_name` ascending, which the controller picks as the only
160
162
  * column a client can page or diff against without SpecGuard promising an id
161
163
  * ordering it has not designed — and `?sort=stale` re-sequences exactly that
162
- * loaded set rather than issuing a different query, so the entries never
163
- * change, only their order does. It is stated here for the same reason the
164
+ * loaded set rather than issuing a different query (as does `?sort=annotated`),
165
+ * so the entries never change, only their order does. It is stated here for the same reason the
164
166
  * other tool states its orders: a list whose order is a coincidence and a list
165
167
  * whose order is a contract look identical in a response body.
166
168
  */
@@ -62,7 +62,9 @@ import { optionalString } from "./args.js";
62
62
  * and `?role=shared` (the exact partition of the accessible set into owned and
63
63
  * shared halves), and `?sort=stale` (never-ingested repositories first, then
64
64
  * least-recently-ingested, `github_full_name` breaking ties so the order is
65
- * deterministic). The concern's own comment says the endpoint reads them "for
65
+ * deterministic) or `?sort=annotated` (least-annotated share first; a
66
+ * repository with no run or an unmeasured suite last, never ranked as 0%; a
67
+ * suite measured at 0-of-N first; `github_full_name` breaking ties). The concern's own comment says the endpoint reads them "for
66
68
  * a machine" — and this bridge IS that machine, so they are forwarded here
67
69
  * rather than re-invented.
68
70
  *
@@ -160,8 +162,8 @@ import { optionalString } from "./args.js";
160
162
  * The order is `full_name` ascending, which the controller picks as the only
161
163
  * column a client can page or diff against without SpecGuard promising an id
162
164
  * ordering it has not designed — and `?sort=stale` re-sequences exactly that
163
- * loaded set rather than issuing a different query, so the entries never
164
- * change, only their order does. It is stated here for the same reason the
165
+ * loaded set rather than issuing a different query (as does `?sort=annotated`),
166
+ * so the entries never change, only their order does. It is stated here for the same reason the
165
167
  * other tool states its orders: a list whose order is a coincidence and a list
166
168
  * whose order is a contract look identical in a response body.
167
169
  */
@@ -198,9 +200,11 @@ const listRepositories = {
198
200
  "`role: \"owned\"` or `\"shared\"` (one half of the owned/shared mix — note the ask is " +
199
201
  "spelled `owned`, not the response field's `owner`; under the AGENT key this ask settles " +
200
202
  "to the no-ask, because ownership is a person fact and the key speaks for nobody), and " +
201
- "`sort: \"stale\"` (repositories " +
203
+ "`sort` (`\"stale\"`: repositories " +
202
204
  "CI has never ingested a run for first, then least-recently-ingested, `full_name` " +
203
- "breaking ties). Omit them all and the request is the plain full list. " +
205
+ "breaking ties; `\"annotated\"`: least-annotated share first, repositories with no run " +
206
+ "or an unmeasured suite last — never ranked as 0% — a suite measured at 0-of-N first, " +
207
+ "`full_name` breaking ties). Omit them all and the request is the plain full list. " +
204
208
  "Ordered by `full_name` ascending unless `sort` asks otherwise, and stable across calls " +
205
209
  "either way. " +
206
210
  "The set is exactly what the key behind it may see — a repository outside the credential's " +
@@ -252,16 +256,20 @@ const listRepositories = {
252
256
  },
253
257
  sort: {
254
258
  type: "string",
255
- enum: ["stale"],
256
- description: "Re-order the list stalest-first. The default order is `full_name` ascending, which " +
259
+ enum: ["stale", "annotated"],
260
+ description: "Re-order the list. The default order is `full_name` ascending, which " +
257
261
  "is stable across calls but says nothing about what needs attention; `stale` puts " +
258
262
  "the repositories CI has NEVER ingested a run for FIRST (never-ingested is the " +
259
263
  "stalest state on this list, not a zero), then least-recently-ingested, newest last, " +
260
264
  "with `github_full_name` breaking ties so two calls with the same data agree element " +
261
265
  "for element. " +
266
+ "`annotated` puts the LEAST-annotated suites first (annotated share of the latest " +
267
+ "run, ascending): a suite measured at 0-of-N leads, and repositories CI has never " +
268
+ "reported a run for, or whose suite was not measured, come LAST — an unmeasured suite " +
269
+ "is never ranked as 0% — with `github_full_name` breaking ties. " +
262
270
  "It re-sequences the loaded set rather than issuing a different query: the same " +
263
- "entries, a different order. `stale` is the only ordering the endpoint names — there " +
264
- "is deliberately no word for the default, because omitting the argument already " +
271
+ "entries, a different order. `stale` and `annotated` are the sole sort words the endpoint " +
272
+ "names — there is deliberately no word for the default, because omitting the argument already " +
265
273
  "means it. " +
266
274
  "Any other value a schema-bypassing client sends settles to the server's no-ask clamp " +
267
275
  "(default order, no error); blank (or null) is no ask, byte-identical to omitting the " +
@@ -1 +1 @@
1
- {"version":3,"file":"list-repositories.js","sourceRoot":"","sources":["../../../src/tools/list-repositories.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"list-repositories.js","sourceRoot":"","sources":["../../../src/tools/list-repositories.ts"],"names":[],"mappings":"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"}
@@ -173,12 +173,12 @@ import type { ToolDefinition } from "./types.js";
173
173
  * one CHOOSES THAT RUN, which the controller states in those terms: `?branch=`
174
174
  * asks about a SERIES, this asks WHICH RUN. It is read once, in that memo, so
175
175
  * every run-grain block moves together — `latest_run` and its rollups, the
176
- * four RUN-GRAIN drill-ins (`spec_directory_files`, `spec_file_examples`,
177
- * `repeated_description_examples` and `unannotated_examples`, the flag-style
178
- * rung documented below), `shards`, both growth windows and
179
- * `previous_test_run`.
176
+ * five RUN-GRAIN drill-ins (`spec_directory_files`, `spec_file_examples`,
177
+ * `repeated_description_examples`, `unannotated_examples` — the flag-style
178
+ * rung documented below — and `slowest_examples`, which `layer` narrows),
179
+ * `shards`, both growth windows and `previous_test_run`.
180
180
  *
181
- * That is four of the FIVE drill-ins on this tool, and the excluded one is
181
+ * That is five of the SIX drill-ins on this tool, and the excluded one is
182
182
  * worth naming because it is the composition an agent will actually try:
183
183
  * `unstable_test_runs` is read over the BRANCH WINDOW (`history_runs`), not off
184
184
  * the anchored run, so it does not move with this parameter. Sent together,
@@ -325,7 +325,7 @@ import type { ToolDefinition } from "./types.js";
325
325
  * is an ABSENCE of data. Serving `rows: []` here instead would spend a
326
326
  * distinction a client has no other way to make.
327
327
  *
328
- * THE `commit_sha` ROSTERS above and in README.md CORRECTLY STAY AT FOUR, and
328
+ * THE `commit_sha` ROSTERS above and in README.md COUNT ONE KEY PER DRILL-IN PARAMETER (five, with `layer`), and
329
329
  * the reason is the roster's UNIT, not anything about this block's shape. That
330
330
  * roster carries ONE REPRESENTATIVE KEY PER DRILL-IN PARAMETER, not one entry
331
331
  * per response key: `spec_directory` opens THREE blocks (see its own
@@ -174,12 +174,12 @@ import { optionalBoolean, optionalString } from "./args.js";
174
174
  * one CHOOSES THAT RUN, which the controller states in those terms: `?branch=`
175
175
  * asks about a SERIES, this asks WHICH RUN. It is read once, in that memo, so
176
176
  * every run-grain block moves together — `latest_run` and its rollups, the
177
- * four RUN-GRAIN drill-ins (`spec_directory_files`, `spec_file_examples`,
178
- * `repeated_description_examples` and `unannotated_examples`, the flag-style
179
- * rung documented below), `shards`, both growth windows and
180
- * `previous_test_run`.
177
+ * five RUN-GRAIN drill-ins (`spec_directory_files`, `spec_file_examples`,
178
+ * `repeated_description_examples`, `unannotated_examples` — the flag-style
179
+ * rung documented below — and `slowest_examples`, which `layer` narrows),
180
+ * `shards`, both growth windows and `previous_test_run`.
181
181
  *
182
- * That is four of the FIVE drill-ins on this tool, and the excluded one is
182
+ * That is five of the SIX drill-ins on this tool, and the excluded one is
183
183
  * worth naming because it is the composition an agent will actually try:
184
184
  * `unstable_test_runs` is read over the BRANCH WINDOW (`history_runs`), not off
185
185
  * the anchored run, so it does not move with this parameter. Sent together,
@@ -326,7 +326,7 @@ import { optionalBoolean, optionalString } from "./args.js";
326
326
  * is an ABSENCE of data. Serving `rows: []` here instead would spend a
327
327
  * distinction a client has no other way to make.
328
328
  *
329
- * THE `commit_sha` ROSTERS above and in README.md CORRECTLY STAY AT FOUR, and
329
+ * THE `commit_sha` ROSTERS above and in README.md COUNT ONE KEY PER DRILL-IN PARAMETER (five, with `layer`), and
330
330
  * the reason is the roster's UNIT, not anything about this block's shape. That
331
331
  * roster carries ONE REPRESENTATIVE KEY PER DRILL-IN PARAMETER, not one entry
332
332
  * per response key: `spec_directory` opens THREE blocks (see its own
@@ -480,7 +480,7 @@ 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), " +
483
+ "only in the runtime one — and how the run-wide declared-layer mix moved, `layer_run_growth`), " +
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 " +
@@ -496,6 +496,12 @@ const getRepositoryOverview = {
496
496
  "`repeated_description` to see the examples that all share one repeated description, or " +
497
497
  "`unstable_test` (alongside `branch`) to see one flaky test's outcome run by run, which is " +
498
498
  "the only way to tell a regression from genuine flakiness. " +
499
+ "Every row of `unstable_tests.rows[]` AND of `unstable_tests.shared_description_rows[]` also " +
500
+ "carries `declared_layers` — the sorted DISTINCT set of `@intent layer:` values that test's " +
501
+ "examples declared anywhere in the window. `[]` means no run in the window declared one: NOT " +
502
+ "`unreadable`, and NOT a measured `unit`. A partially annotated test lists only what was " +
503
+ "declared, and more than one entry means the test changed layer mid-window. It is " +
504
+ "DECLARED-ONLY — the stored column, never inferred from the spec path or `files_seen`. " +
499
505
  "All of those describe the repository's NEWEST run, which on a busy repository may be another " +
500
506
  "branch's: pass `commit_sha` to be answered about ONE named run instead — after pushing a " +
501
507
  "commit and waiting for CI, say — then read `run_anchor` to confirm which run you were served, " +
@@ -511,6 +517,43 @@ const getRepositoryOverview = {
511
517
  "is the ONLY figure on this endpoint that means tests SpecGuard can say nothing about. Never " +
512
518
  "read `total_specs - annotated_specs` as that population — on a suite that has never been " +
513
519
  "annotated it is the whole suite, and almost all of it is readable. " +
520
+ "WHICH LAYER THE SUITE DECLARES IS A THIRD, SEPARATE QUESTION, answered on every response by " +
521
+ "`latest_run.layer_counts`, a sibling of `intent_readings`: five operands — `unit`, " +
522
+ "`integration`, `request`, `system` and `undeclared` — that sum to `intent_readings.recorded`. " +
523
+ "It is `null`, NOT five zeros, when the run stored no per-example rows, because a zero would " +
524
+ "read as a measured none. The layers are DECLARED only — an `@intent` annotation said so — and " +
525
+ "NEVER inferred from the directory path, so a test under `spec/models` that declared nothing " +
526
+ "is `undeclared`; and `undeclared` is NOT `unreadable` (a test can be perfectly readable and " +
527
+ "declare no layer). The operands carry no pyramid verdict; reading the mix is yours. " +
528
+ "WHERE THE MACHINE TIME WENT BY LAYER is `latest_run.layer_durations`, a sibling of `layer_counts` " +
529
+ "with the same five keys, each `{total_seconds, timed_count}`. `total_seconds` is `null`, NOT 0, for " +
530
+ "a layer with no timed example, so an untimed layer is not a free one; `timed_count` (at most that " +
531
+ "layer's `layer_counts` entry) is the real denominator for any average. The whole key is `null` when " +
532
+ "the run stored no per-example rows. It is a SUM of example durations — machine time and NOT wall " +
533
+ "clock — so it can exceed `duration_seconds` on a parallel or sharded run. The layer is DECLARED " +
534
+ "only, never inferred from the path, and the operands carry no pyramid verdict. " +
535
+ "HOW THE DECLARED-LAYER MIX MOVED SINCE THE PREVIOUS RUN is `layer_run_growth`, with its contract " +
536
+ "block `layer_run_growth_window` — both TOP-LEVEL siblings of `directory_run_growth`, NOT inside " +
537
+ "`latest_run` (the delta is not in `latest_run.layer_counts`). They compare the latest run with the " +
538
+ "previous run ON THE LATEST RUN'S OWN BRANCH, so no `branch` is needed, and `commit_sha` re-anchors " +
539
+ "them with the rest of the run-grain blocks exactly as it does the area pair. `layer_run_growth` is " +
540
+ "`null` in EVERY non-comparable state — NEVER a block of zeros, so `null` is not \"no change\" — and " +
541
+ "`layer_run_growth_window.state` names why: `latest_unmeasured`, `previous_unmeasured`, " +
542
+ "`assembled_differently`, `neither_recorded`, `previous_unrecorded`, `latest_unrecorded`, or " +
543
+ "`comparable`, plus `no_latest_run` (CI never reported) and `no_previous_run` (the first run on the " +
544
+ "branch). `layer_run_growth_window.comparable` is true exactly when `layer_run_growth` is non-null; " +
545
+ "the window also carries `basis`, `branch`, `anchor_commit_sha` and `baseline_commit_sha`. When " +
546
+ "comparable, `layer_run_growth` is `{layers, baseline_recorded_count, anchor_recorded_count}`, where " +
547
+ "`layers` holds `unit`, `integration`, `request`, `system` and `undeclared`, each " +
548
+ "`{baseline_count, anchor_count, change}`. A layer that did not move reads `change: 0` — a measured " +
549
+ "zero, not an absence — and the five `change` values sum to `anchor_recorded_count` minus " +
550
+ "`baseline_recorded_count`. The layers are DECLARED only, never inferred from the path, and " +
551
+ "`undeclared` is NOT `unreadable`; the operands carry no pyramid verdict, so reading the shift is " +
552
+ "yours. The same " +
553
+ "`layer_counts` rides each row of `spec_directories`, the `spec_directory_files` area block " +
554
+ "and each of its file rows, and every per-example row of `slowest_examples`, " +
555
+ "`spec_file_examples` and `repeated_description_examples` carries `intent_layer` and " +
556
+ "`declared_intent` (`{entity, action, behavior}` or `null`, declared only). " +
514
557
  "TWO BLOCKS COME BACK ON EVERY RESPONSE — no parameter to pass, no flag to set — and they " +
515
558
  "answer what everything above silently depends on: is SpecGuard still being fed? " +
516
559
  "`delivery_health` is why the figures may be STALE: `refusing` is a comparison of stamps, not a " +
@@ -651,7 +694,8 @@ const getRepositoryOverview = {
651
694
  "`unstable_tests` (which tests failed intermittently across the window rather than " +
652
695
  "consistently) and `directory_growth` (how each area moved between the two ENDPOINTS of " +
653
696
  "that window). The per-area comparisons against the PREVIOUS RUN — `directory_run_growth` " +
654
- "and `directory_runtime_growth` — need no branch and take none; they scope to the latest " +
697
+ "and `directory_runtime_growth`, and the declared-layer mix pair `layer_run_growth` / " +
698
+ "`layer_run_growth_window` — need no branch and take none; they scope to the latest " +
655
699
  "run's own branch by construction, so a plain call already carries them.",
656
700
  },
657
701
  spec_directory: {
@@ -660,7 +704,9 @@ const getRepositoryOverview = {
660
704
  "went by directory but not which files inside it spent it. Use a path exactly as served " +
661
705
  "in `latest_run.spec_directories.rows[].path`. Asking populates " +
662
706
  "`latest_run.spec_directory_files` — the spec files in that one directory with their " +
663
- "`total_seconds`/`recorded_count`/`timed_count`, plus the AREA's own `file_count`, " +
707
+ "`total_seconds`/`recorded_count`/`timed_count` and a `layer_counts` split of the declared " +
708
+ "layers (the same five operands as `latest_run.layer_counts`), plus the AREA's own " +
709
+ "`layer_counts`, `file_count`, " +
664
710
  "`recorded_count`, `timed_count` and the `limit` the row list was cut at (the totals " +
665
711
  "describe the whole area, not the returned page, so do not re-derive them from `rows`). " +
666
712
  "The one ask opens THREE blocks, each in its own grain: `spec_directory_files` for which " +
@@ -687,7 +733,8 @@ const getRepositoryOverview = {
687
733
  "`latest_run.spec_files.rows[].path`. Asking populates " +
688
734
  "`latest_run.spec_file_examples` — up to 50 of that file's individual examples cut by " +
689
735
  "DURATION, each with `name`, `file_path`, `line_number`, `spec_file_path`, " +
690
- "`duration_seconds` and `outcome`, plus the FILE's own `recorded_count` and " +
736
+ "`duration_seconds`, `outcome`, `intent_layer` and `declared_intent` (EIGHT fields), " +
737
+ "plus the FILE's own `recorded_count` and " +
691
738
  "`timed_count` and the `limit` the row list was cut at (the totals describe the whole " +
692
739
  "file, not the returned page, so do not re-derive them from `rows`). " +
693
740
  "SENT TOGETHER WITH `unannotated_examples`, it also narrows THAT worklist to this file — " +
@@ -704,8 +751,8 @@ const getRepositoryOverview = {
704
751
  "the same thing. Use a description exactly as served in " +
705
752
  "`latest_run.repeated_descriptions.rows[].name`. Asking populates " +
706
753
  "`latest_run.repeated_description_examples` — up to 25 of that group's members, each " +
707
- "with `name`, `file_path`, `line_number`, `spec_file_path`, `duration_seconds` and " +
708
- "`outcome`, plus the GROUP's own `recorded_count` and `timed_count` and the `limit` " +
754
+ "with `name`, `file_path`, `line_number`, `spec_file_path`, `duration_seconds`, " +
755
+ "`outcome`, `intent_layer` and `declared_intent` (EIGHT fields), plus the GROUP's own `recorded_count` and `timed_count` and the `limit` " +
709
756
  "the row list was cut at (the totals describe the whole group, not the returned page, " +
710
757
  "so do not re-derive them from `rows`). This is the ONLY way to reach a group's " +
711
758
  "members: `slowest_examples` is the run-wide top ten and rarely contains them, and " +
@@ -742,6 +789,8 @@ const getRepositoryOverview = {
742
789
  "`commit_sha`/`test_run_id`, never off its index: a run that recorded nothing under " +
743
790
  "the description contributes no row and a description carried by two examples in one " +
744
791
  "run contributes two, so `rows` is not one entry per run. " +
792
+ "These drill-in rows do NOT carry a layer: read `declared_layers` off the ranking row " +
793
+ "(`unstable_tests.rows[]`), not here. " +
745
794
  "`branch` IS REQUIRED WITH IT, unlike every other argument here: `unstable_tests` is " +
746
795
  "served only for a branch-narrowed window, so this parameter sent alone leaves the " +
747
796
  "whole containing block `null` and there is nothing to drill into — not an empty " +
@@ -754,15 +803,15 @@ const getRepositoryOverview = {
754
803
  commit_sha: {
755
804
  type: "string",
756
805
  description: "Anchor the whole answer on ONE run, naming it by commit sha. This is a DIFFERENT KIND " +
757
- "OF ASK from every other argument here: the five above narrow what is served ABOUT a run " +
806
+ "OF ASK from every other argument here: the drill-in arguments narrow what is served ABOUT a run " +
758
807
  "that was already chosen for you, and this one CHOOSES THAT RUN. `branch` asks about a " +
759
808
  "SERIES; this asks WHICH RUN. Use a sha exactly as served in " +
760
809
  "`latest_run.commit_sha`, `history[].commit_sha` or " +
761
810
  "`unstable_tests.unstable_test_runs.rows[].commit_sha`. " +
762
811
  "Everything at run grain re-anchors together: `latest_run` and its five rollups, the " +
763
- "four RUN-GRAIN drill-ins (`spec_directory_files`, `spec_file_examples`, " +
764
- "`repeated_description_examples` and `unannotated_examples`), `shards`, both per-area " +
765
- "growth windows and `previous_test_run`. " +
812
+ "five RUN-GRAIN drill-ins (`spec_directory_files`, `spec_file_examples`, " +
813
+ "`repeated_description_examples`, `unannotated_examples` and `slowest_examples` — the " +
814
+ "block `layer` narrows), `shards`, both per-area growth windows and `previous_test_run`. " +
766
815
  "`unstable_test_runs` is the one drill-in that does NOT move with " +
767
816
  "it: it is read over the branch window rather than off the anchored run, so sending " +
768
817
  "this with `unstable_test` still gives you that test across the whole window. " +
@@ -823,8 +872,9 @@ const getRepositoryOverview = {
823
872
  "one is additional, not instead. " +
824
873
  "Asking populates `latest_run.unannotated_examples` — up to 100 of the unannotated " +
825
874
  "examples OF WHATEVER YOU ASKED FOR, each with `name`, `file_path`, `line_number` and " +
826
- "`spec_file_path`, `reading` and `derived_intent` (SIX fields: no `duration_seconds` and " +
827
- "no `outcome`, unlike the per-example drill-ins above), plus that same population's own " +
875
+ "`spec_file_path`, `reading` and `derived_intent` (SIX fields: no `duration_seconds`, no " +
876
+ "`outcome` and no `intent_layer`, unlike the per-example drill-ins above, which carry " +
877
+ "EIGHT), plus that same population's own " +
828
878
  "`recorded_count`, `derived_count` and `unreadable_count`, the " +
829
879
  "`limit` the row list was cut at, and `spec_file`/`spec_directory` ECHOED BACK as the " +
830
880
  "server READ them — `null` for each one you did not send. " +
@@ -888,6 +938,26 @@ const getRepositoryOverview = {
888
938
  "same as omitting it and sends nothing at all: declining is not sending, which is how " +
889
939
  "every other argument here is declined too — none of them has an \"off\" value.",
890
940
  },
941
+ layer: {
942
+ type: "string",
943
+ description: "Narrow ONE block to one DECLARED test layer: `latest_run.slowest_examples` — the " +
944
+ "run-wide slowest-examples ranking — and NOTHING else. It does NOT narrow " +
945
+ "`spec_file_examples`, `spec_directory_files`, `unannotated_examples` or " +
946
+ "`repeated_description_examples`. Use it after `latest_run.layer_durations` shows one " +
947
+ "layer holding most of the machine time (say `request`) and you need to know WHICH " +
948
+ "tests. Values: `unit`, `integration`, `request`, `system` or `undeclared` (a test that " +
949
+ "declared no layer). Any other value is read by the server as NO ASK — never a 400 or " +
950
+ "404 — so it is forwarded unvalidated and a typo silently returns the un-narrowed " +
951
+ "ranking: check that `slowest_examples.layer` is echoed back. That echo is present ONLY " +
952
+ "when a layer was asked (the key is ABSENT otherwise). With a layer asked, " +
953
+ "`recorded_count`, `timed_count` and `reported_outcome_count` are that LAYER's own " +
954
+ "counts (`recorded_count` equals `layer_counts[layer]`, `timed_count` equals " +
955
+ "`layer_durations[layer].timed_count`), not the run's. A layer with no examples answers " +
956
+ "`rows: []` and `recorded_count: 0`, while `slowest_examples: null` still means the run " +
957
+ "recorded nothing at all. Layers are DECLARED only (an `@intent` annotation said so), " +
958
+ "never inferred from the file path. It is at RUN GRAIN, so it moves with `commit_sha`. " +
959
+ "A blank value sends nothing.",
960
+ },
891
961
  },
892
962
  additionalProperties: false,
893
963
  },
@@ -902,6 +972,10 @@ const getRepositoryOverview = {
902
972
  const repeatedDescription = optionalString(args["repeated_description"], "repeated_description");
903
973
  const unstableTest = optionalString(args["unstable_test"], "unstable_test");
904
974
  const commitSha = optionalString(args["commit_sha"], "commit_sha");
975
+ // Forwarded UNVALIDATED, deliberately: the server reads any value outside
976
+ // the five declared layers as no ask (never a 400/404), so an enum check
977
+ // here would only add a second, divergent opinion about what is valid.
978
+ const layer = optionalString(args["layer"], "layer");
905
979
  // A BOOLEAN, and deliberately not stringified below. The server reads only
906
980
  // whether the key is PRESENT — `?unannotated_examples=false` opens the block
907
981
  // exactly as `=true` does — and `getJson` omits only `undefined`, so sending
@@ -926,6 +1000,7 @@ const getRepositoryOverview = {
926
1000
  repeated_description: repeatedDescription,
927
1001
  unstable_test: unstableTest,
928
1002
  commit_sha: commitSha,
1003
+ layer,
929
1004
  unannotated_examples: unannotatedExamples === true ? "true" : undefined,
930
1005
  }, context.fetch);
931
1006
  return {
@@ -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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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "specguard-mcp",
3
- "version": "0.1.39",
3
+ "version": "0.1.41",
4
4
  "description": "MCP server exposing SpecGuard suite intelligence to AI coding agents",
5
5
  "license": "ISC",
6
6
  "type": "module",