@molecule/api-ai-tools 1.14.4 → 1.14.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. package/README.md +236 -190
  2. package/dist/browser-probe.d.ts +4 -4
  3. package/dist/browser-probe.d.ts.map +1 -1
  4. package/dist/browser-probe.js +5 -5
  5. package/dist/command-position.d.ts +15 -16
  6. package/dist/command-position.d.ts.map +1 -1
  7. package/dist/command-position.js +21 -23
  8. package/dist/cut-run.d.ts +9 -9
  9. package/dist/cut-run.js +6 -6
  10. package/dist/failure-kind.d.ts +6 -6
  11. package/dist/failure-kind.js +6 -6
  12. package/dist/index.d.ts +2 -2
  13. package/dist/index.js +2 -2
  14. package/dist/inline-script.d.ts +5 -5
  15. package/dist/inline-script.js +6 -6
  16. package/dist/line-diff.d.ts +2 -3
  17. package/dist/line-diff.d.ts.map +1 -1
  18. package/dist/line-diff.js +2 -3
  19. package/dist/no-test-run.d.ts +5 -5
  20. package/dist/no-test-run.d.ts.map +1 -1
  21. package/dist/no-test-run.js +9 -8
  22. package/dist/output-filter.d.ts +2 -2
  23. package/dist/output-filter.js +2 -2
  24. package/dist/pipeline-exit-note.d.ts +1 -1
  25. package/dist/pipeline-exit-note.js +1 -1
  26. package/dist/playwright-report.d.ts +1 -1
  27. package/dist/playwright-report.js +1 -1
  28. package/dist/server-command.d.ts +2 -2
  29. package/dist/server-command.js +2 -2
  30. package/dist/sleep-peek.d.ts +1 -1
  31. package/dist/sleep-peek.js +1 -1
  32. package/dist/suite-overlap.d.ts +24 -25
  33. package/dist/suite-overlap.d.ts.map +1 -1
  34. package/dist/suite-overlap.js +41 -43
  35. package/dist/tools.d.ts +26 -28
  36. package/dist/tools.d.ts.map +1 -1
  37. package/dist/tools.js +98 -69
  38. package/dist/trace-artifacts.d.ts +64 -65
  39. package/dist/trace-artifacts.d.ts.map +1 -1
  40. package/dist/trace-artifacts.js +73 -75
  41. package/dist/types.d.ts +5 -5
  42. package/dist/utilities.d.ts +107 -91
  43. package/dist/utilities.d.ts.map +1 -1
  44. package/dist/utilities.js +191 -143
  45. package/package.json +2 -2
@@ -2,7 +2,7 @@
2
2
  * What a failed Playwright run's own trace files say about the requests its page made — read
3
3
  * headlessly, in the sandbox, from the `trace.zip` files the run left behind.
4
4
  *
5
- * X1 xr-molecule-flash-m100 (+51:19 → +53:00, 2026-10-16) ended with three failures against the
5
+ * A run ended with three failures against the
6
6
  * deployed URL — `social.spec.ts:22` and `:153` waited for a "Unfollow" button that never appeared
7
7
  * after the click, and `url-navigation.spec.ts:234` was bounced to `/login` mid-test — and nothing
8
8
  * in the run's result said why. The app's own `toggleFollow` swallowed the error of its request
@@ -49,7 +49,7 @@ export const MAX_TRACED_BODY_CHARS = 300;
49
49
  * How much of a websocket's frames the trace read keeps. Longer than {@link MAX_TRACED_BODY_CHARS}
50
50
  * because a frame read back to its own message still has the message, the module id and the
51
51
  * location to carry — Vite's transform error alone is a sentence longer than the plain body cap,
52
- * and the note prints its first 120–200 characters anyway (xr-molecule-flash-m157).
52
+ * and the note prints its first 120–200 characters anyway.
53
53
  */
54
54
  const MAX_TRACED_WEBSOCKET_CHARS = 600;
55
55
  /** How many tests the note in a run's result names. */
@@ -65,7 +65,7 @@ export const MAX_TRACE_NOTE_REQUESTS = 4;
65
65
  /**
66
66
  * How many times ONE test may send the same method+path before the note calls it a render loop.
67
67
  *
68
- * xr-molecule-flash-m215 (+27:27 → +29:42): an Editor effect with `[seeded, slug, t]` in its
68
+ * An Editor effect with `[seeded, slug, t]` in its
69
69
  * dependency list re-fetched `GET /api/articles/<slug>` 2,106 times in one test. The trace reader
70
70
  * caps and de-duplicates its request list, so the note printed four identical `→ 200` lines and
71
71
  * the run patched the component's seeding, rebuilt and re-ran before unzipping the trace by hand.
@@ -109,11 +109,11 @@ const TRACE_NOTE_FAILURE_CHARS = 120;
109
109
  * as its own context: actions and requests keep their context id, requests and frame snapshots
110
110
  * keep the pageId Playwright records, and the failing assertion's page — the page its own step id
111
111
  * ran on — decides which actions, snapshots and requests become the test's row. What the test's
112
- * other browser contexts recorded is reported apart, as `otherContexts` (xr-molecule-flash-m160).
112
+ * other browser contexts recorded is reported apart, as `otherContexts`.
113
113
  *
114
114
  * A request answered 4xx by the app's OWN API also keeps what the page SENT and the first of what
115
115
  * came back: Playwright stores either inline (`text`) or in a resource entry (`_file`), and both
116
- * are read. That is where a wrapped body shows: xr-molecule-flash-m111's helper passed
116
+ * are read. That is where a wrapped body shows: a helper passed
117
117
  * `{ data: body }` as app-http's second argument, so every POST/PUT was `{"data":{…}}` and the API
118
118
  * validated `{}`. Status alone said only "422".
119
119
  *
@@ -2288,7 +2288,7 @@ function sameTracePath(a, b) {
2288
2288
  * The requests of one trace, one entry per method+path, with the trace's own repeat count.
2289
2289
  *
2290
2290
  * A loop is why this exists: the reader keeps at most four copies of a method+path, so the row
2291
- * must print ONE line with the real number (m215's `×2106`) rather than four identical lines.
2291
+ * must print ONE line with the real number (`×2106`) rather than four identical lines.
2292
2292
  *
2293
2293
  * @param requests - The requests to print, in the note's own order.
2294
2294
  * @param repeated - The trace's repeated groups ({@link TraceArtifact.repeated}).
@@ -2345,7 +2345,7 @@ function shownRequest(shown, gotChars) {
2345
2345
  *
2346
2346
  * The loop is not a flaky API: an effect whose dependency list holds a value that is new on every
2347
2347
  * render re-fetches forever, and the fix is that dependency list, never the test or the handler.
2348
- * m215's model found this only by unzipping a trace by hand after a wasted fix and a re-run.
2348
+ * This was found only by unzipping a trace by hand after a wasted fix and a re-run.
2349
2349
  *
2350
2350
  * @param group - The repeated group.
2351
2351
  * @param file - The app source file whose code sends it, when the caller read one.
@@ -2376,7 +2376,7 @@ function callSiteOf(group, callSites) {
2376
2376
  * The failing step's own request as the note writes it first: `the failing step sent DELETE
2377
2377
  * /api/profiles/x/follow → 200 got {"profile":{…}}`.
2378
2378
  *
2379
- * It prints the response body whatever the status — an ANSWERED request is the point: m135's
2379
+ * It prints the response body whatever the status — an ANSWERED request is the point: a
2380
2380
  * Follow click sent the DELETE an unfollow sends, got a 200 and a profile with `following: false`,
2381
2381
  * and nothing in the result said which verb the click used.
2382
2382
  *
@@ -2428,7 +2428,7 @@ function wrappedInData(text) {
2428
2428
  * 404), the manifest, a favicon, the fonts a stylesheet pulls, and Vite's/dev's own asset paths.
2429
2429
  *
2430
2430
  * These are not the failing step's dependencies, so neither a missing response nor a 404 on one is
2431
- * a cause. xr-molecule-flash-m125 (+29:33) was handed "no response recorded — still in flight when
2431
+ * a cause. A run was handed "no response recorded — still in flight when
2432
2432
  * the test ended … GET /sw.js; GET /fonts/ionicons.woff" and answered it by writing a CACHING
2433
2433
  * service worker into the app — in front of `/assets/*`, exactly what makes a redeployed fix
2434
2434
  * invisible to the next proof run. The note is about the test's own API calls.
@@ -2438,7 +2438,7 @@ const STATIC_ASSET_PATH = /^\/(?:sw|service-worker)\.js(?:[?#]|$)|\/manifest\.we
2438
2438
  * The PWA worker's own hashed script, the manifest's touch icons and the splash images.
2439
2439
  *
2440
2440
  * The worker and the shell type these `other`/`fetch`, not `script`/`image`, so
2441
- * {@link STATIC_ASSET_TYPES} alone never caught them: on xr-molecule-flash-m148 every failing
2441
+ * {@link STATIC_ASSET_TYPES} alone never caught them: every failing
2442
2442
  * test's row filled three of its four request slots with `GET /workbox-d8ed3718.js → 200` and
2443
2443
  * `GET /icons/splash-1125x2436.svg → 200`, and the register `POST /api/users` that explains the
2444
2444
  * signed-out page never appeared.
@@ -2481,7 +2481,7 @@ export function isStaticAssetRequest(request) {
2481
2481
  * Whether a trace recorded a failed response or a request error other than cancellation.
2482
2482
  *
2483
2483
  * A 404 on a static asset is excepted: `/sw.js` and `/fonts/*` 404 on an app that never shipped
2484
- * them, and naming one as a failure sent m125 into writing the caching worker it had asked about.
2484
+ * them, and naming one as a failure sent a run into writing the caching worker it had asked about.
2485
2485
  * A 5xx on an asset, or a network error, still counts. A request error alone does not locate
2486
2486
  * the cause in the server: the browser or network may have rejected the request.
2487
2487
  *
@@ -2503,7 +2503,7 @@ function recordedRequestFailure(request) {
2503
2503
  /**
2504
2504
  * Whether a trace recorded no response and no error other than cancellation. The request may
2505
2505
  * have been pending or cancelled when recording ended; the trace does not establish whether
2506
- * the endpoint stalled. A shell request is not evidence about the step (m125 +29:33).
2506
+ * the endpoint stalled. A shell request is not evidence about the step.
2507
2507
  *
2508
2508
  * @param request - One request a trace recorded.
2509
2509
  * @returns True when the request's missing response is inconclusive and worth naming.
@@ -2519,12 +2519,12 @@ export function unansweredRequest(request) {
2519
2519
  * the navigation timed out.
2520
2520
  *
2521
2521
  * The page shell's own incidental requests (`/sw.js`, the manifest, a favicon, a font) are
2522
- * excepted for the reason {@link isStaticAssetRequest} documents: m125's run was sent to write a
2523
- * caching service worker by an aborted `/sw.js`. A pending `/assets/*.css` is different — the
2524
- * navigation blocks on it, so it is the reason `page.goto` ran out of time rather than one of the
2525
- * app's API calls (xr-molecule-flash-m135 +34:10: three deployed `page.goto` timeouts on tests that
2526
- * pass locally, one 88 KB stylesheet fetch measured at 27 s, and the failing tests' traces each
2527
- * held the never-answered CSS while the note said "the cause is in the page").
2522
+ * excepted for the reason {@link isStaticAssetRequest} documents: an aborted `/sw.js` once sent a
2523
+ * run to write a caching service worker. A pending `/assets/*.css` is different — the navigation
2524
+ * blocks on it, so it is the reason `page.goto` ran out of time rather than one of the app's API
2525
+ * calls (three deployed `page.goto` timeouts on tests that pass locally, one 88 KB stylesheet
2526
+ * fetch measured at 27 s, and the failing tests' traces each holding the never-answered CSS while
2527
+ * the note said "the cause is in the page").
2528
2528
  *
2529
2529
  * @param request - One request a trace recorded.
2530
2530
  * @returns True when the request is a document subresource that never finished.
@@ -2544,7 +2544,7 @@ export function stalledDocumentSubresource(request) {
2544
2544
  * How far a trace's last recorded step can sit after an earlier walk's failing test and still be
2545
2545
  * that test. The trace names the LINE of the last step it recorded (the click, the wait), while the
2546
2546
  * run's own summary names the test's DECLARATION line, so a row that repeats a failure sits a few
2547
- * lines below the declaration it repeats: m112's favorite test is declared at
2547
+ * lines below the declaration it repeats: the favorite test is declared at
2548
2548
  * `articles.spec.ts:123` and its last step, the click that changed nothing, was on `:133`.
2549
2549
  */
2550
2550
  const RECURRENCE_LINE_WINDOW = 40;
@@ -2566,7 +2566,7 @@ function sameLocationFile(left, right) {
2566
2566
  * The earlier walk's locations come from the run's own summary — the test's DECLARATION line —
2567
2567
  * while the trace names the last step's line, so a repeat is the same file with its step inside
2568
2568
  * {@link RECURRENCE_LINE_WINDOW} lines after the NEAREST earlier declaration before it (the test
2569
- * body it belongs to). A line BEFORE the declaration is a hook, not the test: m112's
2569
+ * body it belongs to). A line BEFORE the declaration is a hook, not the test:
2570
2570
  * `url-navigation.spec.ts:107` is the Pagination suite's `afterEach`, which four different tests
2571
2571
  * share. A trace that names no spec cannot be placed at all.
2572
2572
  *
@@ -2609,7 +2609,7 @@ function navigationMethod(operation) {
2609
2609
  *
2610
2610
  * The trace names the line of its LAST recorded step; the runner's summary names the test's
2611
2611
  * DECLARATION line, and the step sits inside the body just after it ({@link
2612
- * RECURRENCE_LINE_WINDOW}). A line BEFORE the declaration is a hook — m153's teardown trace sits
2612
+ * RECURRENCE_LINE_WINDOW}). A line BEFORE the declaration is a hook — a teardown trace sits
2613
2613
  * at `url-navigation.spec.ts:107`, the Pagination suite's `afterEach`, while the failing test is
2614
2614
  * declared at `:206` — and a hook is not the failing test's operation.
2615
2615
  *
@@ -2639,7 +2639,7 @@ function runFailureOf(item, failures) {
2639
2639
  * quotes and the line a re-run command takes, so it wins whenever the run reported one for this
2640
2640
  * file: matched by the trace's own line inside the test body ({@link runFailureOf}), and otherwise
2641
2641
  * by the file alone when that file has exactly ONE reported failure — an `afterEach` line sits
2642
- * BEFORE the declaration, so the line window cannot match it (xr-molecule-flash-m163's row said
2642
+ * BEFORE the declaration, so the line window cannot match it (a row said
2643
2643
  * `navigation.spec.ts:12`, the suite's `afterEach`, for the test declared at `:200`).
2644
2644
  *
2645
2645
  * @param item - One traced failure.
@@ -2682,7 +2682,7 @@ function requestCoversWait(request, wait) {
2682
2682
  * navigation ({@link NAVIGATION_OPERATIONS}); the trace's record of that call never finished; and
2683
2683
  * a document subresource still pending at the end started inside that wait
2684
2684
  * ({@link requestCoversWait}). An asset merely unfinished when the test was cancelled, or one a
2685
- * teardown/`afterEach` trace holds, meets none of these and is not a cause (m153).
2685
+ * teardown/`afterEach` trace holds, meets none of these and is not a cause.
2686
2686
  *
2687
2687
  * @param item - One traced failure.
2688
2688
  * @param report - The runner's report and the run's next step.
@@ -2713,11 +2713,11 @@ function stalledNavigation(item, report) {
2713
2713
  /**
2714
2714
  * Whether a trace holds evidence the note can explain: a request that got a RECORDED response, a
2715
2715
  * real failure (4xx/5xx or a network error), or a console line. A request with no response is
2716
- * not evidence (m112 +53:46): four of the note's five rows were traces of one `afterEach` line
2716
+ * not evidence: four of the note's five rows were traces of one `afterEach` line
2717
2717
  * whose every request was `-1`, so the favorite cause — repeated in all three walks — stayed
2718
2718
  * hidden in "… and 7 more traced failures".
2719
2719
  *
2720
- * A request the page shell made (m125 +29:33: `/sw.js`, a font) is not evidence about the step
2720
+ * A request the page shell made (`/sw.js`, a font) is not evidence about the step
2721
2721
  * either, answered or not. The exception is a document subresource that never finished while the
2722
2722
  * navigation the RUNNER reports failing was still open: that navigation waits on it, so it is the
2723
2723
  * reason the `page.goto` timed out ({@link stalledNavigation}).
@@ -2744,7 +2744,7 @@ function traceRowEvidence(item, report) {
2744
2744
  /**
2745
2745
  * The note's row order: a row with a REAL failure first, then a row whose failure an earlier walk
2746
2746
  * also had, then the rest. A recurrence is the only evidence a row carries when its requests were
2747
- * all answered (m112's favorite cause: the click's own request answered, the button never
2747
+ * all answered (the favorite cause: the click's own request answered, the button never
2748
2748
  * changed).
2749
2749
  *
2750
2750
  * @param item - One traced failure.
@@ -2771,7 +2771,7 @@ const NETWORK_ERROR = /\bnet::ERR_[A-Z0-9_]+\b/;
2771
2771
  *
2772
2772
  * A page that never loaded is not a set of app failures: a `page.goto` timeout on a document that
2773
2773
  * ended in a `net::ERR_*` is the one line that explains every test that timed out on it, and it is
2774
- * what m118's preview walk never saw (`net::ERR_CONTENT_DECODING_FAILED` on a gzipped HTML body).
2774
+ * what a preview walk never saw (`net::ERR_CONTENT_DECODING_FAILED` on a gzipped HTML body).
2775
2775
  *
2776
2776
  * @param item - One traced failure.
2777
2777
  * @returns True when the page's navigation started and never ended.
@@ -2846,7 +2846,7 @@ function isApiPath(path, prefixes) {
2846
2846
  /**
2847
2847
  * The API requests that recorded an error without a response, one entry per method+path.
2848
2848
  * Missing failure text stays inconclusive regardless of the number of pending requests
2849
- * (m303/m305). An answer from another endpoint cannot excuse a recorded failure here.
2849
+ * An answer from another endpoint cannot excuse a recorded failure here.
2850
2850
  *
2851
2851
  * @param items - The traces the note is about.
2852
2852
  * @param apiPrefixes - The API prefixes the caller read, or empty.
@@ -2881,7 +2881,7 @@ function failedApiRequests(items, apiPrefixes) {
2881
2881
  * Whether the runner reported this traced test's failure as a navigation that ran out of budget.
2882
2882
  *
2883
2883
  * The runner's own error names the call (`page.goto`, `page.reload`), and that report is the only
2884
- * signal used: m153 showed a `Frame.goto` that never finished on a trace whose failure was a 15 s
2884
+ * signal used: a `Frame.goto` can stay unfinished on a trace whose failure was a 15 s
2885
2885
  * `page.waitForSelector` timeout (the test was cut off mid-navigation), so an unfinished frame
2886
2886
  * action alone would call a selector failure a page-load failure.
2887
2887
  *
@@ -2951,7 +2951,7 @@ function credentialExchangeBody(sent) {
2951
2951
  * This is the path half of {@link isCredentialExchange}, exported so a caller holding only a
2952
2952
  * `METHOD path` reads the same classification: a Hurl failing entry says
2953
2953
  * `POST /api/users/login` and nothing about the body, and the whole-suite note must not explain
2954
- * a wrong-password login that answered 200 as a cookie-jar effect (xr-molecule-flash-m176).
2954
+ * a wrong-password login that answered 200 as a cookie-jar effect.
2955
2955
  *
2956
2956
  * @param path - The request path (`/api/users/login`); a query or fragment is ignored.
2957
2957
  * @param authEndpoints - The endpoints the app's auth config names (`/users/login`).
@@ -2979,7 +2979,7 @@ export function isCredentialExchangePath(path, authEndpoints = []) {
2979
2979
  * `/session` or `/auth/signin`), the path's own last segments name it (`/users/login`), or the
2980
2980
  * body is a credential payload (`{"user":{"email":…,"password":…}}` sends a registration).
2981
2981
  *
2982
- * xr-molecule-flash-m165 (+10:22): `POST /api/users/login → 401
2982
+ * A `POST /api/users/login → 401
2983
2983
  * {"errors":{"credentials":["invalid"]}}` was answered with the missing-token sentence — "the
2984
2984
  * client did not attach the token … The API handler is not the problem" — for a request whose
2985
2985
  * whole purpose is to obtain a token. The model read helpers and configs for 40 minutes instead of
@@ -3012,7 +3012,7 @@ function sameRequestRecord(left, right) {
3012
3012
  * Two readings, strongest first in the sentence but either is proof a token existed: a credential
3013
3013
  * exchange the trace answered 2xx (the test's own registration/login), or any request the client
3014
3014
  * attached an `Authorization` header to. A request from another browser context is not evidence
3015
- * about this one (m160), and a candidate with a clock is only prior when it started before the
3015
+ * about this one, and a candidate with a clock is only prior when it started before the
3016
3016
  * refusal. On a trace without clocks (an older Playwright, a synthetic fixture) the trace-level
3017
3017
  * fact still stands, and the sentence says what the trace recorded rather than "before".
3018
3018
  *
@@ -3069,7 +3069,7 @@ function signInEvidenceLine(evidence) {
3069
3069
  /**
3070
3070
  * The route-guard reading for a refused request with no session evidence behind it.
3071
3071
  *
3072
- * xr-molecule-flash-m221's whole detour: the test navigates to a protected URL while signed out and
3072
+ * The whole detour: the test navigates to a protected URL while signed out and
3073
3073
  * asserts the redirect its route owes. Nothing about the client is wrong; the trace already shows
3074
3074
  * the URL transition, so the sentence names it and the guard the test's assertion measures.
3075
3075
  *
@@ -3103,18 +3103,18 @@ function routeGuardSentence(context) {
3103
3103
  * token on the client, and only then may the note prescribe HTTP-client rewiring. A 403 is a
3104
3104
  * permission answer, not a credential one, and says so.
3105
3105
  *
3106
- * xr-molecule-flash-m148 (+29:18): `POST /api/articles/…/favorite → 401 {"errors":{"token":["is
3106
+ * A `POST /api/articles/…/favorite → 401 {"errors":{"token":["is
3107
3107
  * missing"]}}` was answered with the handler sentence for six local walks, while the trace proved
3108
3108
  * the request carried no `Authorization` header at all and the app's hand-rolled session store
3109
3109
  * never handed its token to the shared client.
3110
3110
  *
3111
- * xr-molecule-flash-m156 (+16:15): the same 401 shape after a reload, and the page's own console
3111
+ * The same 401 shape after a reload: the page's own console
3112
3112
  * named the cause — `@molecule/app-http` logged `no client is bonded`. The auth setup ran before
3113
3113
  * the HTTP setup and kept the fallback client, so the restored token landed on a client nothing
3114
3114
  * sent through. When the trace carries that line, the no-header sentence names the ordering fix
3115
3115
  * instead of leaving the run to re-derive it.
3116
3116
  *
3117
- * xr-molecule-flash-m165 (+10:22): a `POST /api/users/login → 401
3117
+ * A `POST /api/users/login → 401
3118
3118
  * {"errors":{"credentials":["invalid"]}}` is a CREDENTIAL EXCHANGE — the request is how a token is
3119
3119
  * obtained, so an absent `Authorization` header is the request being what it is, not a client bug.
3120
3120
  * The note said "the client did not attach the token … The API handler is not the problem" and the
@@ -3123,7 +3123,7 @@ function routeGuardSentence(context) {
3123
3123
  * categorical handler sentence is gone from the no-header branch too, because a route that
3124
3124
  * requires a token where the app allows anonymous access is the handler's own mistake.
3125
3125
  *
3126
- * xr-molecule-flash-m221 (+20:13): `url-navigation.spec.ts` navigates to `/?feed=following` while
3126
+ * `url-navigation.spec.ts` navigates to `/?feed=following` while
3127
3127
  * SIGNED OUT and asserts the `/login` redirect. Its `GET /api/articles/feed → 401` carried no
3128
3128
  * header because the test never signed in, and the old categorical sentence — "the client did not
3129
3129
  * attach the token" — sent the model into replacing a working HTTP client; the replacement lost the
@@ -3241,12 +3241,12 @@ function authRefusalSentence(request, unbondedClient = false, authEndpoints = []
3241
3241
  * The note's credential-refusal advice, one sentence per distinct shape — at most two.
3242
3242
  *
3243
3243
  * The shapes are `(status, Authorization scheme, cookie present, credential exchange, session
3244
- * evidence)`: m148's ten walks repeated one shape (`401`, no header) on every failing test, and
3244
+ * evidence)`: ten walks repeated one shape (`401`, no header) on every failing test, and
3245
3245
  * repeating its sentence per row would bury the fact rather than state it. A login and a protected
3246
3246
  * request that both carry no header are DIFFERENT shapes — one is the credentials being checked,
3247
- * the other is a request that presented no token (m165). A protected request WITH session evidence
3247
+ * the other is a request that presented no token. A protected request WITH session evidence
3248
3248
  * and one without are different shapes too: only the first can say a token was lost on the client
3249
- * (m221), and collapsing them would prescribe the HTTP-client rewiring for a signed-out route test.
3249
+ * and collapsing them would prescribe the HTTP-client rewiring for a signed-out route test.
3250
3250
  *
3251
3251
  * @param items - The traces the note is about.
3252
3252
  * @param authEndpoints - The endpoints the app's auth config names.
@@ -3313,7 +3313,7 @@ function isLogoutRequest(request) {
3313
3313
  * `@molecule/app-auth`'s `logout()` calls the endpoint inside a `.catch` and clears the session in
3314
3314
  * `finally` (`packages/app/core/auth/src/client.ts`): a 401 there is EXPECTED on a sign-out and is
3315
3315
  * not the failure. What the test waits for is the URL moving, which the page has to do itself.
3316
- * xr-molecule-flash-m156 (+24:02 → +33:52) read `POST /api/users/logout → 401` as a broken
3316
+ * A run read `POST /api/users/logout → 401` as a broken
3317
3317
  * endpoint, added a backend logout route, and paid a re-run and a redeploy — while the real cause
3318
3318
  * was the `navigate('/')` the refactor had dropped.
3319
3319
  *
@@ -3379,7 +3379,7 @@ const ABSOLUTE_URL = /^[a-z][a-z0-9+.-]*:\/\//i;
3379
3379
  * knownApiPrefixes}) — a CDN font or a third-party script has no `/api` under it, and with no
3380
3380
  * known prefix nothing is claimed.
3381
3381
  *
3382
- * xr-molecule-flash-m165 (+10:22): the suite's helper defaulted `API_BASE` to
3382
+ * The suite's helper defaulted `API_BASE` to
3383
3383
  * `https://api.realworld.show/api` and its set-up seeded rows there, while the browser drove this
3384
3384
  * app — whose own `/api` answers a login for none of those users. The trace's absolute-URL rows
3385
3385
  * were the evidence, and the note said nothing about them.
@@ -3446,7 +3446,7 @@ function appOriginOfTarget(target) {
3446
3446
  *
3447
3447
  * It leads the note because it is the cheapest possible wrong result: every row the suite creates
3448
3448
  * lands in a database this app never reads, so the failure says nothing about the app's code.
3449
- * xr-molecule-flash-m165 spent the walk after its failed login reading helpers and configs for a
3449
+ * The walk after a failed login was spent reading helpers and configs for a
3450
3450
  * missing token, when the command's `BASE_URL`/`API_BASE` disagreement was the cause.
3451
3451
  *
3452
3452
  * @param found - The foreign-origin request the trace holds.
@@ -3519,11 +3519,10 @@ function missingApiPrefixSentence(request) {
3519
3519
  * With proof ({@link TraceMissingText.dropped}) it names the response and the fact the trace
3520
3520
  * proves — the value reached the browser and the page did not render it — and stops there. Which
3521
3521
  * cut drops it (a slice, a filter, a limit) is in the component that maps the response, and the
3522
- * note cannot see that component; naming the mapping step is the whole instruction
3523
- * (xr-molecule-flash-m169).
3522
+ * note cannot see that component; naming the mapping step is the whole instruction.
3524
3523
  *
3525
3524
  * Without that proof the sentence says only what the trace shows — a response contained the text —
3526
- * and makes no rendering claim: m194's awaited title was on the page, in a disabled button, while
3525
+ * and makes no rendering claim: an awaited title was on the page, in a disabled button, while
3527
3526
  * the only response carrying it was the creation POST (a button failure is not a missing article).
3528
3527
  *
3529
3528
  * @param missing - The awaited text and the response that carried it.
@@ -3600,7 +3599,7 @@ function bodyCarriesEmptyField(sent, key) {
3600
3599
  /**
3601
3600
  * The field a test typed into that the same page submitted empty, when the trace recorded both.
3602
3601
  *
3603
- * This is the Settings race of xr-molecule-flash-m173: `page.fill('textarea[name="bio"]', newBio)`
3602
+ * This is the Settings race: `page.fill('textarea[name="bio"]', newBio)`
3604
3603
  * then `button[type=submit]`, and the `PUT /api/user` carried `"bio": ""`. The form's seeding
3605
3604
  * effect re-ran between the fill and the submit — on the deployed URL the background session
3606
3605
  * verification lands later than it does locally, and it handed the form a new user object. The
@@ -3708,7 +3707,7 @@ function sfntVersionIsHtml(reason) {
3708
3707
  *
3709
3708
  * `Failed to decode downloaded font: <url> | OTS parsing error: invalid sfntVersion: 1008821359`
3710
3709
  * is not a font to debug: the URL answered HTML (the app's `index.html`, the SPA fallback), so
3711
- * the file the `@font-face` names is not there. xr-molecule-flash-m186's page fetched
3710
+ * the file the `@font-face` names is not there. One page fetched
3712
3711
  * `/fonts/ionicons.woff`, got the index document, and the note printed the raw decode error
3713
3712
  * while the model went looking elsewhere.
3714
3713
  *
@@ -3745,7 +3744,7 @@ const HIDING_RULE = /(?:^|;)\s*(?:display\s*:\s*none|visibility\s*:\s*hidden)/;
3745
3744
  * The sentence a "hidden" visibility failure earns when the trace proved WHY the box is empty.
3746
3745
  *
3747
3746
  * Playwright calls an element with a zero-size box hidden even when it is painted, so the answer
3748
- * is in the element's children. `a.navbar-brand` on xr-molecule-flash-m197 was 0×4 px because its
3747
+ * is in the element's children. An `a.navbar-brand` was 0×4 px because its
3749
3748
  * only child was `<img src="/conduit-logo.svg" height="26">`: an SVG with a `viewBox` and no
3750
3749
  * width/height has no intrinsic size, and the `height` attribute loses to Tailwind's preflight
3751
3750
  * (`img { max-width: 100%; height: auto }`), which the scaffold's own `index.css` imports. The
@@ -3808,7 +3807,7 @@ function countMatchSentence(match) {
3808
3807
  * The row's sentence for a failing count assertion: the locator, both numbers, and the elements
3809
3808
  * the failure snapshot held.
3810
3809
  *
3811
- * xr-molecule-flash-m321's `comments.spec.ts:86` printed only `Expected: 3 / Received: 4`. The
3810
+ * A `comments.spec.ts:86` row printed only `Expected: 3 / Received: 4`. The
3812
3811
  * helper counted `.card:not(.comment-form) .card-block`, and the app's comment form was a
3813
3812
  * `.comment-form` wrapper around a plain `.card`, so the form's own `.card-block` was the fourth
3814
3813
  * match. The trace held the selector and the four elements; the note held neither.
@@ -3875,18 +3874,18 @@ export function countMismatchNote(items) {
3875
3874
  * a network error with Playwright's own text) is a cause. A request with NO RESPONSE RECORDED —
3876
3875
  * Playwright's `-1`, no error text — was still in flight when the test ended (the page closed under
3877
3876
  * it); listing it as a failure sent a run hunting an API that never answered anything wrong
3878
- * (xr-molecule-flash-m112 +30:45). The rest are the page's last answered requests.
3877
+ * The rest are the page's last answered requests.
3879
3878
  *
3880
3879
  * A 4xx request carries what the page SENT beside its status, so a wrapped body is visible in one
3881
3880
  * line rather than inferred from the status; when one of those bodies is an object whose only key
3882
- * is `data`, the note names the call shape that produces it (xr-molecule-flash-m111 +11:36).
3881
+ * is `data`, the note names the call shape that produces it.
3883
3882
  *
3884
3883
  * Every row opens with the test's LAST user action before the failing assertion and the requests
3885
3884
  * that action caused ({@link TraceArtifact.lastAction}) — started after it, before the assertion,
3886
3885
  * the app's own API calls first, each with its status and the first 200 characters of its response,
3887
3886
  * then where the page went next. The trace's action clock and each request's `_monotonicTime` are
3888
3887
  * the same clock, so "caused" is the trace's own fact rather than a guess from recording order.
3889
- * xr-molecule-flash-m148 failed 13 then 12 tests on one unnamed cause while every row led with
3888
+ * A run failed 13 then 12 tests on one unnamed cause while every row led with
3890
3889
  * `GET /api/tags → 200` — the Home page's own fetch after the redirect — and filled its answered
3891
3890
  * slots with the PWA's `/workbox-*.js` and its `/icons/*.svg`; the register `POST /api/users`
3892
3891
  * (answered 201, the page still rendering signed-out) never appeared. With no action clock, the
@@ -3895,7 +3894,7 @@ export function countMismatchNote(items) {
3895
3894
  * The action, the URL and the requests are the FAILING ASSERTION'S PAGE's ({@link
3896
3895
  * TraceArtifact.lastAction}), never the archive's last context: a test that creates its data in a
3897
3896
  * second browser context writes that context's click and `/editor` snapshot into the same zip, and
3898
- * reading the concatenation made them the failing page (xr-molecule-flash-m160). The other
3897
+ * reading the concatenation made them the failing page. The other
3899
3898
  * contexts' requests are named separately as set-up work. When the trace holds more than one used
3900
3899
  * context and the assertion's page cannot be identified, the note lists the requests and makes NO
3901
3900
  * causal claim — no "the test's last action", no "the page stayed at …" — instead of merging them.
@@ -3904,17 +3903,16 @@ export function countMismatchNote(items) {
3904
3903
  * trace holds both facts — the value typed into `textarea[name="bio"]` and the `PUT /api/user`
3905
3904
  * whose body carried `"bio": ""` — so the form's state was reset between the typing and the
3906
3905
  * submit. The note names the effect that re-seeds a form from data whose identity changed and the
3907
- * fix at the source (seed the form once). xr-molecule-flash-m173 lost a deploy-and-walk cycle to
3908
- * this on the deployed URL only, where the background session verification lands later than it
3909
- * does locally.
3906
+ * fix at the source (seed the form once). A deploy-and-walk cycle is lost to this on the
3907
+ * deployed URL only, where the background session verification lands later than it does locally.
3910
3908
  *
3911
3909
  * A write whose response said a boolean field is true and a LATER GET of the same resource that
3912
3910
  * said it is false leads the note first ({@link readContradictionSentence}): the read route never
3913
- * saw the viewer, so the fix is on that route's middleware, not in the page. xr-molecule-flash-m181
3914
- * spent ~8 minutes rewriting the profile component over exactly that pair — the write answered
3911
+ * saw the viewer, so the fix is on that route's middleware, not in the page. Rewriting the
3912
+ * profile component over exactly that pair costs ~8 minutes — the write answered
3915
3913
  * `{"following":true}` and the next profile GET answered `false`.
3916
3914
  *
3917
- * WHICH rows it spends is evidence, not artifact order (xr-molecule-flash-m112 +53:46): a row
3915
+ * WHICH rows it spends is evidence, not artifact order: a row
3918
3916
  * needs a recorded response, a real failure or a console line ({@link traceRowEvidence}), rows are
3919
3917
  * deduplicated by the test's location, and they are ordered real failure → repeated from an
3920
3918
  * earlier walk → the rest ({@link traceRowTier}). Without that the note spent all five rows on four
@@ -3923,21 +3921,21 @@ export function countMismatchNote(items) {
3923
3921
  *
3924
3922
  * A run whose every traced page never finished its navigation leads with the browser's own
3925
3923
  * transport error (`net::ERR_CONTENT_DECODING_FAILED` and friends) and the document it hit: nothing
3926
- * rendered, so no row below is app evidence (xr-molecule-flash-m118 +37:09).
3924
+ * rendered, so no row below is app evidence.
3927
3925
  *
3928
3926
  * When a navigation the runner reports as the failure never finished and one of the document's
3929
3927
  * own subresources (a stylesheet, a script, an asset under `/assets/`) never got a response either
3930
3928
  * — having started inside that wait — the request takes a row and the note says the page was
3931
3929
  * waiting on it. It is not an API call, but on a `page.goto` timeout it is the only request that
3932
3930
  * can explain the timeout — the deployed app was serving the page while one fetch stalled for 27 s
3933
- * (xr-molecule-flash-m135 +34:10). The page shell's incidental requests (`/sw.js`, the manifest, a
3934
- * favicon, a font) stay out, for m125's reason. An asset merely unfinished when a selector wait
3931
+ * The page shell's incidental requests (`/sw.js`, the manifest, a favicon, a font) stay out, for
3932
+ * the reason above. An asset merely unfinished when a selector wait
3935
3933
  * ran out the test budget, or one a teardown/`afterEach` trace holds, is not a cause: the note
3936
- * says it "had no recorded response when the test ended; that alone does not establish the cause"
3937
- * (xr-molecule-flash-m153 +13:43).
3934
+ * says it "had no recorded response when the test ended; that alone does not establish the
3935
+ * cause".
3938
3936
  *
3939
3937
  * A 404 whose path lacks the API prefix the app's own calls carry is called out with that prefix
3940
- * ({@link missingApiPrefixRequests}): xr-molecule-flash-m145 posted `/users` to `vite preview`,
3938
+ * ({@link missingApiPrefixRequests}): a page posted `/users` to `vite preview`,
3941
3939
  * whose 404 was answered by the static server because the HTTP client's `baseURL` was never set —
3942
3940
  * and the note printed "read the handler this route reaches in your own source", which presumes a
3943
3941
  * request that never reached the API. The prefix is READ (the caller passes what the app's client
@@ -3949,16 +3947,16 @@ export function countMismatchNote(items) {
3949
3947
  * credential exchange it answered 2xx, a request the client already attached a token to — and only
3950
3948
  * positive evidence may prescribe the client's token wiring; otherwise the sentence is
3951
3949
  * observational and, for a navigation failure, names the URL transition and the route guard
3952
- * (xr-molecule-flash-m221: a signed-out redirect test's `GET /api/articles/feed → 401` sent the
3953
- * model into replacing a working HTTP client, which lost the session token for ~28 minutes). The
3950
+ * (a signed-out redirect test's `GET /api/articles/feed → 401` sent the model into replacing a
3951
+ * working HTTP client, which lost the session token for ~28 minutes). The
3954
3952
  * handler sentence is kept for the rest — 404/422/500 — and dropped when every failure was a
3955
3953
  * credential refusal, because a trace that proves the header was never sent cannot be explained by
3956
- * the handler. xr-molecule-flash-m148 (+29:18) hit this exactly: six local walks read
3954
+ * the handler. Six local walks read
3957
3955
  * `POST …/favorite → 401 {"errors":{"token":["is missing"]}}` as a handler bug.
3958
3956
  *
3959
3957
  * A credential EXCHANGE (a login/registration/token endpoint, read from the app's auth config, the
3960
3958
  * path or the body) is never that shape: the request's purpose is to obtain a token, so an absent
3961
- * header is not a client omission ({@link isCredentialExchange}). xr-molecule-flash-m165's login
3959
+ * header is not a client omission ({@link isCredentialExchange}). A login
3962
3960
  * 401 was answered as one for 40 minutes; the trace also showed the suite's SET-UP traffic going
3963
3961
  * to `https://api.realworld.show/api` instead of this app, which is what the note leads with
3964
3962
  * ({@link foreignOriginApiRequests}).
@@ -4458,7 +4456,7 @@ const TRACE_SETTING = /trace:\s*(?:\{[^{}]*?mode:\s*)?['"]?(on-first-retry|on-al
4458
4456
  *
4459
4457
  * Only `on` and `retain-on-failure` keep a `trace.zip` for a failure whatever the retries do: the
4460
4458
  * two retry modes need a retry to happen at all, and a diagnosis run is given `--retries=0`
4461
- * (`streamingBackgroundCommand`), so on X1 xr-molecule-flash-m100 the run's own
4459
+ * (`streamingBackgroundCommand`), so a run's own
4462
4460
  * `trace: 'on-first-retry'` recorded nothing — which is what left the failing tests' network log
4463
4461
  * unreadable. A config that sets no `trace:` at all records nothing either (Playwright's default
4464
4462
  * is off); so does one that cannot be read.
@@ -4520,10 +4518,10 @@ function namesTraceMode(command) {
4520
4518
  * end of the whole command: a run Flash sends almost every time ends `… 2>&1 | tail -60` or
4521
4519
  * `… > log 2>&1; echo "exit=$?"; grep -c "" log`, and a flag appended after those is an operand of
4522
4520
  * `tail`/`grep` — GNU `tail` refuses it outright (`tail: option used in invalid context -- 6`) and
4523
- * Playwright never sees it (xr-molecule-flash-m102 +07:40 → +07:53). A step inside a subshell
4521
+ * Playwright never sees it. A step inside a subshell
4524
4522
  * (`( … playwright test … 2>&1)`) is the same rule the other way: a flag written after the `)`
4525
4523
  * closes the group before the shell has read the flag at all
4526
- * (`sh: Syntax error: word unexpected`, xr-molecule-flash-m129 +34:29).
4524
+ * (`sh: Syntax error: word unexpected`).
4527
4525
  *
4528
4526
  * The step and the offset are the package's own shell parse's answers
4529
4527
  * ({@link locatedCommandSegments}, {@link statementArgumentEnd}): the parse says which STATEMENT
@@ -4614,12 +4612,12 @@ async function readRunConfig(command, cwd, readFile) {
4614
4612
  *
4615
4613
  * A run that can serve as PROOF is the exception: the graded measurement is the suite's own
4616
4614
  * settings, so it keeps its own tracing and retries. That was measured, not assumed — on one
4617
- * sandbox in X1 xr-molecule-flash-h15 (+46:53 → +49:30) the same build ran a three-test deployed
4615
+ * sandbox the same build ran a three-test deployed
4618
4616
  * subset 3/3 timed out under this flag (17.6–17.9 s against a 15 s per-test budget) and the whole
4619
4617
  * file passed 14/14 without it (10.9–12.1 s). `retain-on-failure` RETAINS only a failing test's
4620
4618
  * trace (Playwright's `_shouldAbandonTrace` unlinks a passing test's), but it RECORDS every
4621
4619
  * action of every test, and for a test near its per-test budget that recording is the difference
4622
- * between passing and timing out. m163 (+24:58) is the failure this flag was added for: its
4620
+ * between passing and timing out. This flag was added for exactly that failure: its
4623
4621
  * deployed proof run left only an `error-context.md` because the suite traces
4624
4622
  * `on-first-retry` and the run had no retries. That need is met without the flag — the graded
4625
4623
  * deployed run keeps the suite's own retries, so a failing test leaves its retry's trace — and
package/dist/types.d.ts CHANGED
@@ -182,8 +182,8 @@ export interface ToolBuildConfig {
182
182
  * The test titles the person's request EXCLUDES by name (molecule-dev's `excludedTestTitles`),
183
183
  * asked when a finished suite run's cause note is built. Their failures are not causes to fix:
184
184
  * the note drops them, says so at the end, and inverts them out of the narrowed re-run it hands
185
- * over — a result must never name a test beside "it does not count" (xr-molecule-flash-m101
186
- * +12:00, where the executor spent a turn and an edit on the excluded test).
185
+ * over — a result must never name a test beside "it does not count" (an executor once spent a
186
+ * turn and an edit on the excluded test).
187
187
  *
188
188
  * A getter, not an array, because the request is read per turn while the tool set is built
189
189
  * once. Unset means no test is excluded.
@@ -196,8 +196,8 @@ export interface ToolBuildConfig {
196
196
  * `requiredRunSettings` — its mode, say), asked when the cause note composes a narrowed re-run
197
197
  * of a finished run's failures. A re-run composed from the executor's own command inherits what
198
198
  * that command set — and nothing it left out, so a run that measured the suite in `spa` handed
199
- * back a re-run that would measure `spa` again (xr-molecule-flash-m182 +12:06: the request names
200
- * `TEST_MODE=fullstack`, the run and its re-run both omitted it).
199
+ * back a re-run that would measure `spa` again (the request names `TEST_MODE=fullstack`, and
200
+ * both the run and its re-run omitted it).
201
201
  *
202
202
  * A getter, not an array: the request is read per turn while the tool set is built once, and
203
203
  * what the suite's own files read is the consumer's reading. Unset answers "nothing required".
@@ -229,7 +229,7 @@ export interface ToolBuildConfig {
229
229
  suiteBudget?: (command: string, cwd: string) => Promise<SuiteBudgetPin | null | undefined>;
230
230
  /**
231
231
  * A whole walk's duration in ms, as the consumer measured it. A suite run the executor detached
232
- * whose own `timeout` is shorter than this is lifted (m200); unset lifts only a bound no longer
232
+ * whose own `timeout` is shorter than this is lifted; unset lifts only a bound no longer
233
233
  * than this tool's ceiling.
234
234
  *
235
235
  * @param command - The suite command.