@molecule/api-ai-tools 1.14.4 → 1.14.5

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 +211 -184
  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
package/README.md CHANGED
@@ -3,7 +3,7 @@ AUTO-GENERATED — DO NOT EDIT THIS FILE.
3
3
  Generated by `mlcl sync-docs` from the package's src/index.ts JSDoc + mlcl/registry.json.
4
4
  Edits here are overwritten on the next commit (molecule's pre-commit hook regenerates).
5
5
  To change this document, edit the module-level JSDoc in src/index.ts.
6
- Generated: 2026-10-25T03:47:31.740Z
6
+ Generated: 2026-10-25T20:03:24.838Z
7
7
  -->
8
8
 
9
9
  # @molecule/api-ai-tools
@@ -64,7 +64,7 @@ A browser launch bound to a variable, proven to have no cleanup path.
64
64
 
65
65
  ```typescript
66
66
  interface BrowserProbeLeak {
67
- /** The variable the launched browser is bound to (`browser` in the m257 probe). */
67
+ /** The variable the launched browser is bound to (`browser` in the probe above). */
68
68
  readonly variable: string
69
69
  }
70
70
  ```
@@ -136,7 +136,7 @@ two things a caller that WRITES into a command needs. The platform composes a ru
136
136
  executor's own command in more than one place, and a value written for the runner belongs in
137
137
  the runner's own statement: `APP_BASE=https://… cd app && npx playwright test` sets the variable
138
138
  for `cd` alone, so the Playwright config falls back to the local app while the command line
139
- still names the deployed host (xr-molecule-flash-m103 +28:08).
139
+ still names the deployed host.
140
140
 
141
141
  ```typescript
142
142
  interface LocatedCommandSegment {
@@ -202,7 +202,7 @@ interface LocatedCommandSegment {
202
202
  * The file this statement sends its own output to (`> out.log`, `>> log`, `&> run.log`,
203
203
  * `| tee file`), or null. Only a redirect written at the command's own level counts: one
204
204
  * inside a `( … )` / `{ … }` group writes through that group, and one that feeds a heredoc's
205
- * file (`cat > cfg.ts <<'EOF'`) is writing a config (X1 flash-m44, flash-m136).
205
+ * file (`cat > cfg.ts <<'EOF'`) is writing a config.
206
206
  */
207
207
  redirectTarget: string | null
208
208
  }
@@ -252,7 +252,7 @@ interface CutRun {
252
252
  * ({@link commandCutRun}'s `budgetSeconds` is 0). A background run is bounded by what its own
253
253
  * command carries — so a `command-timeout` cut there is that prefix killing the walk, and the
254
254
  * executor must be told to drop the prefix, never to start the run in the background it is
255
- * already in (X1 xr-molecule-flash-m143 +24:45).
255
+ * already in.
256
256
  */
257
257
  background: boolean
258
258
  /**
@@ -277,12 +277,12 @@ interface CutRun {
277
277
  /**
278
278
  * The interpreter of an inline program that only touches local files (`python3`, `node`, …), or
279
279
  * null. Such a program is stopped by its short budget because it is stuck, never because the work
280
- * is slow, so the sentence must not send it to the background (xr-molecule-flash-m200 +03:45).
280
+ * is slow, so the sentence must not send it to the background.
281
281
  */
282
282
  inlineScript?: string | null
283
283
  /**
284
284
  * The variable a leaked standalone browser launch is bound to, when the command ran such a probe
285
- * and the cut reader could only classify it after the run (xr-molecule-flash-m257). A leaked
285
+ * and the cut reader could only classify it after the run. A leaked
286
286
  * handle is not a slow workload: the background is the one place it must not be sent, so the
287
287
  * sentence names the close instead.
288
288
  */
@@ -532,8 +532,7 @@ interface SuiteRunInFlight {
532
532
  target: string
533
533
  /**
534
534
  * Whether the command being judged STOPS this run before starting its own — a kill comes first,
535
- * so a run the command itself stops is not in the way (xr-molecule-flash-m87's
536
- * `kill 19408 … ; npx playwright test …`).
535
+ * so a run the command itself stops is not in the way (`kill 19408 … ; npx playwright test …`).
537
536
  */
538
537
  stoppedByCommand?: boolean
539
538
  }
@@ -638,7 +637,7 @@ interface TraceRequest {
638
637
  * What the page SENT, for a 4xx answered by the app's own API — bounded (see
639
638
  * {@link MAX_TRACED_BODY_CHARS}). A body wrapped as `{"data":{…}}` is visible here in one line:
640
639
  * app-http's verbs take the body as their second argument, so a helper that passes
641
- * `{ data: body }` there ships the wrapper (xr-molecule-flash-m111 +11:36).
640
+ * `{ data: body }` there ships the wrapper.
642
641
  */
643
642
  sent?: string
644
643
  /** What came back for that 4xx, bounded the same way — the API's own error body. */
@@ -662,7 +661,7 @@ interface TraceRequest {
662
661
  * A 401 cannot be read without this: the API's own body said
663
662
  * `{"errors":{"token":["is missing"]}}` while the note told the run to read the API handler,
664
663
  * when the header's absence proved the CLIENT never attached the token
665
- * (xr-molecule-flash-m148 +29:18). A header present moves the answer to the server: the API
664
+ * A header present moves the answer to the server: the API
666
665
  * refused a token it was sent.
667
666
  */
668
667
  sentAuthorization?: boolean
@@ -681,7 +680,7 @@ interface TraceRequest {
681
680
  /**
682
681
  * The trace member this request came from — the browser context Playwright numbered (`1`, `3`).
683
682
  * A test that opens a second browser context writes one trace member per context, and a test's
684
- * request is only evidence about the page it was made on (xr-molecule-flash-m160).
683
+ * request is only evidence about the page it was made on.
685
684
  */
686
685
  context?: string
687
686
  /** The page the request was made on, as the HAR entry's `pageref` records it. */
@@ -695,7 +694,7 @@ The test's LAST user action before the failing assertion, and the requests it ca
695
694
 
696
695
  An assertion after a navigation is not explained by the page's last call (`GET /api/tags` on
697
696
  whatever page the app redirected to); it is explained by what the action the test took sent and
698
- what came back (xr-molecule-flash-m148: 13 then 12 failing tests, every trace row leading with
697
+ what came back (13 then 12 failing tests, every trace row leading with
699
698
  `GET /api/tags → 200`, while the register `POST /api/users` and its answer — the fact that
700
699
  explains the signed-out page — was never shown).
701
700
 
@@ -741,7 +740,7 @@ interface TraceAction {
741
740
  /**
742
741
  * The selector a `fill`/`type`/`selectOption` acted on (`textarea[name="bio"]`), from the
743
742
  * trace's own params. Kept so the note can compare what the test typed with what the page
744
- * submitted (m173: the field it typed into was sent empty).
743
+ * submitted (a field typed into and sent empty).
745
744
  */
746
745
  selector?: string
747
746
  /**
@@ -759,7 +758,7 @@ two-context test opens for its own setup.
759
758
 
760
759
  Its actions and requests belong to a different page: a request it sent is not the failing
761
760
  action's effect, and the URL it left the page on is not where the assertion's page went
762
- (xr-molecule-flash-m160: the helper context created an article in an editor page while the
761
+ (the helper context created an article in an editor page while the
763
762
  primary page moved to the profile the assertion then failed on, and the note called the
764
763
  editor page the failing page).
765
764
 
@@ -784,13 +783,13 @@ The assertion's own error names the text (a `has-text(…)` / `getByText(…)` /
784
783
  argument), and the trace's network log holds the response that contained it. That pair is the
785
784
  whole diagnosis: the API returned the value and the page dropped it before rendering, so the cut
786
785
  is in the component that maps the response onto the list — not in the API, the route or the
787
- selector. xr-molecule-flash-m169 (+13:09) spent its fix rounds on the wrong component and on a
786
+ selector. One run spent its fix rounds on the wrong component and on a
788
787
  markup detail while `GET /api/tags` was returning the missing "trending" and `PopularTags`
789
- sliced the response to its first 20 entries (the m99 top-N class, in the frontend).
788
+ sliced the response to its first 20 entries (a top-N cut, in the frontend).
790
789
 
791
790
  The text must be a value the response held, never a substring of one: a whole JSON string or
792
791
  number value, or a word bounded by non-alphanumerics. A text of 2 characters or fewer, or one
793
- made of digits only, must be a whole JSON value. xr-molecule-flash-m208's pagination assertion
792
+ made of digits only, must be a whole JSON value. A pagination assertion
794
793
  waited for "2" and the raw substring hit `pag1792394785820` in a tags response, so the note led
795
794
  with a response that had nothing to do with the failure; when no response holds the text that
796
795
  way, the field is absent and the note leads with its next finding.
@@ -808,7 +807,7 @@ interface TraceMissingText {
808
807
  * of the collection that started after the last navigation, and the text is absent from the
809
808
  * page's own failure snapshot ({@link traceArtifactsScript}).
810
809
  *
811
- * Absent when the evidence is weaker — a creation POST carried the text (m194's button failure
810
+ * Absent when the evidence is weaker — a creation POST carried the text (a button failure
812
811
  * was not a missing article), the snapshot still showed it, or the trace recorded no clock —
813
812
  * and the note then says only that a response contained the text.
814
813
  */
@@ -821,7 +820,7 @@ interface TraceMissingText {
821
820
  A write the trace recorded answering a boolean field, and a LATER GET of the same resource
822
821
  answering the opposite for that field.
823
822
 
824
- This is the pair that reads as a frontend race and is not one: xr-molecule-flash-m181's follow
823
+ This is the pair that reads as a frontend race and is not one: a follow
825
824
  test sent `POST /api/profiles/:username/follow` and the API answered
826
825
  `{"profile":{…,"following":true}}`, then a `GET /api/profiles/:username` answered
827
826
  `{"profile":{…,"following":false}}` — the READ route never saw the viewer, so it hydrated
@@ -900,7 +899,7 @@ interface TraceCountMatch {
900
899
  text?: string
901
900
  /** Its ancestors, outermost first (`body > div.comment-form > div.card`), bounded. */
902
901
  path?: string
903
- /** True when a `<form>` is one of its ancestors — the m321 extra match's shape. */
902
+ /** True when a `<form>` is one of its ancestors — the shape of an extra form-internal match. */
904
903
  inForm?: true
905
904
  }
906
905
  ```
@@ -911,7 +910,7 @@ A failing assertion that compared a LOCATOR COUNT (`expect(await locator.count()
911
910
  `expect(locator).toHaveCount(n)`), with the locator the trace recorded and, when the failure
912
911
  snapshot can supply them, the elements it matched.
913
912
 
914
- xr-molecule-flash-m321's `comments.spec.ts:86` sat on `Expected: 3 / Received: 4` for ~30
913
+ A `comments.spec.ts:86` assertion sat on `Expected: 3 / Received: 4` for ~30
915
914
  minutes and three whole suite walks: the helper counted `.card:not(.comment-form) .card-block`,
916
915
  the app's comment form was a `.comment-form` wrapper around a plain `.card`, and the form's own
917
916
  `.card-block` made the fourth. The trace had the selector (its `Frame.queryCount` entry) and the
@@ -972,7 +971,7 @@ interface TraceArtifact {
972
971
  * action caused ({@link TraceArtifact.lastAction}), else — on a trace with no action clock — the
973
972
  * trace's LAST `fetch`/`xhr` in recording order, else its document. It leads the note's row when
974
973
  * {@link lastAction} is absent, because a click that changed nothing is explained by the request
975
- * the click sent and what came back — xr-molecule-flash-m135's Follow click sent
974
+ * the click sent and what came back — a Follow click sent
976
975
  * `DELETE /api/profiles/x/follow → 200` (its `following` state was stale) and the note listed only
977
976
  * the test's earlier, answered requests.
978
977
  *
@@ -992,7 +991,7 @@ interface TraceArtifact {
992
991
  *
993
992
  * A test that opens a second browser context writes one trace member per context, and the
994
993
  * archive does not order them by time: the last action of the concatenation may belong to the
995
- * helper's page while the assertion failed on another (xr-molecule-flash-m160). The action is
994
+ * helper's page while the assertion failed on another. The action is
996
995
  * therefore the failing page's own, and its `pageAfter` is that page's last frame snapshot.
997
996
  *
998
997
  * Absent on traces read before this field existed, on traces whose network entries recorded no
@@ -1012,13 +1011,13 @@ interface TraceArtifact {
1012
1011
  * True when the trace held more than one browser context and none of them could be tied to the
1013
1012
  * failing assertion's page. The note then makes no causal claim — no "the test's last action",
1014
1013
  * no "the page stayed at …" — rather than attributing one context's click and URL to another
1015
- * context's assertion (xr-molecule-flash-m160).
1014
+ * context's assertion.
1016
1015
  */
1017
1016
  unattributed?: true
1018
1017
  /**
1019
1018
  * The browser contexts the test opened BESIDES the failing assertion's page, with the app
1020
1019
  * requests each made. Kept apart so the note can name them as set-up work instead of printing
1021
- * their requests as the failing action's effects (xr-molecule-flash-m160).
1020
+ * their requests as the failing action's effects.
1022
1021
  *
1023
1022
  * Absent when the trace recorded one context only, when every other context made no request,
1024
1023
  * and on traces read before this field existed.
@@ -1027,8 +1026,7 @@ interface TraceArtifact {
1027
1026
  /**
1028
1027
  * The text the failing assertion waited for and a same-page API response carried, when the trace
1029
1028
  * recorded both. The note leads with it: the value reached the browser and the page did not
1030
- * render it, so the next read is where that response is mapped — never the API or the selector
1031
- * (xr-molecule-flash-m169).
1029
+ * render it, so the next read is where that response is mapped — never the API or the selector.
1032
1030
  *
1033
1031
  * Absent when the assertion waited for no text (a text-free selector, a strict-mode violation),
1034
1032
  * when no page-scoped `fetch`/`xhr` answered 2xx/3xx with the text in its body, and on traces
@@ -1037,7 +1035,8 @@ interface TraceArtifact {
1037
1035
  missingText?: TraceMissingText
1038
1036
  /**
1039
1037
  * A write's answer a later GET of the same resource contradicted — the read route does not see
1040
- * the viewer (xr-molecule-flash-m181's `following`). The note leads with it and sends the run at
1038
+ * the viewer (a `following` flag that reads as `false`). The note leads with it and sends the
1039
+ * run at
1041
1040
  * the route's middleware, not the page's state handling.
1042
1041
  *
1043
1042
  * Absent when no write and later read in the trace answered the same boolean field differently,
@@ -1048,19 +1047,19 @@ interface TraceArtifact {
1048
1047
  * A visibility failure whose locator RESOLVED into an empty box — Playwright's "hidden" — with
1049
1048
  * the element's children read from the failure snapshot ({@link TraceHiddenBox}). The note uses
1050
1049
  * it to name why the box is empty (an `<img>` with no CSS size, a textless element) instead of
1051
- * leaving the run to probe computed styles (xr-molecule-flash-m197).
1050
+ * leaving the run to probe computed styles.
1052
1051
  */
1053
1052
  hiddenBox?: TraceHiddenBox
1054
1053
  /**
1055
1054
  * A failing assertion that compared a locator count, with the locator the trace recorded and the
1056
1055
  * elements its failure snapshot matched ({@link TraceCountMismatch}). The row prints them, so a
1057
1056
  * count that is off by one names the extra element instead of leaving the run to probe for it
1058
- * (xr-molecule-flash-m321's 30-minute `Expected: 3 / Received: 4`).
1057
+ * (a 30-minute `Expected: 3 / Received: 4` hunt).
1059
1058
  */
1060
1059
  countMismatch?: TraceCountMismatch
1061
1060
  /**
1062
1061
  * The method+path groups this test's page sent {@link TRACE_NOTE_LOOP_REPEATS} times or more,
1063
- * most-repeated first — a render loop the note leads with (xr-molecule-flash-m215: 2,106
1062
+ * most-repeated first — a render loop the note leads with (2,106
1064
1063
  * `GET /api/articles/<slug>` in one test, printed as four identical `→ 200` lines). Counted over
1065
1064
  * every network entry of the failing page, not the capped {@link TraceArtifact.requests} list.
1066
1065
  *
@@ -1087,8 +1086,8 @@ interface TraceArtifact {
1087
1086
  What the runner's own report says about ONE failing test: where the test is declared, which
1088
1087
  Playwright call its failure names, and the per-test deadline the failure measured against.
1089
1088
 
1090
- A trace cannot tell a navigation that ran out of budget from a selector wait that did. On
1091
- xr-molecule-flash-m153 a 15 s `page.waitForSelector` timeout left a trace whose `Frame.goto`
1089
+ A trace cannot tell a navigation that ran out of budget from a selector wait that did. A 15 s
1090
+ `page.waitForSelector` timeout can leave a trace whose `Frame.goto`
1092
1091
  never finished (the test was cut off mid-navigation) with a `/src/components/*.tsx` module still
1093
1092
  pending when the context closed — and the note read that as an asset hang, then sent the run to
1094
1093
  re-run the same tests unchanged against the same dev server while the same result's
@@ -1136,7 +1135,7 @@ interface TraceRunReport {
1136
1135
  /**
1137
1136
  * The app source files whose code sends a repeated request, read by the caller from the
1138
1137
  * project (`app/src/**`) before this note is written. A loop's sentence names the component to
1139
- * read instead of leaving the run to search for it (xr-molecule-flash-m215's `Editor.tsx`).
1138
+ * read instead of leaving the run to search for it (the component's own file).
1140
1139
  * Empty when the caller could not read the app or no file states the path.
1141
1140
  */
1142
1141
  callSites?: readonly { method: string; path: string; file: string }[]
@@ -1357,8 +1356,8 @@ interface ToolBuildConfig {
1357
1356
  * The test titles the person's request EXCLUDES by name (molecule-dev's `excludedTestTitles`),
1358
1357
  * asked when a finished suite run's cause note is built. Their failures are not causes to fix:
1359
1358
  * the note drops them, says so at the end, and inverts them out of the narrowed re-run it hands
1360
- * over — a result must never name a test beside "it does not count" (xr-molecule-flash-m101
1361
- * +12:00, where the executor spent a turn and an edit on the excluded test).
1359
+ * over — a result must never name a test beside "it does not count" (an executor once spent a
1360
+ * turn and an edit on the excluded test).
1362
1361
  *
1363
1362
  * A getter, not an array, because the request is read per turn while the tool set is built
1364
1363
  * once. Unset means no test is excluded.
@@ -1372,8 +1371,8 @@ interface ToolBuildConfig {
1372
1371
  * `requiredRunSettings` — its mode, say), asked when the cause note composes a narrowed re-run
1373
1372
  * of a finished run's failures. A re-run composed from the executor's own command inherits what
1374
1373
  * that command set — and nothing it left out, so a run that measured the suite in `spa` handed
1375
- * back a re-run that would measure `spa` again (xr-molecule-flash-m182 +12:06: the request names
1376
- * `TEST_MODE=fullstack`, the run and its re-run both omitted it).
1374
+ * back a re-run that would measure `spa` again (the request names `TEST_MODE=fullstack`, and
1375
+ * both the run and its re-run omitted it).
1377
1376
  *
1378
1377
  * A getter, not an array: the request is read per turn while the tool set is built once, and
1379
1378
  * what the suite's own files read is the consumer's reading. Unset answers "nothing required".
@@ -1407,7 +1406,7 @@ interface ToolBuildConfig {
1407
1406
 
1408
1407
  /**
1409
1408
  * A whole walk's duration in ms, as the consumer measured it. A suite run the executor detached
1410
- * whose own `timeout` is shorter than this is lifted (m200); unset lifts only a bound no longer
1409
+ * whose own `timeout` is shorter than this is lifted; unset lifts only a bound no longer
1411
1410
  * than this tool's ceiling.
1412
1411
  *
1413
1412
  * @param command - The suite command.
@@ -1415,6 +1414,8 @@ interface ToolBuildConfig {
1415
1414
  * @returns The duration in ms, or null.
1416
1415
  */
1417
1416
  suiteRunMs?: (command: string, cwd: string) => Promise<number | null | undefined>
1417
+
1418
+ /** Post-write hook (e.g. auto-format via Prettier/ESLint). Called after every write_file/edit_file. */
1418
1419
  // … truncated — the full declaration is in node_modules/@molecule/api-ai-tools/dist/types.d.ts
1419
1420
  ```
1420
1421
 
@@ -1620,21 +1621,21 @@ interface FailureCause {
1620
1621
  * The suite's own per-test budget in ms, when the cause is the test-budget kill
1621
1622
  * (`Test timeout of 15000ms exceeded`). The signature normalizes the number away
1622
1623
  * ({@link normalizedSignature}) so equal causes group, and that number is the one fact that
1623
- * predicts a test spending its budget on a repeated action (xr-molecule-flash-m110 +20:44).
1624
+ * predicts a test spending its budget on a repeated action.
1624
1625
  */
1625
1626
  budgetMs?: number
1626
1627
  /**
1627
1628
  * The layer the failure came from ({@link classifyRunFailure}). A `connection` cause never
1628
1629
  * reached the app, so it is NOT a cause the app's code can fix: the note says to re-run it
1629
1630
  * once and read the app's log on a repeat, instead of sending a fix at a handler
1630
- * (xr-molecule-flash-m110 +18:42 rewrote a CORS middleware for a 20 s connection timeout).
1631
+ * (a CORS middleware was rewritten for a 20 s connection timeout).
1631
1632
  */
1632
1633
  kind: RunFailureKind
1633
1634
  /**
1634
1635
  * What the page itself showed at the moment of the failure, when the caller read it from
1635
1636
  * Playwright's `error-context.md` (the alert / error list). The failure's own error line names
1636
- * the symptom — `waitForURL` timed out — and never what the page was saying: xr-molecule-flash-
1637
- * m122 +23:39 grouped eight `waitForURL` timeouts under one line while the page snapshots named
1637
+ * the symptom — `waitForURL` timed out — and never what the page was saying: eight
1638
+ * `waitForURL` timeouts were grouped under one line while the page snapshots named
1638
1639
  * the cause (`email can't be blank`, `username can't be blank` — the settings form submitted
1639
1640
  * before its values had loaded). Attached to the cause so the fix needs no `cat` of the file.
1640
1641
  */
@@ -1915,8 +1916,8 @@ This is the reading a policy that asks "does this command run X" needs, and it i
1915
1916
  not a text match. The command-position parser already knows what runs and what is only quoted
1916
1917
  data ({@link commandSegments}), so a pattern never reads a `|` inside a quoted grep alternation
1917
1918
  as a pipeline: `grep -E "USER CALLS|ENV|BUTTON" app.log` prints log lines, and the `ENV` in
1918
- its pattern started nothing (X0 xr-molecule-flash-m331 blocked exactly that call as an
1919
- environment dump). What the shell DOES run stays visible through the same walk: a bare
1919
+ its pattern starts nothing — a text match would block exactly that call as an environment
1920
+ dump. What the shell DOES run stays visible through the same walk: a bare
1920
1921
  launcher (`ls | env`), a shell string (`bash -c 'env'`), a substitution
1921
1922
  (`echo "$(printenv)"`) and a nested one (`sh -c 'x; env'`) are all commands here.
1922
1923
 
@@ -1954,8 +1955,8 @@ A flag written "at the end of the command" is not the runner's: a statement can
1954
1955
  redirection (`… 2>&1`), and a statement can sit inside a group whose closer belongs to the
1955
1956
  shell, not to the words (`( … )`, `{ …; }`). Appending after that closer is a different shell
1956
1957
  word that the group has already closed — `… --config=x 2>&1) --reporter=list` is
1957
- `sh: Syntax error: word unexpected`, which killed a backgrounded walk at once and pushed the
1958
- model off the platform's runner shape (xr-molecule-flash-m129 +34:29). Write the option where
1958
+ `sh: Syntax error: word unexpected`, which kills a backgrounded walk at once and pushes the
1959
+ model off the platform's runner shape. Write the option where
1959
1960
  the program's own arguments end and the rest of the statement still parses:
1960
1961
  `… --config=x --reporter=list 2>&1)`.
1961
1962
 
@@ -1986,8 +1987,8 @@ adjacent closer to its last word because no separator comes between them: `( …
1986
1987
  parses its last stage as `tail` with the argument `-25)`. {@link LocatedCommandSegment.end}
1987
1988
  therefore says one past the `)`, and a caller cutting that stage out of the command takes the
1988
1989
  group's closer with it — the rewritten command is then `( … 2>&1`, which no shell parses
1989
- (xr-molecule-flash-m418 +23:31: a heredoc config plus a parenthesized Playwright pipeline came
1990
- back as `end of file unexpected` from the background runner).
1990
+ (a heredoc config plus a parenthesized Playwright pipeline came back as `end of file
1991
+ unexpected` from the background runner).
1991
1992
 
1992
1993
  The parse's own group depths answer which closers belong to an enclosing group: the depth a
1993
1994
  statement was written at is its first character's depth (an opener is recorded at the depth
@@ -2041,9 +2042,9 @@ largest bound that was lifted.
2041
2042
  The platform moves a run to the background precisely because its own bound cannot fit this
2042
2043
  tool's ceiling, and a background task has no ceiling — its wait is bounded by `wait_for_task`
2043
2044
  and the turn's deadline. The `timeout N` an executor wrote to fit the ceiling therefore keeps
2044
- killing the run at N in the background, where nothing needed it: X1 xr-molecule-flash-m143
2045
- (+24:45) wrote `timeout 280` for a 31-test walk, the tool backgrounded it, and the prefix stopped
2046
- the walk with no tally — then the cut sentence told the executor to "run it in the background",
2045
+ killing the run at N in the background, where nothing needed it: an executor wrote
2046
+ `timeout 280` for a 31-test walk, the tool backgrounded it, and the prefix stopped the walk
2047
+ with no tally — then the cut sentence told the executor to "run it in the background",
2047
2048
  which is where it already was.
2048
2049
 
2049
2050
  The wrapper is found by the same parse every other command reader uses ({@link commandStart}):
@@ -2136,7 +2137,7 @@ The exit code a finished suite run may report.
2136
2137
  The code in a background result is the code of the command's LAST pipeline stage. When a stage
2137
2138
  after the suite runner still consumes its output (`| tee run.log`, or a filter the platform could
2138
2139
  not prove output-only), that stage produced the code, not the run — and `… | grep … | tail -20`
2139
- exited 0 for a run with a failure in it (xr-molecule-flash-m101 +25:54). No code is reported
2140
+ can exit 0 for a run with a failure in it. No code is reported
2140
2141
  then: the log's own tally decides.
2141
2142
 
2142
2143
  The same reading covers a code of 0 beside a tally that names a failure: whatever ended the
@@ -2407,7 +2408,7 @@ A runner counts only where a shell would RUN it ({@link commandSegments}): the w
2407
2408
  position of a segment, after its wrapper prefixes. A runner named in an argument is not an
2408
2409
  invocation — `head -30 run-api-tests-hurl.sh` and `grep -n playwright e2e/README.md` name a
2409
2410
  file to read, and a `--list` written inside a file the command writes is not a flag anyone runs
2410
- with (flash-m81).
2411
+ with.
2411
2412
 
2412
2413
  A command that invokes no runner is NOT one of these (false): "the command runs no test" is
2413
2414
  then true for `ls`, which is not the question any caller is asking. The question is whether
@@ -2449,7 +2450,7 @@ function outputFilterAfterRunner(
2449
2450
 
2450
2451
  - `command` — The command as the executor sent it.
2451
2452
  - `runs` — Whether a segment is the runner this run is about (the caller knows its own kind: {@link CommandSegment.program} is the program, once wrapper words like `timeout 280` and `npx` are taken away).
2452
- - `occurrence` — Which runner invocation the output belongs to, 1-based. A command can run the same runner more than once (xr-molecule-flash-m170: the suite bare, then with `HOST=…`), and each invocation carries its OWN pipe; a reader judging the second walk must name the second walk's cut, never the first's.
2453
+ - `occurrence` — Which runner invocation the output belongs to, 1-based. A command can run the same runner more than once (the suite bare, then with `HOST=…`), and each invocation carries its OWN pipe; a reader judging the second walk must name the second walk's cut, never the first's.
2453
2454
 
2454
2455
  **Returns:** The filter and the unfiltered command, or null.
2455
2456
 
@@ -2725,7 +2726,7 @@ it already names one, or starts no Playwright run.
2725
2726
  The flag rides the same statement the runner does: a `cd`, an env prefix and a `timeout` before
2726
2727
  it are left exactly as they were, and so is everything chained after the run (`| tail -50`).
2727
2728
 
2728
- xr-molecule-flash-m113 (+19:09): the model's fix-round re-run dropped the
2729
+ A fix-round re-run dropped the
2729
2730
  `--config playwright.conduit.config.ts` both earlier runs had carried, so Playwright started with
2730
2731
  NO base URL and all 10 failures were `page.goto: Cannot navigate to invalid URL` — a failure list
2731
2732
  that says nothing about the app. The platform composes commands back to the executor too (the
@@ -2746,21 +2747,21 @@ function withSuiteConfig(command: string, config: string | null | undefined): st
2746
2747
  The whole-suite command made scoped to the tests it should re-run instead: the same
2747
2748
  invocation — same launcher, same settings — with the named `file:line`s in place of every
2748
2749
  positional selection the run carried (a spec file, a suite directory or a regex filter),
2749
- `--last-failed` dropped (it re-runs the tests that never ran too, X1 flash-m60) and
2750
+ `--last-failed` dropped (it re-runs the tests that never ran too) and
2750
2751
  `--retries=0` set (a re-run of a known failure does not need to pay for retries) — except the
2751
2752
  re-run of a run against a DEPLOYED URL, which keeps the suite's own retries and tracing
2752
2753
  (`options.suiteSettings`).
2753
2754
 
2754
2755
  The re-run keeps the run's `> <file>` redirect only in the sense of keeping its OUTPUT there:
2755
2756
  the target is rewritten to a fresh sibling ({@link redirectRunnerOutputsToFreshFiles}), so a
2756
- re-run never overwrites the log the run itself is the evidence for (xr-molecule-flash-m173) —
2757
- and the setup around the run keeps its own file writes untouched (xr-molecule-flash-m429). A
2757
+ re-run never overwrites the log the run itself is the evidence for —
2758
+ and the setup around the run keeps its own file writes untouched. A
2758
2759
  `tail`/`head`/`cat`/`grep` chained after the run that reads that exact log is shown the fresh
2759
- sibling instead, so the re-run displays the run it performed (xr-molecule-flash-o03).
2760
+ sibling instead, so the re-run displays the run it performed.
2760
2761
 
2761
2762
  `config` is the config the run was measured under ({@link withSuiteConfig}): the narrowed re-run
2762
2763
  carries it whenever the command itself does not, so a run that dropped `--config` cannot be
2763
- handed back a command with the same defect (xr-molecule-flash-m113: every failing test was
2764
+ handed back a command with the same defect (every failing test was
2764
2765
  `Cannot navigate to invalid URL` because the re-run loaded no base URL).
2765
2766
 
2766
2767
  ```typescript
@@ -2777,23 +2778,23 @@ function scopedRerunCommand(
2777
2778
 
2778
2779
  - `command` — The whole-suite run's command.
2779
2780
  - `locations` — The failing `file:line`s to re-run, as the run's own log printed them. A location the reporter printed relative to the runner's own directory (`../../fixtures/…`, which no absolute path contains) is resolved here ({@link playwrightLocations}), so the command this returns is one Playwright can match.
2780
- - `excluded` — The test titles the request carves out. They are inverted out (`--grep-invert`) so a re-run of the failing locations cannot report one of them again — xr-molecule-flash-m101 re-ran the whole 139-test suite and spent ~4 minutes to be told about a test the request had already said does not count.
2781
+ - `excluded` — The test titles the request carves out. They are inverted out (`--grep-invert`) so a re-run of the failing locations cannot report one of them again — a re-run of the whole 139-test suite spends ~4 minutes to be told about a test the request had already said does not count.
2781
2782
  - `config` — The config the run loaded, when the caller knows it; added when the command does not name one.
2782
2783
  - `cwd` — The directory `exec_command` was given, when it was; the base a location is resolved against when the command does not `cd` anywhere.
2783
- - `env` — The settings the REQUEST requires of the suite and this run left out ({@link withRunEnv}): the re-run carries them, so a re-run of a run measured in the wrong mode is not measured in that mode again (xr-molecule-flash-m182 +12:06).
2784
- - `options` — `suiteSettings` for the re-run of a run against a DEPLOYED URL: it keeps the suite's own retries and tracing instead of the diagnosis ones. The graded measurement is the suite's own settings, and a retry is what leaves a failing test's trace there; the platform's `--retries=0` and its `--trace=retain-on-failure` are both a stricter measurement than the one that was graded, and on X1 xr-molecule-flash-h15 the recording alone turned three budget-bound deployed tests into timeouts.
2784
+ - `env` — The settings the REQUEST requires of the suite and this run left out ({@link withRunEnv}): the re-run carries them, so a re-run of a run measured in the wrong mode is not measured in that mode again.
2785
+ - `options` — `suiteSettings` for the re-run of a run against a DEPLOYED URL: it keeps the suite's own retries and tracing instead of the diagnosis ones. The graded measurement is the suite's own settings, and a retry is what leaves a failing test's trace there; the platform's `--retries=0` and its `--trace=retain-on-failure` are both a stricter measurement than the one that was graded, and the recording alone turned three budget-bound deployed tests into timeouts.
2785
2786
 
2786
2787
  **Returns:** The scoped command, or the command unchanged when it runs no Playwright suite.
2787
2788
 
2788
2789
  #### `withRunEnv(command, settings)`
2789
2790
 
2790
2791
  The command with the request's required settings put in front of its RUN statement — the ONE
2791
- place every composed re-run gets them (xr-molecule-flash-m182).
2792
+ place every composed re-run gets them.
2792
2793
 
2793
2794
  The settings are written at the statement's own assignment offset, never in front of the whole
2794
2795
  command: a shell binds an assignment there to the statement's program, while one in front of the
2795
2796
  whole command is the environment of its FIRST statement alone (`APP_BASE=… cd app && npx
2796
- playwright test` sets the variable for `cd`; xr-molecule-flash-m103 +28:08). A name the command
2797
+ playwright test` sets the variable for `cd`). A name the command
2797
2798
  gives a different value is replaced, and one it already gives the required value is left as
2798
2799
  written. When the parse cannot place the statement (a run inside a nested `sh -c '…'`), the
2799
2800
  settings become `export`s, which no statement boundary can swallow.
@@ -2850,10 +2851,10 @@ disagree:
2850
2851
  ({@link ./utilities.js} `streamingBackgroundCommand`) — a diagnosis walks each failure once,
2851
2852
  while the run the suite is judged by keeps the suite's own retries; and
2852
2853
  - the platform's own notes (molecule-dev's `suite-cli-override.ts`), which must not tell the
2853
- executor to drop the `--retries=0` the platform itself has just added — the contradiction X1
2854
- flash-m74 and m75 filed, and m76 filed a third time.
2854
+ executor to drop the `--retries=0` the platform itself has just added — a contradiction
2855
+ filed three times.
2855
2856
 
2856
- Until xr-molecule-flash-m89 they were a regex and a predicate that only LOOKED alike, and the
2857
+ Until then they were a regex and a predicate that only LOOKED alike, and the
2857
2858
  gap was exactly the run the platform had asked for: its `testRunNote` says "run the whole suite
2858
2859
  once with `--max-failures=0`", and the rewriter read that cap flag as a capped diagnosis and
2859
2860
  stripped the suite's retries from the uncapped proof run that follows a deploy — the one run the
@@ -2936,11 +2937,10 @@ The command that stops a running background task, read from the sandbox's own pi
2936
2937
 
2937
2938
  THE one builder for it, so every note that hands the executor a way to stop a run hands over the
2938
2939
  same pid-only form: a `pkill -f <something>` matches the shell running it (its argv IS the
2939
- command), and `molecule-dev/api/src/ai/pattern-kill-guard.ts` holds exactly that — X1
2940
- xr-molecule-flash-m87's stuck note suggested `kill $(cat /tmp/<id>.pid) 2>/dev/null; pkill -f
2941
- <id>.sh`, which the platform's own guard then refused, and the same shape cost a refused call at
2942
- +21:57. The pid tree is the whole of what the pattern was for: the detached shell and every
2943
- process under it.
2940
+ command), and `molecule-dev/api/src/ai/pattern-kill-guard.ts` holds exactly that — a stuck note
2941
+ that suggested `kill $(cat /tmp/<id>.pid) 2>/dev/null; pkill -f <id>.sh` was refused by the
2942
+ platform's own guard, and the same shape costs a refused call every time. The pid tree is the
2943
+ whole of what the pattern was for: the detached shell and every process under it.
2944
2944
 
2945
2945
  ```typescript
2946
2946
  function taskStopCommand(backend: ExecutionBackend, taskId: string): Promise<string>
@@ -2956,8 +2956,8 @@ function taskStopCommand(backend: ExecutionBackend, taskId: string): Promise<str
2956
2956
  The steer attached to a SUCCESSFUL read of a package's built output. The ENOENT
2957
2957
  redirect below fires only when the read FAILS, so a model that knows the hoisted
2958
2958
  layout reads `node_modules/@molecule/<pkg>/dist/*.js` happily and never learns the
2959
- documented API is one call away (X0 flash-m70: 24 such reads in 57 s, no note on
2960
- any of them). Carried as `distNote` rather than merged into `note` so a host that
2959
+ documented API is one call away (24 such reads in 57 s, with no note on any of
2960
+ them). Carried as `distNote` rather than merged into `note` so a host that
2961
2961
  has read_molecule_doc (molecule-dev's cadence note, which also names the functions)
2962
2962
  can supersede it without string-matching.
2963
2963
 
@@ -2979,7 +2979,7 @@ The task id is the ownership: it is the handle `wait_for_task` returned, `/tmp/$
2979
2979
  the log this platform's launcher writes for it, and the redirect target is the file this
2980
2980
  process's own launch registered for that id — never a path parsed out of a command by the
2981
2981
  caller. A diagnosis that reads a running walk must not build a `/tmp` path of its own
2982
- (xr-molecule-flash-l07: the wait's DISPLAY was diagnosed as if it were the log).
2982
+ (a wait's DISPLAY gets diagnosed as if it were the log).
2983
2983
 
2984
2984
  ```typescript
2985
2985
  function registeredTaskLogCommand(taskId: string): string | null
@@ -3012,17 +3012,17 @@ when the path is not under `node_modules` or nothing is installed there.
3012
3012
 
3013
3013
  `node_modules` is not the project's code: nothing written there survives the
3014
3014
  next install, no deploy carries it, and a sandbox whose dependency tree is
3015
- shared (the pre-installed superset) breaks every other run through it. X0
3016
- xr-molecule-flash-m91 (+04:43) called `write_file` on
3017
- `node_modules/@molecule/api-resource-comment/dist/numbers.d.ts` while reading
3018
- the package's declarations and clobbered its runtime module a call later
3015
+ shared (the pre-installed superset) breaks every other run through it. A
3016
+ `write_file` on
3017
+ `node_modules/@molecule/api-resource-comment/dist/numbers.d.ts`, made while
3018
+ reading the package's declarations, clobbered its runtime module a call later
3019
3019
  (`module.exports = {}` over the ESM handler its own code imports) — the write
3020
3020
  answered `ok: true`, and 18 s went to noticing, `npm pack`-ing the package and
3021
3021
  putting the file back. Reading these files stays allowed (that is how the
3022
3022
  declarations above are read at all).
3023
3023
 
3024
3024
  What is protected is the INSTALL, not the spelling: the decision comes from
3025
- {@link InstalledPackageFacts}, never from the path alone (m106 above). Three
3025
+ {@link InstalledPackageFacts}, never from the path alone (see the symlink case above). Three
3026
3026
  things are the run's own to remove or replace —
3027
3027
 
3028
3028
  - a `node_modules` that is a SYMLINK: `rm`/`unlink` removes the link, never the
@@ -3032,6 +3032,7 @@ things are the run's own to remove or replace —
3032
3032
 
3033
3033
  A path INSIDE the link is still decided by what resolves there: a link into a
3034
3034
  real tree is refused, because removing or writing through it reaches the
3035
+ install.
3035
3036
 
3036
3037
  _(description truncated — read the full text in `node_modules/@molecule/api-ai-tools/dist/tools.d.ts`.)_
3037
3038
 
@@ -3125,7 +3126,7 @@ function isStaticAssetRequest(request: TraceRequest): boolean
3125
3126
  Whether a trace recorded a failed response or a request error other than cancellation.
3126
3127
 
3127
3128
  A 404 on a static asset is excepted: `/sw.js` and `/fonts/*` 404 on an app that never shipped
3128
- them, and naming one as a failure sent m125 into writing the caching worker it had asked about.
3129
+ them, and naming one as a failure sent a run into writing the caching worker it had asked about.
3129
3130
  A 5xx on an asset, or a network error, still counts. A request error alone does not locate
3130
3131
  the cause in the server: the browser or network may have rejected the request.
3131
3132
 
@@ -3141,7 +3142,7 @@ function failedRequest(request: TraceRequest): boolean
3141
3142
 
3142
3143
  Whether a trace recorded no response and no error other than cancellation. The request may
3143
3144
  have been pending or cancelled when recording ended; the trace does not establish whether
3144
- the endpoint stalled. A shell request is not evidence about the step (m125 +29:33).
3145
+ the endpoint stalled. A shell request is not evidence about the step.
3145
3146
 
3146
3147
  ```typescript
3147
3148
  function unansweredRequest(request: TraceRequest): boolean
@@ -3158,12 +3159,12 @@ other asset the page itself loads, with no response and no error text — still
3158
3159
  the navigation timed out.
3159
3160
 
3160
3161
  The page shell's own incidental requests (`/sw.js`, the manifest, a favicon, a font) are
3161
- excepted for the reason {@link isStaticAssetRequest} documents: m125's run was sent to write a
3162
- caching service worker by an aborted `/sw.js`. A pending `/assets/*.css` is different — the
3163
- navigation blocks on it, so it is the reason `page.goto` ran out of time rather than one of the
3164
- app's API calls (xr-molecule-flash-m135 +34:10: three deployed `page.goto` timeouts on tests that
3165
- pass locally, one 88 KB stylesheet fetch measured at 27 s, and the failing tests' traces each
3166
- held the never-answered CSS while the note said "the cause is in the page").
3162
+ excepted for the reason {@link isStaticAssetRequest} documents: an aborted `/sw.js` once sent a
3163
+ run to write a caching service worker. A pending `/assets/*.css` is different — the navigation
3164
+ blocks on it, so it is the reason `page.goto` ran out of time rather than one of the app's API
3165
+ calls (three deployed `page.goto` timeouts on tests that pass locally, one 88 KB stylesheet
3166
+ fetch measured at 27 s, and the failing tests' traces each holding the never-answered CSS while
3167
+ the note said "the cause is in the page").
3167
3168
 
3168
3169
  ```typescript
3169
3170
  function stalledDocumentSubresource(request: TraceRequest): boolean
@@ -3181,7 +3182,7 @@ endpoint — as opposed to a protected resource that presents one.
3181
3182
  This is the path half of {@link isCredentialExchange}, exported so a caller holding only a
3182
3183
  `METHOD path` reads the same classification: a Hurl failing entry says
3183
3184
  `POST /api/users/login` and nothing about the body, and the whole-suite note must not explain
3184
- a wrong-password login that answered 200 as a cookie-jar effect (xr-molecule-flash-m176).
3185
+ a wrong-password login that answered 200 as a cookie-jar effect.
3185
3186
 
3186
3187
  ```typescript
3187
3188
  function isCredentialExchangePath(path: string, authEndpoints?: readonly string[]): boolean
@@ -3197,7 +3198,7 @@ function isCredentialExchangePath(path: string, authEndpoints?: readonly string[
3197
3198
  The sentence a "hidden" visibility failure earns when the trace proved WHY the box is empty.
3198
3199
 
3199
3200
  Playwright calls an element with a zero-size box hidden even when it is painted, so the answer
3200
- is in the element's children. `a.navbar-brand` on xr-molecule-flash-m197 was 0×4 px because its
3201
+ is in the element's children. An `a.navbar-brand` was 0×4 px because its
3201
3202
  only child was `<img src="/conduit-logo.svg" height="26">`: an SVG with a `viewBox` and no
3202
3203
  width/height has no intrinsic size, and the `height` attribute loses to Tailwind's preflight
3203
3204
  (`img { max-width: 100%; height: auto }`), which the scaffold's own `index.css` imports. The
@@ -3217,7 +3218,7 @@ function hiddenBoxNote(items: readonly TraceArtifact[]): string | null
3217
3218
  The row's sentence for a failing count assertion: the locator, both numbers, and the elements
3218
3219
  the failure snapshot held.
3219
3220
 
3220
- xr-molecule-flash-m321's `comments.spec.ts:86` printed only `Expected: 3 / Received: 4`. The
3221
+ A `comments.spec.ts:86` row printed only `Expected: 3 / Received: 4`. The
3221
3222
  helper counted `.card:not(.comment-form) .card-block`, and the app's comment form was a
3222
3223
  `.comment-form` wrapper around a plain `.card`, so the form's own `.card-block` was the fourth
3223
3224
  match. The trace held the selector and the four elements; the note held neither.
@@ -3258,14 +3259,15 @@ The three kinds are kept apart, because they mean different things. A FAILED req
3258
3259
  a network error with Playwright's own text) is a cause. A request with NO RESPONSE RECORDED —
3259
3260
  Playwright's `-1`, no error text — was still in flight when the test ended (the page closed under
3260
3261
  it); listing it as a failure sent a run hunting an API that never answered anything wrong
3261
- (xr-molecule-flash-m112 +30:45). The rest are the page's last answered requests.
3262
+ The rest are the page's last answered requests.
3262
3263
 
3263
3264
  A 4xx request carries what the page SENT beside its status, so a wrapped body is visible in one
3264
3265
  line rather than inferred from the status; when one of those bodies is an object whose only key
3265
- is `data`, the note names the call shape that produces it (xr-molecule-flash-m111 +11:36).
3266
+ is `data`, the note names the call shape that produces it.
3266
3267
 
3267
3268
  Every row opens with the test's LAST user action before the failing assertion and the requests
3268
3269
  that action caused ({@link TraceArtifact.lastAction}) — started after it, before the assertion,
3270
+ the app's own API calls first, each with its status and the first 200 characters of its response,
3269
3271
 
3270
3272
  _(description truncated — read the full text in `node_modules/@molecule/api-ai-tools/dist/trace-artifacts.d.ts`.)_
3271
3273
 
@@ -3293,7 +3295,7 @@ Whether a Playwright config records traces for the tests that fail.
3293
3295
 
3294
3296
  Only `on` and `retain-on-failure` keep a `trace.zip` for a failure whatever the retries do: the
3295
3297
  two retry modes need a retry to happen at all, and a diagnosis run is given `--retries=0`
3296
- (`streamingBackgroundCommand`), so on X1 xr-molecule-flash-m100 the run's own
3298
+ (`streamingBackgroundCommand`), so a run's own
3297
3299
  `trace: 'on-first-retry'` recorded nothing — which is what left the failing tests' network log
3298
3300
  unreadable. A config that sets no `trace:` at all records nothing either (Playwright's default
3299
3301
  is off); so does one that cannot be read.
@@ -3332,14 +3334,15 @@ decide its own `--trace`, and whose config keeps no trace for its failures.
3332
3334
 
3333
3335
  A run that can serve as PROOF is the exception: the graded measurement is the suite's own
3334
3336
  settings, so it keeps its own tracing and retries. That was measured, not assumed — on one
3335
- sandbox in X1 xr-molecule-flash-h15 (+46:53 → +49:30) the same build ran a three-test deployed
3337
+ sandbox the same build ran a three-test deployed
3336
3338
  subset 3/3 timed out under this flag (17.6–17.9 s against a 15 s per-test budget) and the whole
3337
3339
  file passed 14/14 without it (10.9–12.1 s). `retain-on-failure` RETAINS only a failing test's
3338
3340
  trace (Playwright's `_shouldAbandonTrace` unlinks a passing test's), but it RECORDS every
3339
3341
  action of every test, and for a test near its per-test budget that recording is the difference
3340
- between passing and timing out. m163 (+24:58) is the failure this flag was added for: its
3342
+ between passing and timing out. This flag was added for exactly that failure: its
3341
3343
  deployed proof run left only an `error-context.md` because the suite traces
3342
3344
  `on-first-retry` and the run had no retries. That need is met without the flag — the graded
3345
+ deployed run keeps the suite's own retries, so a failing test leaves its retry's trace — and
3343
3346
 
3344
3347
  _(description truncated — read the full text in `node_modules/@molecule/api-ai-tools/dist/trace-artifacts.d.ts`.)_
3345
3348
 
@@ -3543,7 +3546,7 @@ function outputIsWithheldUntilExit(command: string): boolean
3543
3546
  The file a command sends its own output to, when it redirects it (`> out.txt`,
3544
3547
  `>> log`, `&> run.log`, `| tee [-a] file`), or null. A background command that does
3545
3548
  this leaves its task log empty, so the log is the wrong place to look and an empty
3546
- log proves nothing (X1 flash-m29).
3549
+ log proves nothing.
3547
3550
 
3548
3551
  Which redirect counts is decided by the command's own shell structure, from the same
3549
3552
  parse every other command reader uses: a redirect written in a BACKGROUNDED statement
@@ -3551,7 +3554,7 @@ parse every other command reader uses: a redirect written in a BACKGROUNDED stat
3551
3554
  the command's. The platform's own preview launch is exactly that — the preview server is
3552
3555
  started with `>/tmp/mol-preview-4173.log 2>&1 &` inside the build/serve prelude, and the
3553
3556
  suite's foreground command follows it — so a reader that took the last `>` in the whole
3554
- text told a run its output went to the PREVIEW's log (X1 flash-m136 +18:31).
3557
+ text tells a run its output went to the PREVIEW's log.
3555
3558
 
3556
3559
  The target comes back without its shell quotes: `> '/tmp/x.log'` is `/tmp/x.log`, and
3557
3560
  the callers resolve a relative one against the command's cwd.
@@ -3569,7 +3572,7 @@ function outputRedirectTarget(command: string): string | null
3569
3572
  Rewrite a command about to run in the background so its log grows while it
3570
3573
  runs. Two shapes left the log empty until exit, and an empty log is what
3571
3574
  `wait_for_task` reads as "stuck", so working suites were reported stuck and
3572
- killed (X1 run flash-m15 lost 20 of its 60 minutes this way, 2026-10-15):
3575
+ killed (one run lost 20 of its 60 minutes this way):
3573
3576
 
3574
3577
  - a trailing `| tail -N`, which holds everything back until the command ends.
3575
3578
  It is dropped: `wait_for_task` already returns the end of the log.
@@ -3577,7 +3580,7 @@ killed (X1 run flash-m15 lost 20 of its 60 minutes this way, 2026-10-15):
3577
3580
  failing test's own error and leaves the pipeline's exit status — the filter's — as the run's.
3578
3581
  Every such stage is dropped from EVERY suite run in the command, not only the last
3579
3582
  ({@link stripTrailingSuiteFilters}); `wait_for_task` already returns the end of the full log,
3580
- and a run whose tally shows a failure must never report 0 (xr-molecule-flash-m101 +25:54).
3583
+ and a run whose tally shows a failure must never report 0.
3581
3584
  - `playwright test` with no `--reporter`, which runs the config's reporter —
3582
3585
  often `html`, which prints nothing per test. `--reporter=list` is added
3583
3586
  when the playwright run is the command's last step, piped or not: it writes each result as
@@ -3598,7 +3601,7 @@ function streamingBackgroundCommand(
3598
3601
  ```
3599
3602
 
3600
3603
  - `command` — The command as the executor sent it.
3601
- - `context` — What the caller knows beyond the command: the tests the person's request excludes by name, and whether this command IS the platform's graded proof ({@link DiagnosisRunContext}). A `--grep-invert` of exactly those exclusions is the request's own scope, not a diagnosis, so it keeps the suite's retries on a deployed proof (xr-molecule-flash-m170 +33:16) — and a proof the platform itself composed and launched keeps them whatever its scope, targeted set included (xr-molecule-flash-l48 +26:35).
3604
+ - `context` — What the caller knows beyond the command: the tests the person's request excludes by name, and whether this command IS the platform's graded proof ({@link DiagnosisRunContext}). A `--grep-invert` of exactly those exclusions is the request's own scope, not a diagnosis, so it keeps the suite's retries on a deployed proof — and a proof the platform itself composed and launched keeps them whatever its scope, targeted set included.
3602
3605
  - `reportPath` — Where this run should write Playwright's standard `json` report, when the caller keeps one ({@link ./playwright-report.js}). The reporter is added to the run's own reporter set, never in place of one, and its output goes to that file through `PLAYWRIGHT_JSON_OUTPUT_FILE` — so the log, the executors' own reporters and every verdict stay exactly as they are. Omitted, or a run whose reporter set is not this function's to place (already names `json`, sets the variable itself, or whose runner cannot be located), leaves the command untouched and the result's `reportPath` unset.
3603
3606
 
3604
3607
  **Returns:** The command to run, one sentence per change made (empty when none), and the report path when one was actually wired — or `error` when the command starts the suite more than once.
@@ -3670,7 +3673,7 @@ function isSuiteRunCommand(command: string): boolean
3670
3673
  Refuse only a command made entirely of identical suite invocations.
3671
3674
 
3672
3675
  Mixed shell commands execute as written. Rebuilding their prefix or suffix can lose writes,
3673
- break heredoc delimiters or turn an && guard into unconditional work (m277). Different args
3676
+ break heredoc delimiters or turn an && guard into unconditional work. Different args
3674
3677
  or environments may select different suites or targets; they are not known duplicates either.
3675
3678
  This is an optimization, so uncertainty always allows the original command.
3676
3679
 
@@ -3688,8 +3691,8 @@ A command with the supplied suite's own settings written back onto its runner as
3688
3691
  flags, and the flags that could not be placed.
3689
3692
 
3690
3693
  The grader walks the suite under its OWN budget, so a run whose runner config sets a different
3691
- timeout or worker count measures a run the grader never sees (xr-molecule-flash-m169: a 60 s
3692
- wrapper config produced a green local proof the official 15 s grader then failed). Playwright
3694
+ timeout or worker count measures a run the grader never sees (a 60 s wrapper config produced
3695
+ a green local proof the official 15 s grader then failed). Playwright
3693
3696
  lets a command-line flag win over every config file, so the suite's values are put on the
3694
3697
  runner's own arguments — written where {@link statementArgumentEnd} places them, never after a
3695
3698
  pipe, redirect or group closer. Only the command's LAST suite step is touched: that is the run
@@ -3747,7 +3750,7 @@ bound that was lifted.
3747
3750
  Used where the platform moves a run to the background: the executor wrote the bound to fit this
3748
3751
  tool's foreground ceiling, and in the background that ceiling no longer applies — the task is
3749
3752
  bounded by `wait_for_task` and the turn's deadline — so the prefix only kills the walk
3750
- ({@link withoutTimeoutWrapper}; X1 xr-molecule-flash-m143 +24:45).
3753
+ ({@link withoutTimeoutWrapper}).
3751
3754
 
3752
3755
  ```typescript
3753
3756
  function withoutSuiteTimeout(command: string): { command: string; seconds: number | null }
@@ -3763,7 +3766,7 @@ Whether a command starts a Playwright run — a `playwright test` in command pos
3763
3766
  that runs something.
3764
3767
 
3765
3768
  `npx playwright test --list` matched every `\bplaywright\s+test\b` test in the platform and was
3766
- then treated as a run: held (flash-m79's config check), backgrounded for a run that outlasts
3769
+ then treated as a run: held (a config check), backgrounded for a run that outlasts
3767
3770
  the tool's ceiling, and rewritten with `--reporter`. A list takes two seconds, prints its lines
3768
3771
  and exits, so it is none of those; {@link commandRunsNoTests} is what decides.
3769
3772
 
@@ -3799,8 +3802,8 @@ Where the suite runner's exit code comes from: the runner itself, or a stage pip
3799
3802
  code a finished run reports is its LAST pipeline stage's, so a stage after the runner makes the
3800
3803
  code the stage's — but only when such a stage EXISTS. The platform used to report "piped" for
3801
3804
  any run whose statements it could not place in the text, which one heredoc body was enough to
3802
- cause: on X1 xr-molecule-flash-m105 (+08:12) a config written in the same `exec_command` made
3803
- the run come back with no exit code at all, and the note under it claimed a stage after the
3805
+ cause: a config written in the same `exec_command` made the run come back with no exit code
3806
+ at all, and the note under it claimed a stage after the
3804
3807
  runner that was not there. The parse now places every statement (`locatedCommandSegments`), so
3805
3808
  "unplaced" is the rare, named case rather than a guess dressed as an answer.
3806
3809
 
@@ -3832,10 +3835,9 @@ Start a background suite run at lower CPU and IO priority, so the sandbox it
3832
3835
  shares with everything else stays responsive to what the executor does next.
3833
3836
 
3834
3837
  A whole-suite Playwright run saturates the one container the app's Vite
3835
- server, its API process and every other command also live in: on X1 flash-m75
3836
- the model backgrounded a 139-test run at +36:23 and the two-word shell
3837
- command it sent next — tick its plan file — returned nothing for 2 min 40 s,
3838
- measured on the chat payload and on the live-stream follower independently.
3838
+ server, its API process and every other command also live in: a backgrounded 139-test run
3839
+ has left the two-word shell command sent next — tick its plan file — returning nothing for
3840
+ 2 min 40 s, measured on the chat payload and on the live-stream follower independently.
3839
3841
  The backgrounding note is right that the executor should go do other work;
3840
3842
  what it cannot promise is that the sandbox will let it.
3841
3843
 
@@ -3866,8 +3868,8 @@ Check if a command is blocked for security reasons. Returns error message or nul
3866
3868
  The first check reads the commands the shell actually RUNS — the statements, a `sh -c`
3867
3869
  string's body, and every command substitution ({@link executedCommands}) — so a `|` inside a
3868
3870
  quoted grep alternation is data, not a pipeline: `grep -E "USER CALLS|ENV|BUTTON|passed|failed"
3869
- app.log` prints log lines, and the `ENV` in its pattern started nothing (X0
3870
- xr-molecule-flash-m331 blocked exactly that call as an environment dump, twice). What the
3871
+ app.log` prints log lines, and the `ENV` in its pattern starts nothing — a text
3872
+ match would block exactly that call as an environment dump, twice over. What the
3871
3873
  shell DOES run stays visible through the same walk: `ls | env`, `bash -c 'env'`,
3872
3874
  `echo "$(printenv)"` and a nested `sh -c 'x; env'` are all commands, and so is `env` itself
3873
3875
  when nothing follows it.
@@ -3901,8 +3903,7 @@ Whether a tool path points outside the project root once normalized (an
3901
3903
  absolute path elsewhere, or a `..` that climbs out). {@link resolvePath}
3902
3904
  clamps such a path to the root; a file tool must refuse it instead of
3903
3905
  answering about the root — a `list_files /tmp/x` used to return the
3904
- workspace listing as if it were `/tmp/x` (X1 runs sonnet-m17 and sol-m05,
3905
- 2026-10-14).
3906
+ workspace listing as if it were `/tmp/x`.
3906
3907
 
3907
3908
  ```typescript
3908
3909
  function isOutsideRoot(path: string, projectRoot: string): boolean
@@ -3913,6 +3914,34 @@ function isOutsideRoot(path: string, projectRoot: string): boolean
3913
3914
 
3914
3915
  **Returns:** True when the path leaves the root.
3915
3916
 
3917
+ #### `commandStartsWithCdInto(command, directory, projectRoot)`
3918
+
3919
+ Whether a command's FIRST statement already changes into `directory`.
3920
+
3921
+ `exec_command` refuses a `cwd` outside the workspace, and that refusal tells
3922
+ the caller to drop `cwd` and start the command with `cd <path> && `. When the
3923
+ command ALREADY starts that way the advice describes what was just sent, so
3924
+ the command runs as written with the backend's working directory at the root
3925
+ instead (`{cwd: "/tmp", command: "cd /tmp && …"}` was refused with "start the command with
3926
+ `cd /tmp && `"; the same command resent with `cwd: "/workspace"` then passes).
3927
+
3928
+ Only the leading statement counts, only when the shell's own parse puts it in
3929
+ the caller's shell — a `( cd … )` group or a `sh -c '…'` runs in its own
3930
+ directory and moves nothing — and only when it ends the way a following
3931
+ command needs (`&&`, `;`, a newline, or nothing after it). `cd … | cat` is a
3932
+ pipeline, so its `cd` runs in a subshell, and `&` backgrounds it: neither
3933
+ leaves the caller's directory changed.
3934
+
3935
+ ```typescript
3936
+ function commandStartsWithCdInto(command: string, directory: string, projectRoot: string): boolean
3937
+ ```
3938
+
3939
+ - `command` — The shell command as the tool received it.
3940
+ - `directory` — The `cwd` the caller asked for.
3941
+ - `projectRoot` — The project root a relative path is resolved against.
3942
+
3943
+ **Returns:** True when the command's first statement `cd`s into `directory`.
3944
+
3916
3945
  #### `isValidGlob(pattern)`
3917
3946
 
3918
3947
  Validate that a glob/include pattern is safe (no shell metacharacters that could
@@ -3943,8 +3972,8 @@ expanded pattern.
3943
3972
  Neither search tool expands braces itself: `grep --include` and `find` take
3944
3973
  the pattern as a single shell-quoted argument, so no shell ever sees it.
3945
3974
  `find_files {pattern:"*.{ts,tsx}"}` and `search_files {include:"*.{ts,tsx}"}`
3946
- were both refused outright (xr-molecule-flash-m199 and m189), costing a round
3947
- trip and pushing the agent to a narrower search. The group is expanded here
3975
+ were both refused outright, costing a round trip and pushing the agent to a narrower
3976
+ search. The group is expanded here
3948
3977
  instead — `search_files` passes one `--include` per alternative and
3949
3978
  `find_files` ORs one `-name`/`-path` predicate per alternative.
3950
3979
 
@@ -3967,8 +3996,8 @@ The `find` predicate for a `find_files` pattern.
3967
3996
 
3968
3997
  `find -name` compares a pattern against a file's BASENAME, so a pattern
3969
3998
  containing a slash (`helpers/*`, `e2e/*.spec.ts`, `src` + `**` + `/App.tsx`)
3970
- can never match and the tool answers `[]` (xr-molecule-flash-m77, on two
3971
- calls in one run). Such a pattern is matched with `-path` instead: an fnmatch
3999
+ can never match and the tool answers `[]` (twice in one run). Such a pattern is matched
4000
+ with `-path` instead: an fnmatch
3972
4001
  glob over the whole printed path, whose `*` crosses `/` — the rule
3973
4002
  `.gitignore` uses, and the reason a bare `helpers/*` means "a `helpers/`
3974
4003
  directory anywhere below the root". The pattern is anchored with a leading
@@ -4019,14 +4048,14 @@ anchor ({@link findPatternArgs}), so `find` visits every entry below the
4019
4048
  search root. Handed `/workspace/node_modules` and
4020
4049
  `@molecule/api-resource-user/dist/*.d.ts` — a directory named outright —
4021
4050
  `find` walked the sandbox's entire dependency tree and hit the tool's 10 s
4022
- deadline without printing a result (xr-molecule-flash-m94: the one directory
4023
- the model meant answered a `list_files` in 0 s). The literal prefix is that
4051
+ deadline without printing a result (the one directory the model meant answered a `list_files`
4052
+ in 0 s). The literal prefix is that
4024
4053
  directory, and rooting the search at it is what keeps the call instant.
4025
4054
 
4026
4055
  A BARE first segment (`helpers/*`, `bonds/*`, `e2e/*.spec.ts`) is NOT one:
4027
4056
  `helpers/*` means "a `helpers/` directory anywhere below the root", which the
4028
- tool documents and a live run relied on (xr-molecule-flash-m77 — a path
4029
- pattern is not anchored to one depth). Rooting those at
4057
+ tool documents and a live run relied on (a path pattern is not anchored to one depth).
4058
+ Rooting those at
4030
4059
  `<root>/helpers` would answer with a SUBSET, silently: the nested
4031
4060
  `api/src/helpers/` matches would disappear, and a missing file reads as
4032
4061
  "no such file". So a prefix is returned only when it names a path of two or
@@ -4055,7 +4084,7 @@ The E2B SDK answers a timed-out `exec` with its generic text —
4055
4084
  `[deadline_exceeded] the operation timed out: … It can be modified by passing
4056
4085
  'timeoutMs' when making the request. Use '0' to disable the timeout.` — which
4057
4086
  names an option the executor cannot set and says nothing about the search
4058
- that died. Handing that sentence to the model is what xr-molecule-flash-m94
4087
+ that died. Handing that sentence to the model is what a run
4059
4088
  read after `find_files` spent 10 s walking `node_modules`; the tool answers
4060
4089
  the deadline in its own words instead (see {@link searchTimeoutError}).
4061
4090
 
@@ -4116,8 +4145,8 @@ shape a truncated provider stream leaves behind.
4116
4145
 
4117
4146
  The path message is the wrong reading of it: "requires a non-empty path
4118
4147
  argument" says the call was understood and the path was left out, so the model
4119
- retries the call it just made instead of sending the whole call again (x0
4120
- flash-m83 +29:32: `edit_file {}`, one round lost). An empty object and a
4148
+ retries the call it just made instead of sending the whole call again (`edit_file {}` loses
4149
+ one round). An empty object and a
4121
4150
  missing `path` are different failures and deserve different sentences.
4122
4151
 
4123
4152
  ```typescript
@@ -4282,9 +4311,8 @@ The shell command whose stdout is the interesting part of a log that is still be
4282
4311
  the failure lines so far (capped at {@link RUNNING_FAILURE_LINES}), then the end of the log.
4283
4312
 
4284
4313
  A Playwright `list` run prints one line per test as it finishes, so the LAST bytes of a running
4285
- log are its least informative part — in X1 flash-m61 the last 3 000 bytes of a 139-test walk
4286
- were the skip list, and all 61 failures were above them, which cost the run the grep it had to
4287
- make anyway. A background run also carries each failure's own error as it fails
4314
+ log are its least informative part — the last 3 000 bytes of a 139-test walk are the skip
4315
+ list, and all 61 failures were above them, which costs the run the grep it has to make anyway. A background run also carries each failure's own error as it fails
4288
4316
  ({@link PLAYWRIGHT_FAILURES_INLINE_ENV}), and {@link RUNNING_FAILURE_LINE_RE} already matches
4289
4317
  those blocks' headers and their `Error:` lines, so this slice shows the causes too.
4290
4318
 
@@ -4322,11 +4350,11 @@ function runningCauseCommand(log: string, own?: string): string
4322
4350
  The shell command whose stdout is a bounded CONTIGUOUS read of a running task's own log: the
4323
4351
  log's byte size, then its last {@link RUNNING_LOG_READ_BYTES} bytes.
4324
4352
 
4325
- {@link runningOutputSliceCommand} is the wrong read for a diagnosis, and l07 is the finding: it
4353
+ {@link runningOutputSliceCommand} is the wrong read for a diagnosis: it
4326
4354
  stitches the first 40 grep-selected failure lines to the last 1 000 bytes with a blank line
4327
4355
  between, so the tail is DISJOINT from the headers above it. Read as one log, the last numbered
4328
- header absorbs whatever the tail starts with — a clipped skipped-test title became the cause of
4329
- a genuine failure (xr-molecule-flash-l07). A contiguous window can only ever hold real
4356
+ header absorbs whatever the tail starts with — a clipped skipped-test title becomes the cause
4357
+ of a genuine failure. A contiguous window can only ever hold real
4330
4358
  neighbouring lines of one log.
4331
4359
 
4332
4360
  The size rides along so a caller can say when the window is only the log's end
@@ -4370,11 +4398,12 @@ log does NOT carry.
4370
4398
 
4371
4399
  Either way the point is the same: a suite whose failures repeat one cause spends its whole
4372
4400
  runtime proving that one cause, and the executor watching it can be told so at the third
4373
- failure instead of at the last. X1 flash-m76 walked 15 tests in 4.0 minutes where 15.6 s
4401
+ failure instead of at the last. Fifteen tests walked in 4.0 minutes where 15.6 s
4374
4402
  each was the test timeout and one missing `navigate('/')` was the cause of all of them.
4375
4403
 
4376
4404
  The quorum is of DISTINCT tests — {@link REPEATING_FAILURE_MIN} of them — because a log that
4377
- prints each failure twice (a second reporter, a retry) had X1 flash-m83 told that four of its
4405
+ prints each failure twice (a second reporter, a retry) has told a run that four of its
4406
+ tests failed the same way when two had, so the executor stopped a 139-test walk at test 21
4378
4407
 
4379
4408
  _(description truncated — read the full text in `node_modules/@molecule/api-ai-tools/dist/utilities.d.ts`.)_
4380
4409
 
@@ -4406,8 +4435,7 @@ is one the reporter printed inline.
4406
4435
  A body for a test the request EXCLUDES is not that evidence: its failure does not count for
4407
4436
  this request ({@link matchingExcludedTitles}), so a wait that handed it over as the diagnostic
4408
4437
  spent a model round trip and 8 k of partial log on a test the same result says to ignore —
4409
- exactly what xr-molecule-flash-h13 (+19:06) did twice while the platform's proof was still
4410
- walking.
4438
+ which a run has done twice while the platform's proof was still walking.
4411
4439
 
4412
4440
  With `finalOnly`, only a failure the run has FINISHED with counts; a pending retry waits.
4413
4441
 
@@ -4431,8 +4459,8 @@ How many test FILES a Playwright run's own command narrows it to, or null when i
4431
4459
  whole suite (or its selection cannot be read).
4432
4460
 
4433
4461
  {@link universalCause}'s file threshold is written for a whole-suite run, which a narrowed run
4434
- can never reach. xr-molecule-flash-m119 (+42:08) re-ran ONE spec file against a hand-started
4435
- `vite preview` the browser could not reach, and every test in it failed `page.goto: Timeout` —
4462
+ can never reach. A run that re-ran ONE spec file against a hand-started `vite preview` the
4463
+ browser could not reach had every test in it fail `page.goto: Timeout` —
4436
4464
  but one file is below {@link UNIVERSAL_CAUSE_FILES}, so the wait sat out its entire 280 s
4437
4465
  budget on a run that had already measured all it could.
4438
4466
 
@@ -4459,7 +4487,7 @@ The test is: the cause accounts for every failure the log names, it has hit the
4459
4487
  threshold, and nothing has passed since its first failure. The threshold is
4460
4488
  {@link UNIVERSAL_CAUSE_FILES} for a whole-suite run but the number of files the command
4461
4489
  SELECTED for a narrowed one ({@link specFilesSelected}): a one-file run can never span three,
4462
- and xr-molecule-flash-m119 (+42:08) waited out its whole budget on exactly that shape. An app
4490
+ and a run can wait out its whole budget on exactly that shape. An app
4463
4491
  that is not up, a 5xx on every request, or a selector that is missing on every page all look
4464
4492
  like that, and every remaining test will fail the same way — so the run's remaining minutes
4465
4493
  measure nothing. A CONNECTION-class cause ({@link CONNECTION_CAUSE}) needs no file span at all:
@@ -4468,8 +4496,8 @@ case however few files the run walks.
4468
4496
 
4469
4497
  Anything less is NOT this: a cause that stops at one file of a multi-file run, or that leaves
4470
4498
  other tests passing, or that shares the run with failures of another shape, leaves the run with
4471
- something to say, and the run is the only thing that will say it. X1 flash-m83 (2026-10-16)
4472
- stopped eight local runs at their first repeating cause over 14.5 minutes and never finished
4499
+ something to say, and the run is the only thing that will say it. Stopping runs at their first
4500
+ repeating cause has burned eight local runs over 14.5 minutes without finishing
4473
4501
  one; three of its deploys each fixed a single cause that a finished run would have listed
4474
4502
  alongside the others.
4475
4503
 
@@ -4498,16 +4526,17 @@ Both halves are load-bearing, each of them learned from a run that lost minutes
4498
4526
  spec-file threshold — {@link UNIVERSAL_CAUSE_FILES}, or the files a narrowed run's own
4499
4527
  command selects, or {@link CONNECTION_CAUSE_TESTS} tests of an app that never answered — with
4500
4528
  nothing passing since the first. That is the
4501
- dont-stop-runs rule. X1 flash-m83 (2026-10-16) stopped eight local runs at their first
4502
- repeating cause in 14.5 minutes and never finished one, and a run that still has other causes
4529
+ dont-stop-runs rule. Stopping runs at their first repeating cause has burned eight local
4530
+ runs in 14.5 minutes without finishing one, and a run that still has other causes
4503
4531
  left to name is the only thing that will name them.
4504
4532
  - **A PROVEN cause** is an error repeated VERBATIM. A shared DURATION is a LEAD, never a cause:
4505
4533
  a suite whose config sets a timeout spends that timeout on every failure that waits for
4506
4534
  anything, so three unrelated tests timing out together look exactly like one broken run
4507
- (`~7 s` is a property of the CONFIG, not of the cause — {@link normalizedSignature}). X1
4508
- xr-molecule-flash-m99 (2026-10-16) was told `status: 'repeating_failure'` twice on that
4535
+ (`~7 s` is a property of the CONFIG, not of the cause — {@link normalizedSignature}). A run
4536
+ told `status: 'repeating_failure'` twice on that
4509
4537
  shape — three `url-navigation.spec.ts` tests at ~16.2 s, one `timeout: 15_000` plus teardown
4510
4538
  — read the early return as "stop waiting, edit now", and voided a run that was still walking;
4539
+ the second cost a 224 s wait that ended with no result at all.
4511
4540
 
4512
4541
  _(description truncated — read the full text in `node_modules/@molecule/api-ai-tools/dist/utilities.d.ts`.)_
4513
4542
 
@@ -4532,12 +4561,11 @@ The request quotes a test's own title (`… except "should require login to post
4532
4561
  extracted by molecule-dev's `excludedTestTitles`) while a run's heading carries more of it
4533
4562
  (`comments.spec.ts › Comments › should require login to post comment`), so containment is the
4534
4563
  comparison. Whitespace is normalised and case is ignored: a brief may wrap the title across a
4535
- line (`xr-molecule-flash-m44`), and the reporter's own casing never has to match the brief's.
4564
+ line, and the reporter's own casing never has to match the brief's.
4536
4565
 
4537
4566
  Two readers used to answer this separately — the causes note (which therefore asked the
4538
4567
  executor to fix a test the same result said not to) and molecule-dev's exclusion notes — and
4539
- xr-molecule-flash-m101 paid for the gap (+12:00: a turn and an edit spent on the excluded
4540
- test).
4568
+ a run paid for the gap (a turn and an edit spent on the excluded test).
4541
4569
 
4542
4570
  ```typescript
4543
4571
  function matchingExcludedTitles(heading: string, excluded: readonly string[]): string[]
@@ -4555,7 +4583,7 @@ tests it hit.
4555
4583
 
4556
4584
  The point is that ONE run yields EVERY cause. A Playwright report prints its failures one
4557
4585
  after another with no statement of which of them share a cause, so a run of 19 failures is 19
4558
- bodies to read; X1 flash-m83 (2026-10-16) spent three deploys (6.7 minutes) each fixing a
4586
+ bodies to read; three deploys (6.7 minutes) each fixed a
4559
4587
  single cause, two of them found by runs stopped before they walked the rest.
4560
4588
 
4561
4589
  The signature is the cause itself where the log carries the failures' bodies (a finished run, a
@@ -4567,8 +4595,8 @@ proven cause. A test the log printed twice, or failed twice, is one test.
4567
4595
  A test the request EXCLUDES by name is not a cause to fix: its failure does not count for
4568
4596
  this request ({@link matchingExcludedTitles}), so it is dropped here rather than handed to the
4569
4597
  executor as work — a result that names it beside "it does not count" is the contradiction
4570
- xr-molecule-flash-m101 filed (+12:00: the model spent a turn and an edit on the excluded test,
4571
- on a page that was passing).
4598
+ a run filed (the model spent a turn and an edit on the excluded test, on a page that was
4599
+ passing).
4572
4600
 
4573
4601
  ```typescript
4574
4602
  function failuresByCause(log: string, excluded?: readonly string[]): FailureCause[]
@@ -4597,7 +4625,7 @@ function requiredLandmark(selector: string): RequiredLandmark | null
4597
4625
  The sentence for a run whose navigational elements are all missing from pages that otherwise
4598
4626
  painted — the missing shared header the executor must check BEFORE rewriting auth.
4599
4627
 
4600
- xr-molecule-flash-m193 (+13:54 → +20:00): four failures on `/` — `a[href="/profile/…"]`,
4628
+ A run had four failures on `/` — `a[href="/profile/…"]`,
4601
4629
  `a.navbar-brand`, `nav a[href="/"]`, `nav .user-pic` — while every `error-context.md` snapshot
4602
4630
  showed the feed, sidebar and footer with no navigation at all. `Home.tsx` imported and
4603
4631
  re-exported `Navbar` but never rendered it, and `App.tsx` mounted `<Home />` in a bare route.
@@ -4691,7 +4719,7 @@ function rerunOfRunningSuite(
4691
4719
  ): string | null
4692
4720
  ```
4693
4721
 
4694
- - `run` — The run in flight: the command it was started with, as it was run, the directory that command ran in, the config it loaded when the caller knows it, and the settings the request required and the run left out (`env`) — the re-run carries them, so it never reproduces the configuration the run was measured under by mistake (m182).
4722
+ - `run` — The run in flight: the command it was started with, as it was run, the directory that command ran in, the config it loaded when the caller knows it, and the settings the request required and the run left out (`env`) — the re-run carries them, so it never reproduces the configuration the run was measured under by mistake.
4695
4723
  - `locations` — The failing `file:line`s to re-run, as the run's log printed them.
4696
4724
  - `excluded` — The test titles the request carves out: the re-run inverts them out (`--grep-invert`) so it cannot report them again.
4697
4725
 
@@ -4708,17 +4736,18 @@ tests, so the note never names one or two tests as a cause.
4708
4736
  The note names the cause early so the executor can START FIXING while the run keeps walking,
4709
4737
  and it hands a stop command over only when {@link earlyReturnCause} says so — the SAME
4710
4738
  predicate the wait uses to decide whether to return early, so a finding the wait keeps waiting
4711
- on is a finding this note never asks to stop for. X1 flash-m76 (2026-10-16) spent 4.0 minutes
4739
+ on is a finding this note never asks to stop for. One run spent 4.0 minutes
4712
4740
  walking 15 tests whose one cause was certain at the third, 47 s in, and the note answers
4713
- exactly that; X1 flash-m83 then stopped eight runs at their first repeating cause in 14.5
4741
+ exactly that; another stopped eight runs at their first repeating cause in 14.5
4714
4742
  minutes and never finished one, so the note must not say to stop when the run still has other
4715
- causes to name. X1 xr-molecule-flash-m99 (2026-10-16) is the third shape: a shared duration is
4743
+ causes to name. The third shape: a shared duration is
4716
4744
  not a cause at all, so a lead reaches the executor as a note on a result it is still waiting
4717
4745
  for — never as a verdict with a stop command in it.
4718
4746
 
4719
4747
  The run is STILL WALKING while this note is written — both callers produce it mid-run — so a
4720
4748
  re-run of one of its tests is a second run against the same app and database, and the platform
4721
4749
  refuses that ({@link suiteRunInTheWay}, the same rule its overlap hold answers with):
4750
+ an executor read *"Start on them now, while the run keeps walking.
4722
4751
 
4723
4752
  _(description truncated — read the full text in `node_modules/@molecule/api-ai-tools/dist/utilities.d.ts`.)_
4724
4753
 
@@ -4920,7 +4949,7 @@ Python WSGI server. Matched against a command segment's own text, and against a
4920
4949
  when the command only names the script file — but NEVER against an inline program's code
4921
4950
  (`node -e …`, `python3 -c …`), where this text is the user's program rather than a file being
4922
4951
  run: `require('…/node_modules/vite')` imports a module, it does not start a dev server
4923
- (xr-molecule-flash-m391 +13:13, refused as "node starts a server" for exactly that line).
4952
+ (refused as "node starts a server" for exactly that line).
4924
4953
 
4925
4954
  ```typescript
4926
4955
  const SERVER_PROGRAM: RegExp
@@ -4974,14 +5003,13 @@ The closing advice on an over-budget message for a command that IS a suite run
4974
5003
  (Playwright, Vitest, a `hurl` run — {@link isSuiteRunCommand}): its files are not
4975
5004
  a bigger unit to break up.
4976
5005
 
4977
- X1 flash-m36 asked for this half and the message kept saying "run a smaller unit"
4978
- for two months. It is the wrong direction for a suite, and measurably: a run
4979
- stopped here reports NO tally, so nothing in the result says which test or request
4980
- hung — the run has to be sent again in the background (off this budget, its output
4981
- written to a log that can be read mid-run) or, when a consumer knows the runner's
4982
- per-request limit, with each request bounded. xr-molecule-flash-m93 (+06:22,
4983
- 2026-10-16) lost 4.8 minutes to a Hurl run whose ONE unanswered request had hurl's
4984
- 300 s default per request holding the file, ten seconds past this tool's budget.
5006
+ The wrong advice here is "run a smaller unit": it is the wrong direction for a
5007
+ suite, and measurably so — a run stopped here reports NO tally, so nothing in
5008
+ the result says which test or request hung. The run has to be sent again in the
5009
+ background (off this budget, its output written to a log that can be read
5010
+ mid-run) or, when a consumer knows the runner's per-request limit, with each
5011
+ request bounded. One Hurl run lost 4.8 minutes to a single unanswered request
5012
+ held by hurl's 300 s default per request, ten seconds past this tool's budget.
4985
5013
 
4986
5014
  ```typescript
4987
5015
  const SUITE_OVER_BUDGET_ADVICE: string
@@ -5048,7 +5076,7 @@ const MAX_TRACE_NOTE_REQUESTS: 4
5048
5076
 
5049
5077
  How many times ONE test may send the same method+path before the note calls it a render loop.
5050
5078
 
5051
- xr-molecule-flash-m215 (+27:27 → +29:42): an Editor effect with `[seeded, slug, t]` in its
5079
+ An Editor effect with `[seeded, slug, t]` in its
5052
5080
  dependency list re-fetched `GET /api/articles/<slug>` 2,106 times in one test. The trace reader
5053
5081
  caps and de-duplicates its request list, so the note printed four identical `→ 200` lines and
5054
5082
  the run patched the component's seeding, rebuilt and re-ran before unzipping the trace by hand.
@@ -5112,8 +5140,8 @@ reporter still prints each failure exactly once.
5112
5140
  Every background command is given this (see {@link streamingBackgroundCommand}), so a suite the
5113
5141
  executor starts through its own wrapper is covered too — the wrapper passes the environment on
5114
5142
  to the Playwright process it spawns. Without it the log's only failure lines are `✘` rows:
5115
- X1 xr-molecule-flash-m99 (+19:27 → +21:00, 2026-10-16) was told to `grep -n -A 20 '<test name>'`
5116
- the log, got nothing back through four greps, inferred causes from the spec prose instead, and
5143
+ A run told to `grep -n -A 20 '<test name>'` the log got nothing back through four greps,
5144
+ inferred causes from the spec prose instead, and
5117
5145
  edited `app/src` while the run was still walking — which voids the run.
5118
5146
 
5119
5147
  ```typescript
@@ -5198,9 +5226,8 @@ place, keeping ~30 KB of each end. A batched read that crossed it lost its
5198
5226
  MIDDLE — the cut lands between two `"content"` values, so whole files fell
5199
5227
  out and the note in their place said only "N characters cut here" — while
5200
5228
  this tool's own note had promised each of those files that it "fits in one
5201
- call, so it is not paged": X0 flash-m81 (2026-10-16) read ten e2e specs in
5202
- one call (121,467 chars), lost the middle six, and bought them again in six
5203
- further calls (52,908 chars).
5229
+ call, so it is not paged": one batched read of ten e2e specs (121,467 chars) lost the
5230
+ middle six and bought them again in six further calls (52,908 chars).
5204
5231
 
5205
5232
  So the CALL gets the ceiling the request gives it. Whole files are returned
5206
5233
  up to it; the paths that did not fit are named in `note` and listed in
@@ -5247,7 +5274,7 @@ const MAX_READ_RETURN_CHARS: number
5247
5274
 
5248
5275
  A file this small is returned whole on a second window of it (paging it costs a call each).
5249
5276
  The same bound as {@link MAX_READ_RETURN_CHARS}: the windowed-read note promises that a
5250
- file under it "fits in ONE call", and a smaller bound here broke that promise (X1 flash-m67).
5277
+ file under it "fits in ONE call", and a smaller bound here breaks that promise.
5251
5278
 
5252
5279
  ```typescript
5253
5280
  const SMALL_FILE_WHOLE_CHARS: number
@@ -5262,11 +5289,11 @@ an HTML read is almost never worth it.
5262
5289
  An entry document is boilerplate the reader rarely needs in full: meta tags,
5263
5290
  stylesheet and preload links, a `<style>` block, and a handful of `<script>`
5264
5291
  tags. The parts an executor acts on — the body's structure, where a script is
5265
- loaded — are all visible in an outline of one line per tag. X0 flash-m77 paid
5266
- 63,735 chars for one such read: ~60 KB of it was the IDE's own preview bridges,
5292
+ loaded — are all visible in an outline of one line per tag. One such read paid
5293
+ 63,735 chars: ~60 KB of it was the IDE's own preview bridges,
5267
5294
  and the read pushed the transcript past its context cap, so the e2e specs the
5268
5295
  executor had just read were trimmed to summaries and it read the whole suite
5269
- again — twice (findings, +01:23 and +02:56). The scaffold now keeps those
5296
+ again — twice. The scaffold now keeps those
5270
5297
  bridges in separate files, but a template's own head is still ~5-12 KB, and a
5271
5298
  static-site or SSR entry can be far more.
5272
5299
 
@@ -5396,8 +5423,8 @@ const TOOL_RESULT_CHARS: 8000
5396
5423
 
5397
5424
  #### `FAILURE_CAUSES_CHARS`
5398
5425
 
5399
- The characters a finished run's cause list may use of {@link TOOL_RESULT_CHARS}. The recap
5400
- measured by xr-molecule-flash-m102 (+12:43) was `12 failures, 8 causes`: one cause line is
5426
+ The characters a finished run's cause list may use of {@link TOOL_RESULT_CHARS}. A measured
5427
+ recap was `12 failures, 8 causes`: one cause line is
5401
5428
  ~200 chars and ~80 more with its two body lines, so 8 causes is ~2.3 k against the 8 k cap —
5402
5429
  the old 5-cause cap withheld 3 causes that the same result had room for.
5403
5430
 
@@ -5447,7 +5474,7 @@ How many tests a run must have walked — with nothing passing since its first f
5447
5474
  THREE, and the number is the cost of the alternative. The old floor of 15 was chosen when the
5448
5475
  reading was only offered at a completed run; once it STOPS the walk, every test waited for is
5449
5476
  a test whose result is thrown away, and a blank page costs its per-test budget each time
5450
- (m177: 18 tests, ~4.2 minutes, on a page whose thrown error was visible in the first
5477
+ (18 tests, ~4.2 minutes, on a page whose thrown error was visible in the first
5451
5478
  `pageerror`). Three is the smallest count that is not one page's own bug: the cause additionally
5452
5479
  needs three DISTINCT spec files (`UNIVERSAL_CAUSE_FILES`, or the files a narrowed run selected),
5453
5480
  no failure showing a locator RESOLVING ({@link ELEMENT_FOUND} — a blank page cannot resolve
@@ -5509,7 +5536,7 @@ Peer dependencies:
5509
5536
  ceiling the request side puts on a single tool result: whole files are
5510
5537
  returned up to it and every path past that is named in `note` and listed as
5511
5538
  `not returned`, so a file is never handed back in part — the shape that lost
5512
- the middle of a ten-file batch to the request-side cut (X0 flash-m81). Each
5539
+ the middle of a ten-file batch to the request-side cut. Each
5513
5540
  entry carries its own content or its own error, so one bad path never fails
5514
5541
  the batch.
5515
5542
  - **`edit_file` shows the result, so the model need not re-read.** A
@@ -5535,7 +5562,7 @@ Peer dependencies:
5535
5562
  added or removed and nothing else, the edit can only move text across lines —
5536
5563
  joining the next line onto the replaced text, or pushing the rest of the line
5537
5564
  down — which is what a weak model does by accident when it repeats a line it
5538
- means to keep (flash-m28, m55, m62, m89, five times in the m89 run alone). The
5565
+ means to keep. The
5539
5566
  replacement is skipped, the rest of the batch is applied, and the result
5540
5567
  carries `skippedNote`: one line naming the replacement, what applying it would
5541
5568
  have done, and how to say it on purpose (include the next line in `old_string`).