@orkestrel/scaffold 0.0.91 → 0.0.93

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 (42) hide show
  1. package/dist/agents/templates/brief.md +2 -0
  2. package/dist/bin/main.js +6 -6
  3. package/dist/bin/main.js.map +1 -1
  4. package/dist/host/AGENTS.md +2 -2
  5. package/dist/host/agents/orchestration.md +1 -1
  6. package/dist/host/agents/skills/enterprise-bootstrap/references/bootstrap-reference.md +4 -2
  7. package/dist/host/agents/skills/enterprise-bootstrap/references/responsive-layout.md +1 -1
  8. package/dist/host/agents/skills/enterprise-bootstrap/references/utilities.md +3 -3
  9. package/dist/host/agents/skills/orkestrel-falsify/SKILL.md +3 -3
  10. package/dist/host/agents/skills/orkestrel-journey/references/statechart.md +1 -1
  11. package/dist/host/agents/skills/orkestrel-publish/references/window.md +3 -4
  12. package/dist/host/agents/skills/orkestrel-scout/SKILL.md +1 -1
  13. package/dist/host/agents/templates/brief.md +2 -0
  14. package/dist/host/agents/transports/cursor.md +1 -1
  15. package/dist/host/claude/agents/analyst.md +1 -1
  16. package/dist/host/claude/agents/grok.md +1 -1
  17. package/dist/host/claude/agents/orkestrel.md +8 -8
  18. package/dist/host/claude/agents/planner.md +1 -1
  19. package/dist/host/claude/agents/researcher.md +1 -1
  20. package/dist/host/claude/agents/scout.md +1 -1
  21. package/dist/host/claude/rules/names.md +1 -1
  22. package/dist/host/claude/rules/patterns.md +1 -1
  23. package/dist/host/claude/rules/quality.md +11 -0
  24. package/dist/host/claude/rules/styles.md +5 -0
  25. package/dist/host/claude/rules/tests.md +7 -8
  26. package/dist/host/claude/rules/writing.md +2 -1
  27. package/dist/host/codex/agents/researcher.toml +2 -2
  28. package/dist/host/codex/agents/scout.toml +1 -1
  29. package/dist/host/dotfiles/oxlintrc.json +168 -0
  30. package/dist/host/guides/browser.md +483 -392
  31. package/dist/host/guides/mcp.md +15 -15
  32. package/dist/host/guides/pool.md +190 -69
  33. package/dist/host/guides/probe.md +262 -216
  34. package/dist/host/guides/router.md +1 -1
  35. package/dist/host/guides/worker.md +43 -7
  36. package/dist/host/manifest.json +34 -34
  37. package/dist/host/tests/config.test.ts +46 -3
  38. package/dist/src/core/index.cjs +6 -6
  39. package/dist/src/core/index.cjs.map +1 -1
  40. package/dist/src/core/index.js +6 -6
  41. package/dist/src/core/index.js.map +1 -1
  42. package/package.json +6 -6
@@ -82,7 +82,7 @@ A repair inside an existing file is never large by itself. A private retry, cach
82
82
  Within the size, in order:
83
83
 
84
84
  1. **Types.** Write or revise the contract in `*/types.ts`. Typecheck it.
85
- 2. **Prove.** Select the instrument per `.claude/rules/quality.md` § Instruments: a `prove` claim (edit, test, breaking edit, breaking stage) for a TypeScript claim, otherwise the smallest test or probe. Quote a `prove` closing line where the claim is reported. After two failed attempts to form a claim, write the test and continue.
85
+ 2. **Prove.** Select the instrument per `.claude/rules/quality.md` § Instruments: a `prove` claim (edit, test, breaking edit, breaking stage) for a TypeScript claim, otherwise the smallest test or probe. Quote a `prove` closing line where the claim is reported. When attempts to form a claim stop narrowing the question, write the test and continue.
86
86
  3. **Implement.** Conform to the types. Place each declaration in its kind file. Update the barrel.
87
87
  4. **Test.** Cover happy paths, edge cases, failures, and boundaries with deterministic tests against real implementations. For a defect, record the failing command and count before the fix and the same command green after.
88
88
  5. **Consolidate.** Remove duplication, nested functions, and superfluous wrappers without widening the API.
@@ -120,7 +120,7 @@ Each row is a normative extension of this file. Its `paths` frontmatter controls
120
120
  | `.claude/rules/portability.md` | Host branching, paths, line endings, processes, terminals, OS claims |
121
121
  | `.claude/rules/documentation.md` | Guides, parity, roadmap, showcase, examples, skill files |
122
122
  | `.claude/rules/writing.md` | Prose in guides, replies, commits, and instruction files |
123
- | `.claude/rules/quality.md` | Evidence, probes, instruments, research, completion |
123
+ | `.claude/rules/quality.md` | Evidence, probes, instruments, performance, research, completion |
124
124
 
125
125
  ## Writing
126
126
 
@@ -58,7 +58,7 @@ The harness's own engine orchestrates: Opus 5.5 in Claude Code, Astra in Codex,
58
58
 
59
59
  - Never run a review on a small change. Never run a second design round on the same brief.
60
60
  - A fix round re-audits the repaired claim only. A fix that adopted the reviewer's prescription verbatim closes with a mutation probe (disable the load-bearing line, watch the test fail, restore it). A fix that departs from it gets one pass by the other engine.
61
- - Three review rounds at one seam end the depth search. Name what the audit is for, dispatch one blind lens per station of the stream the defect moves along, locate the source, and plan from there.
61
+ - When review rounds at one seam keep surfacing defects without converging on their source, follow `.agents/skills/orkestrel-falsify/SKILL.md` § End the depth search.
62
62
  - An all-confirmed round ends the audit. A round needs an added or repaired claim to attack; reviewer appetite is not a subject.
63
63
 
64
64
  ## Campaign
@@ -294,7 +294,8 @@ $utilities: map-merge(
294
294
  values: auto pointer grab,
295
295
  ),
296
296
  // Modify an existing utility: make width responsive.
297
- 'width': map-merge(
297
+ 'width':
298
+ map-merge(
298
299
  map-get($utilities, 'width'),
299
300
  (
300
301
  responsive: true,
@@ -889,7 +890,8 @@ Bootstrap has **no** combobox/autocomplete, date picker, multi-select tags input
889
890
  $utilities: map-merge(
890
891
  $utilities,
891
892
  (
892
- 'width': map-merge(
893
+ 'width':
894
+ map-merge(
893
895
  map-get($utilities, 'width'),
894
896
  (
895
897
  responsive: true,
@@ -109,7 +109,7 @@ the component's own breakpoint class instead
109
109
  Recipes:
110
110
 
111
111
  - **Table scroller.** `<div class="table-responsive" role="region" aria-label="Invoices"
112
- tabindex="0">` — the shipped class is `overflow-x: auto` only; the name and `tabindex` make it
112
+ tabindex="0">` — the shipped class is `overflow-x: auto` only; the name and `tabindex` make it
113
113
  keyboard-reachable. `table-responsive-{bp}` scrolls only below the breakpoint.
114
114
  - **Menus in a scroller.** A scroller clips its `dropdown-menu`. Add
115
115
  `data-bs-popper-config='{"strategy":"fixed"}'` to the toggle, or open row actions in a
@@ -362,7 +362,7 @@ Helpers are single-purpose classes that sit alongside utilities.
362
362
  Protect titles or marks that must retain height with `flex-shrink-0`. Do not add `overflow-hidden`
363
363
  to an ancestor to conceal a layout bug; it can clip menus and focus rings.
364
364
  - **Toolbars:** start with `d-grid gap-2` or labelled `row g-2` controls; expand with `d-sm-flex
365
- flex-sm-wrap` or `col-md-auto` only when the container fits. Do not default to a horizontal
365
+ flex-sm-wrap` or `col-md-auto` only when the container fits. Do not default to a horizontal
366
366
  scroller for search or primary actions. Keep matching control sizes and usable hit areas. Align equal-height
367
367
  cards only where their content benefits, not to fill empty space.
368
368
  - **Responsive content:** follow [responsive-layout.md](responsive-layout.md); unprefixed utilities define the complete narrow task. A class that resolves can still implement the wrong layout. Reflow and prioritize before truncating. Hide a button caption only when
@@ -397,10 +397,10 @@ flex-sm-wrap` or `col-md-auto` only when the container fits. Do not default to a
397
397
  take `object-fit-contain` when the whole asset matters. Guard a user upload against bleeding into
398
398
  a same-color surface with `border border-black border-opacity-10` — translucent, so it does not
399
399
  clash with the photo. Reduce a photo's dynamics before placing text on it: a `bg-dark
400
- bg-opacity-50` (or `-75`) overlay layer under `card-img-overlay`, measured at every crop. Keep a
400
+ bg-opacity-50` (or `-75`) overlay layer under `card-img-overlay`, measured at every crop. Keep a
401
401
  small glyph near 16–24 px inside `rounded-circle bg-primary-subtle p-3` rather than scaling it up.
402
402
  Keep useful image detail and icon optical size rather than stretching assets to fill a box.
403
403
  - **Lists and quotes:** `list-unstyled` with a meaningful glyph per item (`d-flex gap-2
404
- align-items-baseline`, glyph `aria-hidden="true"`); `.blockquote` with `.blockquote-footer`.
404
+ align-items-baseline`, glyph `aria-hidden="true"`); `.blockquote` with `.blockquote-footer`.
405
405
  - **Print:** mark chrome `d-print-none` and keep results readable; do not hide data merely because
406
406
  its interactive controls have no print role.
@@ -41,7 +41,7 @@ Write `tmp/units/<unit>-claims.md` and point every lane at it. Read `references/
41
41
  Every lane returns exactly this:
42
42
 
43
43
  1. Numbered verdicts in claim order, one value each: `CONFIRMED` (attacked and held, with the attack), `BROKEN` (the failing input, state, or interleaving plus the smallest correct fix), `UNRESOLVED` (what would settle it; a claim whose only evidence is the writer's report), `NOT-EVIDENCED` (the capture that is missing).
44
- 2. Findings outside the claims, each substantiated to the `BROKEN` standard.
44
+ 2. Findings outside the claims, each substantiated to the `BROKEN` standard. After them, list each cost finding that `.claude/rules/quality.md` § Performance rules advisory, marked `ADVISORY`; an advisory never enters the terminal line.
45
45
  3. Attacked and held: attacks no verdict line carries, and the adjacent behavior that looks like the defect and is correct.
46
46
  4. One terminal line: `VERDICT: PASS` or `VERDICT: FAIL <claim numbers>; outside the claims: <finding ids or none>`. `PASS` needs every claim `CONFIRMED` and no substantiated outside finding.
47
47
 
@@ -62,6 +62,6 @@ Read `references/reconcile.md`.
62
62
 
63
63
  Write `.orkestrel/<package>/<unit>-audit-verdict.md` with the lanes that ran, their engines, the per-claim rulings, the findings carried into fix units, and any lane the round did not run with the reason. Delete the claims file and the verdict when the seam closes.
64
64
 
65
- ## After three rounds at one seam
65
+ ## End the depth search
66
66
 
67
- Stop the depth search. Name what the audit is for, dispatch one blind lens per station of the stream the defect moves along, locate the source, and plan from the source. A subject that reprices on every edit (a count, a census) is not a seam; drop the claim.
67
+ When review rounds at one seam keep surfacing defects without converging on their source, name what the audit is for, dispatch one blind lens per station of the stream the defect moves along, locate the source, and plan from the source. A subject that reprices on every edit (a count, a census) is not a seam; drop the claim.
@@ -269,7 +269,7 @@ Prove the harness from the browser project, through the object and the markup to
269
269
  zero, and the passed tally equals the total.
270
270
  - Assert the inventory before the tally. A harness that mounted no row would pass every tally
271
271
  assertion, and `createHarness` refuses an empty table with `Statechart harness mounted no
272
- transition`.
272
+ transition`.
273
273
  - Name the failing rows from `failures`, which lists each row whose rendered `result` reads failed,
274
274
  in table order. A red gate says which transition broke.
275
275
  - Read the tally off `harness.root` as well as off the object, so the attribute contract a gate
@@ -136,10 +136,9 @@ rest of the layer either fits inside it or takes another approval.
136
136
  moving target the user cannot approve in time. Publish a layer's opening package with exactly
137
137
  one attempt.
138
138
  - Retry only an upload that failed **inside** an already-open window. `EOTP` there is intermittent
139
- contention rather than the window closing: retry about three times, and retry a failed set after
140
- the layer ends. Packages have landed on a third attempt and on a later pass with no new
141
- approval. These are different failures wearing similar codes; a retry fixes in-window contention
142
- and causes the moving approval target.
139
+ contention rather than the window closing: retry while the window stays open, and retry a failed
140
+ set after the layer ends. These failures carry similar codes: a retry clears in-window
141
+ contention and moves the approval target.
143
142
  - Expect a large layer to outlast one window. Size batches to what uploads in five minutes and
144
143
  name each planned approval point to the user, rather than discovering them mid-run.
145
144
  - The contract's serialization law binds every upload in the window, and
@@ -25,4 +25,4 @@ A map is mechanical; reading is not. Run the map first, hand it to the reader, a
25
25
  ## Refuse
26
26
 
27
27
  - A question that needs reading at depth or a judgment: route it to `grok`, `distiller`, or the reviewer the size gate names, with the map attached.
28
- - A census over a term shorter than three characters without `--paths`.
28
+ - A census over a term short enough to match inside unrelated words, without `--paths`.
@@ -50,6 +50,8 @@ Stop and report (expected, found, evidence, done or not done, one hypothesis) on
50
50
 
51
51
  **Observations, not criteria.** TIMING_SENSITIVE_OR_TREE_WIDE_GATES the unit reports and the Orchestrator re-runs.
52
52
 
53
+ **Measurement.** FIXTURE_KINDS: the realistic heavy loads a cost claim is read under, named by kind; the unit sizes and reads them per `.claude/rules/quality.md` § Performance.
54
+
53
55
  ## Review evidence
54
56
 
55
57
  The actual diff and `git status --porcelain` for a code change; the capture portfolio for a rendered surface; the proposal, the canon it must satisfy, and its motivation for a process proposal.
@@ -21,7 +21,7 @@ node .agents/skills/orkestrel-dispatch/scripts/launch.ts --journal tmp/cursor/<u
21
21
 
22
22
  - Write the brief to `tmp/cursor/<unit>-brief.md` with `scripts/brief.ts --lane cursor`; the prompt is a pointer to it.
23
23
  - Read the answer and the session id with `node .agents/skills/orkestrel-dispatch/scripts/result.ts --cursor tmp/cursor/<unit>.jsonl`. The `init` event carries the session id; resume through the CLI's `--resume` option, probed before its first use.
24
- - A driver runs a lane finishing in about two minutes itself and returns the result. For anything longer its job ends at drafting: return the brief path, the resolved command, and the journal path. A driver never recommends a cap and never detaches a run.
24
+ - A driver runs a lane itself when the lane finishes well inside the foreground command cap of the harness running it (on Claude Code, `.claude/AGENTS.md` § Dispatch), and returns the result. For anything longer its job ends at drafting: return the brief path, the resolved command, and the journal path. A driver never recommends a cap and never detaches a run.
25
25
  - A driver pinned read-only writes nothing: it returns the brief text, its intended path, the resolved command, and the journal paths, and the Orchestrator writes and launches.
26
26
 
27
27
  ## Containment
@@ -17,7 +17,7 @@ Read `.agents/transports/codex.md` and follow it exactly. It owns the command, t
17
17
  1. Take the dispatch's brief, or write one to `tmp/codex/<unit>-brief.md` from the dispatch's objective, evidence slice, claims, scope, and return shape. For an audit, the brief names `tmp/units/<unit>-claims.md` and the `orkestrel-falsify` verdict shape.
18
18
  2. Run `node .agents/skills/orkestrel-dispatch/scripts/brief.ts --check <brief>` and fix every missing path.
19
19
  3. Resolve the `codex exec` command per the transport, as the `launch.ts` line it shows.
20
- 4. Return the brief path, the resolved command, and the journal path. Do not launch a multi-minute unit; the Orchestrator launches it under a cap. Run a bounded question under two minutes yourself and return the answer read with `scripts/result.ts --codex`, with the journal path and session id.
20
+ 4. Return the brief path, the resolved command, and the journal path. When a bounded question finishes well inside the foreground command cap (`.claude/AGENTS.md` § Dispatch), run it yourself and return the answer read with `scripts/result.ts --codex`, with the journal path and session id; launch nothing longer, because the Orchestrator launches it under a cap.
21
21
 
22
22
  ## Refuse
23
23
 
@@ -17,7 +17,7 @@ Read `.agents/transports/cursor.md` and follow it exactly. It owns the model pin
17
17
  1. Require a bounded question and an exact file scope from the dispatch. Refuse an unbounded one.
18
18
  2. Write the brief to `tmp/cursor/<unit>-brief.md`: read-only, the evidence sought, `file:line` pointers required, no raw dumps, no decisions.
19
19
  3. Resolve the command per the transport: `node .agents/skills/orkestrel-dispatch/scripts/bench.ts --cursor --resolve` prints the entry, and the transport shows the `launch.ts` line.
20
- 4. For a run under two minutes, run that command yourself and return the answer read with `scripts/result.ts --cursor`. For anything longer, return the brief path, the resolved command, and the journal path; the Orchestrator launches it under a cap.
20
+ 4. Run the command yourself only as `.agents/transports/cursor.md` § Command allows, and return the answer read with `scripts/result.ts --cursor`. Otherwise return the brief path, the resolved command, and the journal path; the Orchestrator launches it under a cap.
21
21
  5. Launch with `--status`, so `launch.ts` records `git status --porcelain` before and after. Any change is a deviation.
22
22
 
23
23
  ## Return
@@ -46,9 +46,9 @@ so network-controlled descriptions never enter agent instruction context.
46
46
  | Package | Version | Layer | Runtime dependencies | Peer dependencies |
47
47
  | ----------------------- | -------- | ----- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------- |
48
48
  | `@orkestrel/abort` | `0.0.12` | L1 | `@orkestrel/contract` `^0.0.18` | |
49
- | `@orkestrel/agent` | `0.0.25` | L5 | `@orkestrel/tool` `^0.0.17`, `@orkestrel/abort` `^0.0.12`, `@orkestrel/queue` `^0.0.15`, `@orkestrel/budget` `^0.0.12`, `@orkestrel/emitter` `^0.0.11`, `@orkestrel/timeout` `^0.0.12`, `@orkestrel/contract` `^0.0.18`, `@orkestrel/database` `^0.0.16`, `@orkestrel/workflow` `^0.0.20`, `@orkestrel/workspace` `^0.0.10` | |
49
+ | `@orkestrel/agent` | `0.0.26` | L5 | `@orkestrel/tool` `^0.0.18`, `@orkestrel/abort` `^0.0.12`, `@orkestrel/queue` `^0.0.16`, `@orkestrel/budget` `^0.0.12`, `@orkestrel/emitter` `^0.0.11`, `@orkestrel/timeout` `^0.0.12`, `@orkestrel/contract` `^0.0.19`, `@orkestrel/database` `^0.0.17`, `@orkestrel/workflow` `^0.0.21`, `@orkestrel/workspace` `^0.0.11` | |
50
50
  | `@orkestrel/brief` | `0.0.10` | L4 | `@orkestrel/reason` `^0.0.12`, `@orkestrel/emitter` `^0.0.11`, `@orkestrel/contract` `^0.0.18`, `@orkestrel/interpret` `^0.0.15` | |
51
- | `@orkestrel/browser` | `0.0.23` | L5 | `@orkestrel/mcp` `^0.0.36`, `@orkestrel/html` `^0.0.12`, `@orkestrel/pool` `^0.0.14`, `@orkestrel/tool` `^0.0.18`, `@orkestrel/router` `^0.0.16`, `@orkestrel/server` `^0.0.22`, `@orkestrel/emitter` `^0.0.11`, `@orkestrel/contract` `^0.0.19`, `@orkestrel/markdown` `^0.0.17`, `@orkestrel/websocket` `^0.0.14` | |
51
+ | `@orkestrel/browser` | `0.0.26` | L5 | `@orkestrel/mcp` `^0.0.36`, `@orkestrel/html` `^0.0.12`, `@orkestrel/pool` `^0.0.16`, `@orkestrel/tool` `^0.0.18`, `@orkestrel/router` `^0.0.16`, `@orkestrel/server` `^0.0.22`, `@orkestrel/emitter` `^0.0.11`, `@orkestrel/contract` `^0.0.19`, `@orkestrel/markdown` `^0.0.17`, `@orkestrel/websocket` `^0.0.14` | |
52
52
  | `@orkestrel/budget` | `0.0.12` | L1 | `@orkestrel/contract` `^0.0.18` | |
53
53
  | `@orkestrel/codec` | `0.0.5` | L1 | `@orkestrel/contract` `^0.0.18` | |
54
54
  | `@orkestrel/console` | `0.0.15` | L2 | `@orkestrel/emitter` `^0.0.11`, `@orkestrel/contract` `^0.0.18` | |
@@ -68,8 +68,8 @@ so network-controlled descriptions never enter agent instruction context.
68
68
  | `@orkestrel/msg` | `0.0.12` | L1 | `@orkestrel/contract` `^0.0.18` | |
69
69
  | `@orkestrel/ndjson` | `0.0.11` | L1 | `@orkestrel/contract` `^0.0.18` | |
70
70
  | `@orkestrel/ollama` | `0.0.20` | L6 | `@orkestrel/tool` `^0.0.18`, `@orkestrel/agent` `^0.0.25`, `@orkestrel/budget` `^0.0.12`, `@orkestrel/ndjson` `^0.0.11`, `@orkestrel/contract` `^0.0.19` | |
71
- | `@orkestrel/pool` | `0.0.14` | L2 | `@orkestrel/emitter` `^0.0.11`, `@orkestrel/contract` `^0.0.19` | |
72
- | `@orkestrel/probe` | `0.0.19` | L5 | `@orkestrel/lsp` `^0.0.10`, `@orkestrel/mcp` `^0.0.33`, `@orkestrel/tool` `^0.0.17`, `@orkestrel/queue` `^0.0.15`, `@orkestrel/emitter` `^0.0.11`, `@orkestrel/timeout` `^0.0.12`, `@orkestrel/contract` `^0.0.18` | `vitest` `^4.1.11`, `typescript` `^6.0.3` |
71
+ | `@orkestrel/pool` | `0.0.16` | L2 | `@orkestrel/emitter` `^0.0.11`, `@orkestrel/contract` `^0.0.19` | |
72
+ | `@orkestrel/probe` | `0.0.21` | L5 | `@orkestrel/lsp` `^0.0.10`, `@orkestrel/mcp` `^0.0.36`, `@orkestrel/pool` `^0.0.16`, `@orkestrel/tool` `^0.0.18`, `@orkestrel/emitter` `^0.0.11`, `@orkestrel/timeout` `^0.0.12`, `@orkestrel/contract` `^0.0.19` | `vitest` `^4.1.11`, `typescript` `^6.0.3` |
73
73
  | `@orkestrel/process` | `0.0.14` | L2 | `@orkestrel/emitter` `^0.0.11`, `@orkestrel/contract` `^0.0.18` | |
74
74
  | `@orkestrel/program` | `0.0.15` | L4 | `@orkestrel/rater` `^0.0.16`, `@orkestrel/reason` `^0.0.12`, `@orkestrel/emitter` `^0.0.11`, `@orkestrel/contract` `^0.0.18`, `@orkestrel/qualifier` `^0.0.16` | |
75
75
  | `@orkestrel/qualifier` | `0.0.16` | L3 | `@orkestrel/reason` `^0.0.12`, `@orkestrel/emitter` `^0.0.11`, `@orkestrel/contract` `^0.0.18` | |
@@ -78,7 +78,7 @@ so network-controlled descriptions never enter agent instruction context.
78
78
  | `@orkestrel/reason` | `0.0.12` | L2 | `@orkestrel/emitter` `^0.0.11`, `@orkestrel/contract` `^0.0.18` | |
79
79
  | `@orkestrel/relation` | `0.0.15` | L3 | `@orkestrel/emitter` `^0.0.11`, `@orkestrel/contract` `^0.0.19`, `@orkestrel/database` `^0.0.17` | |
80
80
  | `@orkestrel/router` | `0.0.16` | L2 | `@orkestrel/abort` `^0.0.12`, `@orkestrel/emitter` `^0.0.11`, `@orkestrel/contract` `^0.0.18` | |
81
- | `@orkestrel/scaffold` | `0.0.90` | L3 | `@orkestrel/console` `^0.0.15`, `@orkestrel/emitter` `^0.0.11`, `@orkestrel/process` `^0.0.14`, `@orkestrel/contract` `^0.0.19`, `@orkestrel/markdown` `^0.0.17`, `@orkestrel/template` `^0.0.9` | |
81
+ | `@orkestrel/scaffold` | `0.0.92` | L3 | `@orkestrel/console` `^0.0.15`, `@orkestrel/emitter` `^0.0.11`, `@orkestrel/process` `^0.0.14`, `@orkestrel/contract` `^0.0.19`, `@orkestrel/markdown` `^0.0.17`, `@orkestrel/template` `^0.0.9` | |
82
82
  | `@orkestrel/sea` | `0.0.18` | L3 | `@orkestrel/emitter` `^0.0.11`, `@orkestrel/process` `^0.0.14`, `@orkestrel/contract` `^0.0.18` | |
83
83
  | `@orkestrel/server` | `0.0.22` | L3 | `@orkestrel/abort` `^0.0.12`, `@orkestrel/codec` `^0.0.5`, `@orkestrel/router` `^0.0.16`, `@orkestrel/emitter` `^0.0.11`, `@orkestrel/timeout` `^0.0.12`, `@orkestrel/contract` `^0.0.19` | |
84
84
  | `@orkestrel/sqlite` | `0.0.14` | L1 | `@orkestrel/contract` `^0.0.19` | |
@@ -90,10 +90,10 @@ so network-controlled descriptions never enter agent instruction context.
90
90
  | `@orkestrel/test` | `0.0.24` | L1 | `@orkestrel/contract` `^0.0.18` | `vitest` `^4.1.11` |
91
91
  | `@orkestrel/timeout` | `0.0.12` | L1 | `@orkestrel/contract` `^0.0.18` | |
92
92
  | `@orkestrel/tool` | `0.0.18` | L2 | `@orkestrel/emitter` `^0.0.11`, `@orkestrel/contract` `^0.0.19` | |
93
- | `@orkestrel/toolbox` | `0.0.16` | L6 | `@orkestrel/form` `^0.0.8`, `@orkestrel/tool` `^0.0.17`, `@orkestrel/agent` `^0.0.25`, `@orkestrel/server` `^0.0.21`, `@orkestrel/contract` `^0.0.18`, `@orkestrel/database` `^0.0.16`, `@orkestrel/relation` `^0.0.14`, `@orkestrel/terminal` `^0.0.17`, `@orkestrel/workflow` `^0.0.20`, `@orkestrel/workspace` `^0.0.10` | |
93
+ | `@orkestrel/toolbox` | `0.0.17` | L6 | `@orkestrel/form` `^0.0.8`, `@orkestrel/tool` `^0.0.18`, `@orkestrel/agent` `^0.0.26`, `@orkestrel/server` `^0.0.22`, `@orkestrel/contract` `^0.0.19`, `@orkestrel/database` `^0.0.17`, `@orkestrel/relation` `^0.0.15`, `@orkestrel/terminal` `^0.0.18`, `@orkestrel/workflow` `^0.0.21`, `@orkestrel/workspace` `^0.0.11` | |
94
94
  | `@orkestrel/websocket` | `0.0.14` | L2 | `@orkestrel/emitter` `^0.0.11`, `@orkestrel/contract` `^0.0.18` | |
95
- | `@orkestrel/worker` | `0.0.14` | L4 | `@orkestrel/pool` `^0.0.13`, `@orkestrel/queue` `^0.0.15`, `@orkestrel/emitter` `^0.0.11`, `@orkestrel/contract` `^0.0.18`, `@orkestrel/database` `^0.0.16` | |
96
- | `@orkestrel/workflow` | `0.0.20` | L4 | `@orkestrel/abort` `^0.0.12`, `@orkestrel/queue` `^0.0.15`, `@orkestrel/budget` `^0.0.12`, `@orkestrel/emitter` `^0.0.11`, `@orkestrel/timeout` `^0.0.12`, `@orkestrel/contract` `^0.0.18`, `@orkestrel/database` `^0.0.16` | |
95
+ | `@orkestrel/worker` | `0.0.16` | L4 | `@orkestrel/pool` `^0.0.16`, `@orkestrel/queue` `^0.0.16`, `@orkestrel/emitter` `^0.0.11`, `@orkestrel/contract` `^0.0.19`, `@orkestrel/database` `^0.0.17` | |
96
+ | `@orkestrel/workflow` | `0.0.21` | L4 | `@orkestrel/abort` `^0.0.12`, `@orkestrel/queue` `^0.0.16`, `@orkestrel/budget` `^0.0.12`, `@orkestrel/emitter` `^0.0.11`, `@orkestrel/timeout` `^0.0.12`, `@orkestrel/contract` `^0.0.19`, `@orkestrel/database` `^0.0.17` | |
97
97
  | `@orkestrel/workspace` | `0.0.11` | L3 | `@orkestrel/emitter` `^0.0.11`, `@orkestrel/contract` `^0.0.19`, `@orkestrel/database` `^0.0.17` | |
98
98
 
99
99
  <!-- /orkestrel:catalog -->
@@ -13,7 +13,7 @@ You design. You hold no edit tool and run no command; your final message is the
13
13
 
14
14
  1. Read the brief, `AGENTS.md`, the rules whose `paths` match the subject, the named skill, the guide, and the supplied distillate. Work from the brief alone; never look for or reconcile the other lane's answer.
15
15
  2. Hold the lane the dispatch names and say which one: subjective (shape, naming, ergonomics, design fit) or objective (correctness, constraints, what the contracts permit).
16
- 3. Propose one design. Name at most two real alternatives and why the design wins.
16
+ 3. Propose one design. Name each real alternative that a constraint favors and why the design wins; leave out an option nothing favors.
17
17
  4. Cut every unit to a fully specified brief a cheap executor could implement; name each unit's role and engine, owned files, dependencies, and acceptance criteria.
18
18
  5. Name every judgment call under `Tensions` for the other lane or the Orchestrator to rule.
19
19
 
@@ -14,7 +14,7 @@ You gather cited facts from primary sources. You decide nothing.
14
14
 
15
15
  1. Take one bounded question and the sources it names: official documentation, release notes, the installed declaration under `node_modules`.
16
16
  2. Fetch and read each source. Never answer from memory.
17
- 3. Record each fact with its URL or `file:line` and a supporting quote under 25 words.
17
+ 3. Record each fact with its URL or `file:line` and the shortest supporting quote that carries the fact, never a passage.
18
18
  4. Put anything a primary source did not settle under `Unknowns` rather than guessing.
19
19
 
20
20
  ## Return
@@ -18,4 +18,4 @@ You locate. You do not read at depth, edit, or judge.
18
18
 
19
19
  ## Return
20
20
 
21
- `Question`, `Hits` (cited), `Shape` (under ten lines), `Not found` (patterns that returned nothing). Nothing else.
21
+ `Question`, `Hits` (cited), `Shape` (the shortest summary that places every part of the question), `Not found` (patterns that returned nothing). Nothing else.
@@ -29,7 +29,7 @@ Hard targets:
29
29
  - Ungrouped option keys: one word.
30
30
  - Grouped option key: the configured entity noun; every leaf remains one word.
31
31
  - Events: one present-tense verb or noun.
32
- - Private methods: two or three words are acceptable.
32
+ - Private methods: as many words as name the step unambiguously, and no more.
33
33
 
34
34
  The rule does not apply to standalone helpers, type names with role suffixes, or qualified constants.
35
35
 
@@ -105,7 +105,7 @@ Choose one event model per environment. `Emitter<TMap>` remains the default outs
105
105
  - Never publish a generic `status` event carrying a transition value; publish each transition as its own event.
106
106
  - Type errors as `unknown`.
107
107
  - Use empty tuples for signals and labeled tuple elements for IDE clarity.
108
- - Keep an entity's event map focused, normally four to eight events.
108
+ - Keep an entity's event map focused on the transitions and operations a consumer observes.
109
109
 
110
110
  ## Validation and contracts
111
111
 
@@ -44,6 +44,17 @@ paths:
44
44
  - Baseline a published-artifact claim against the published artifact (the tarball, the deployed asset). Prove a module cycle by loading the built entry points.
45
45
  - Promote an instrument that settled a claim into a test, with its control, before accepting the work it settled.
46
46
 
47
+ ## Performance
48
+
49
+ - Keep runtime cost reasonable and measurable. When a change claims a cost or a gain in speed, name the instrument that reads it and report each reading with its run.
50
+ - Change code for speed only when a measurement shows a gain worth having under the heavy load that real pages or callers produce. Never justify a change with an invented load.
51
+ - Refuse a micro optimization (hoisting a small array, caching one cheap read, shaving a constant) unless its own measurement shows a gain worth having.
52
+ - Keep an algorithmic repair (a superlinear term, a repeated layout) when the measurement shows it.
53
+ - Before the run, size the fixtures, the sample count, and the threshold to the case, and state the reasoning and the result that makes the change worth keeping.
54
+ - Read the difference between methods against each side's reported uncertainty, and record no difference smaller than the result stated before the run.
55
+ - Report every measurement with the host's other load during the run.
56
+ - Rule a cost finding advisory unless it shows its effect under a realistic load, and never carry an advisory into a fix brief as a required change; `.agents/skills/orkestrel-falsify/SKILL.md` § Verdict shape places it in a review lane's return.
57
+
47
58
  ## Ecosystem reuse
48
59
 
49
60
  - Prove a semantic difference before keeping a local variant of an installed primitive.
@@ -74,6 +74,11 @@ SCSS mirrors TypeScript centralization. Concrete token prefixes are project-spec
74
74
  for that framework and every `!important` declaration outside every layer. A derived build of that
75
75
  recreation for a utility library may place the framework's reset rules in `reset` under a switch
76
76
  the guide records, keeping every `!important` declaration outside every layer.
77
+ - A derived build of a recreation for a utility library may substitute the framework's token
78
+ literals (colors and scale values) with the utility library's theme values under a switch the guide
79
+ records, when a committed record maps every substituted literal to its source token and resolved
80
+ value and a proof reads the derived sheet against the framework's own compile from the mapped
81
+ bases; the substitution changes no selector, declaration order, or declaration count.
77
82
  - Declare cascade-layer order once in the consumer entry before `@import 'tailwindcss'`, so utilities win predictably. When a package publishes several sheets, open every published sheet with the same full order statement, so the order holds whichever sheet loads first.
78
83
  - Open `themes/index.scss` with `@use '../tokens'`, whose first emitted rule is the order statement, then `@use 'default'`; Sass refuses a `@use` after another rule, so never write the statement there literally.
79
84
 
@@ -25,7 +25,7 @@ paths:
25
25
  population. The policy sweep (`tests/setupPolicy.ts`) enforces both directions.
26
26
  - Prefer test filenames matching entrypoints: `index.test.ts` for `index.ts`, `main.test.ts` for `main.ts`.
27
27
  - Tests are deterministic: identical inputs produce identical results.
28
- - Keep default suites fast: timers normally use 10–50 ms and tests make no network calls.
28
+ - Keep default suites fast: give each timer the shortest real duration that still separates the orderings the test asserts on a loaded host, and make no network calls.
29
29
  - Use real implementations and small scenarios. Never use mocks, behavioral fakes, module replacement, or framework spies for project-owned or integrated behavior.
30
30
  - Use recorders for calls/events, temporary resources for stateful boundaries, protocol-faithful fixture servers for deterministic network peers, and the real external service when its behavior is the claim.
31
31
  - Prefer inert customizable data and input stubs.
@@ -127,13 +127,12 @@ Run a probe before relying on an unverified belief about behaviour: what a funct
127
127
  configuration resolves to, whether a path is reached at all. Prefer a probe to an argument whenever
128
128
  the probe is cheap.
129
129
 
130
- When the question is whether the difference between methods is a magnitude or negligible, write a
131
- guarded bench block beside the probe test and run the `test:bench` script. Declare the threshold
132
- before the run, read the ratio between the methods against each side's reported uncertainty, and
133
- record nothing below a magnitude. A settled magnitude that underwrites an implementation choice
134
- promotes with its test into the mirrored suite and keeps its guarded block there while that choice
135
- stands. A deterministic relationship promotes as an ordinary assertion, so delete the block. Never
136
- commit baseline output.
130
+ When the question is whether the difference between methods is worth having, write a guarded bench
131
+ block beside the probe test, run the `test:bench` script, and size its fixtures, declare its
132
+ threshold, and read its result per `.claude/rules/quality.md` § Performance. A settled difference
133
+ that underwrites an implementation choice promotes with its test into the mirrored suite and keeps
134
+ its guarded block there while that choice stands. A deterministic relationship promotes as an
135
+ ordinary assertion, so delete the block. Never commit baseline output.
137
136
 
138
137
  These rules bind every probe:
139
138
 
@@ -56,7 +56,8 @@
56
56
  - Cut every clause that persuades, reassures, or explains to a person.
57
57
  - Give a rule one home. Point at it from elsewhere; never restate it.
58
58
  - Keep an example only when it disambiguates the rule.
59
- - Keep `AGENTS.md` under 200 lines and the always-loaded set small; move a procedure into a skill and scope a rule with `paths`.
59
+ - When an instruction file or a brief governs a quantity, state the property the quantity must serve and leave the figure to the case: never fix a fixture size, a sample count, a percentage, or a threshold, and describe a fixture by its kind and the load it represents. Keep a figure only where it is a contract: a limit a protocol, format, standard, or external tool fixes, an exit code, a measurement with its run, a version, a date, or a cardinality a design law fixes (one word per name, one writer per checkout).
60
+ - Keep `AGENTS.md` to the laws every task needs and the always-loaded set small: move a procedure into a skill and scope a rule with `paths`.
60
61
 
61
62
  ## Substitutions
62
63
 
@@ -8,8 +8,8 @@ Gather cited facts from primary sources. Decide nothing.
8
8
 
9
9
  Take one bounded question and the sources it names: official documentation, release notes, the
10
10
  installed declaration under node_modules. Read each source; never answer from memory. Record each
11
- fact with its URL or file:line and a supporting quote under 25 words. Put anything a primary
12
- source did not settle under Unknowns.
11
+ fact with its URL or file:line and the shortest supporting quote that carries the fact, never a
12
+ passage. Put anything a primary source did not settle under Unknowns.
13
13
 
14
14
  Return only: Question, Facts (claim, source, date, quote), Matrix when asked (each row ending
15
15
  implement, repair, retain, or exclude with evidence), Unknowns. Never spawn another agent.
@@ -13,6 +13,6 @@ a match. Refuse a dispatch that names no map and asks for one. Return every hit
13
13
  one-line shape note, grouped by the question's parts, and name the search patterns and roots you
14
14
  used.
15
15
 
16
- Return only: Question, Hits, Shape (under ten lines), Not found (patterns that returned nothing).
16
+ Return only: Question, Hits, Shape (the shortest summary that places every part of the question), Not found (patterns that returned nothing).
17
17
  Never spawn another agent.
18
18
  """
@@ -226,6 +226,174 @@
226
226
  ]
227
227
  }
228
228
  },
229
+ {
230
+ "files": ["src/bootstrap/**/*.{cjs,cts,js,jsx,mjs,mts,ts,tsx,vue}"],
231
+ "rules": {
232
+ "no-restricted-imports": [
233
+ "error",
234
+ {
235
+ "patterns": [
236
+ {
237
+ "regex": "^(?:(?:vue|vite)(?:[/?#]|$)|@(?:vue|vitejs)/|@(?:src|app)/vue(?:[/?#]|$)|@orkestrel/[^/]+/vue(?:[/?#]|$)|(?:\\.\\./)+(?:vue|src/vue|app/vue)(?:[/?#]|$))",
238
+ "message": "src/bootstrap must not depend on Vue extension modules"
239
+ },
240
+ {
241
+ "regex": "^(?:/|[A-Za-z]:[\\\\/])",
242
+ "message": "imports must not use machine-specific absolute paths"
243
+ },
244
+ {
245
+ "regex": "^(?:[A-Za-mo-z][A-Za-z0-9+.-]*|n(?:[A-Za-np-z0-9+.-][A-Za-z0-9+.-]*)?|no(?:[A-Za-ce-z0-9+.-][A-Za-z0-9+.-]*)?|nod(?:[A-Za-df-z0-9+.-][A-Za-z0-9+.-]*)?|node[A-Za-z0-9+.-]+):",
246
+ "message": "imports must not use non-Node URL schemes"
247
+ },
248
+ {
249
+ "regex": "(?:^|/)(?:[^/.][^/]*|\\.[^/.][^/]*|\\.\\.[^/]+)/\\.{1,2}(?:/|$)",
250
+ "message": "internal import paths must not contain noncanonical dot segments"
251
+ },
252
+ {
253
+ "regex": "^(?:(?:\\./)+\\.\\.(?:/|$)|(?:\\.\\./)+(?:\\./)+)|//",
254
+ "message": "relative import paths must not contain normalized traversal segments"
255
+ },
256
+ {
257
+ "regex": "\\\\",
258
+ "message": "import paths must use portable forward slashes"
259
+ },
260
+ {
261
+ "regex": "^typescript(?:[/?#]|$)",
262
+ "message": "the in-process compiler API is not a surface the fleet uses"
263
+ },
264
+ {
265
+ "regex": "^(?:@app(?:[/?#]|$)|(?:\\.\\./)+app(?:[/?#]|$))",
266
+ "message": "src environments must not depend on private app modules"
267
+ },
268
+ {
269
+ "regex": "^(?:node:|(?:_(?:http_(?:agent|client|common|incoming|outgoing|server)|stream_(?:duplex|passthrough|readable|transform|wrap|writable)|tls_(?:common|wrap))|assert(?:/strict)?|async_hooks|buffer|child_process|cluster|console|constants|crypto|dgram|diagnostics_channel|dns(?:/promises)?|domain|events|fs(?:/promises)?|http|http2|https|inspector(?:/promises)?|module|net|os|path(?:/(?:posix|win32))?|perf_hooks|process|punycode|querystring|readline(?:/promises)?|repl|sqlite|stream(?:/(?:consumers|promises|web))?|string_decoder|sys|timers(?:/promises)?|tls|trace_events|tty|url|util(?:/types)?|v8|vm|wasi|worker_threads|zlib)(?:[/?#]|$)|@src/server(?:[/?#]|$)|@orkestrel/[^/]+/server(?:[/?#]|$)|(?:\\.\\./)+(?:server|src/server|app/server)(?:[/?#]|$))",
270
+ "message": "src/bootstrap must not depend on Node or server-only modules"
271
+ },
272
+ {
273
+ "regex": "^(?:@src/tailwindcss(?:[/?#]|$)|@orkestrel/[^/]+/tailwindcss(?:[/?#]|$)|(?:\\.\\./)+(?:tailwindcss|src/tailwindcss)(?:[/?#]|$))",
274
+ "message": "src/bootstrap must not import another styles face's TypeScript"
275
+ },
276
+ {
277
+ "regex": "^(?:@src/styles(?:[/?#]|$)|@orkestrel/[^/]+/styles(?:[/?#]|$)|(?:\\.\\./)+(?:styles|src/styles)(?:[/?#]|$))",
278
+ "message": "src/bootstrap must not import another styles face's TypeScript"
279
+ }
280
+ ]
281
+ }
282
+ ]
283
+ }
284
+ },
285
+ {
286
+ "files": ["src/tailwindcss/**/*.{cjs,cts,js,jsx,mjs,mts,ts,tsx,vue}"],
287
+ "rules": {
288
+ "no-restricted-imports": [
289
+ "error",
290
+ {
291
+ "patterns": [
292
+ {
293
+ "regex": "^(?:(?:vue|vite)(?:[/?#]|$)|@(?:vue|vitejs)/|@(?:src|app)/vue(?:[/?#]|$)|@orkestrel/[^/]+/vue(?:[/?#]|$)|(?:\\.\\./)+(?:vue|src/vue|app/vue)(?:[/?#]|$))",
294
+ "message": "src/tailwindcss must not depend on Vue extension modules"
295
+ },
296
+ {
297
+ "regex": "^(?:/|[A-Za-z]:[\\\\/])",
298
+ "message": "imports must not use machine-specific absolute paths"
299
+ },
300
+ {
301
+ "regex": "^(?:[A-Za-mo-z][A-Za-z0-9+.-]*|n(?:[A-Za-np-z0-9+.-][A-Za-z0-9+.-]*)?|no(?:[A-Za-ce-z0-9+.-][A-Za-z0-9+.-]*)?|nod(?:[A-Za-df-z0-9+.-][A-Za-z0-9+.-]*)?|node[A-Za-z0-9+.-]+):",
302
+ "message": "imports must not use non-Node URL schemes"
303
+ },
304
+ {
305
+ "regex": "(?:^|/)(?:[^/.][^/]*|\\.[^/.][^/]*|\\.\\.[^/]+)/\\.{1,2}(?:/|$)",
306
+ "message": "internal import paths must not contain noncanonical dot segments"
307
+ },
308
+ {
309
+ "regex": "^(?:(?:\\./)+\\.\\.(?:/|$)|(?:\\.\\./)+(?:\\./)+)|//",
310
+ "message": "relative import paths must not contain normalized traversal segments"
311
+ },
312
+ {
313
+ "regex": "\\\\",
314
+ "message": "import paths must use portable forward slashes"
315
+ },
316
+ {
317
+ "regex": "^typescript(?:[/?#]|$)",
318
+ "message": "the in-process compiler API is not a surface the fleet uses"
319
+ },
320
+ {
321
+ "regex": "^(?:@app(?:[/?#]|$)|(?:\\.\\./)+app(?:[/?#]|$))",
322
+ "message": "src environments must not depend on private app modules"
323
+ },
324
+ {
325
+ "regex": "^(?:node:|(?:_(?:http_(?:agent|client|common|incoming|outgoing|server)|stream_(?:duplex|passthrough|readable|transform|wrap|writable)|tls_(?:common|wrap))|assert(?:/strict)?|async_hooks|buffer|child_process|cluster|console|constants|crypto|dgram|diagnostics_channel|dns(?:/promises)?|domain|events|fs(?:/promises)?|http|http2|https|inspector(?:/promises)?|module|net|os|path(?:/(?:posix|win32))?|perf_hooks|process|punycode|querystring|readline(?:/promises)?|repl|sqlite|stream(?:/(?:consumers|promises|web))?|string_decoder|sys|timers(?:/promises)?|tls|trace_events|tty|url|util(?:/types)?|v8|vm|wasi|worker_threads|zlib)(?:[/?#]|$)|@src/server(?:[/?#]|$)|@orkestrel/[^/]+/server(?:[/?#]|$)|(?:\\.\\./)+(?:server|src/server|app/server)(?:[/?#]|$))",
326
+ "message": "src/tailwindcss must not depend on Node or server-only modules"
327
+ },
328
+ {
329
+ "regex": "^(?:@src/bootstrap(?:[/?#]|$)|@orkestrel/[^/]+/bootstrap(?:[/?#]|$)|(?:\\.\\./)+(?:bootstrap|src/bootstrap)(?:[/?#]|$))",
330
+ "message": "src/tailwindcss must not import another styles face's TypeScript"
331
+ },
332
+ {
333
+ "regex": "^(?:@src/styles(?:[/?#]|$)|@orkestrel/[^/]+/styles(?:[/?#]|$)|(?:\\.\\./)+(?:styles|src/styles)(?:[/?#]|$))",
334
+ "message": "src/tailwindcss must not import another styles face's TypeScript"
335
+ }
336
+ ]
337
+ }
338
+ ]
339
+ }
340
+ },
341
+ {
342
+ "files": ["src/styles/**/*.{cjs,cts,js,jsx,mjs,mts,ts,tsx,vue}"],
343
+ "rules": {
344
+ "no-restricted-imports": [
345
+ "error",
346
+ {
347
+ "patterns": [
348
+ {
349
+ "regex": "^(?:(?:vue|vite)(?:[/?#]|$)|@(?:vue|vitejs)/|@(?:src|app)/vue(?:[/?#]|$)|@orkestrel/[^/]+/vue(?:[/?#]|$)|(?:\\.\\./)+(?:vue|src/vue|app/vue)(?:[/?#]|$))",
350
+ "message": "src/styles must not depend on Vue extension modules"
351
+ },
352
+ {
353
+ "regex": "^(?:/|[A-Za-z]:[\\\\/])",
354
+ "message": "imports must not use machine-specific absolute paths"
355
+ },
356
+ {
357
+ "regex": "^(?:[A-Za-mo-z][A-Za-z0-9+.-]*|n(?:[A-Za-np-z0-9+.-][A-Za-z0-9+.-]*)?|no(?:[A-Za-ce-z0-9+.-][A-Za-z0-9+.-]*)?|nod(?:[A-Za-df-z0-9+.-][A-Za-z0-9+.-]*)?|node[A-Za-z0-9+.-]+):",
358
+ "message": "imports must not use non-Node URL schemes"
359
+ },
360
+ {
361
+ "regex": "(?:^|/)(?:[^/.][^/]*|\\.[^/.][^/]*|\\.\\.[^/]+)/\\.{1,2}(?:/|$)",
362
+ "message": "internal import paths must not contain noncanonical dot segments"
363
+ },
364
+ {
365
+ "regex": "^(?:(?:\\./)+\\.\\.(?:/|$)|(?:\\.\\./)+(?:\\./)+)|//",
366
+ "message": "relative import paths must not contain normalized traversal segments"
367
+ },
368
+ {
369
+ "regex": "\\\\",
370
+ "message": "import paths must use portable forward slashes"
371
+ },
372
+ {
373
+ "regex": "^typescript(?:[/?#]|$)",
374
+ "message": "the in-process compiler API is not a surface the fleet uses"
375
+ },
376
+ {
377
+ "regex": "^(?:@app(?:[/?#]|$)|(?:\\.\\./)+app(?:[/?#]|$))",
378
+ "message": "src environments must not depend on private app modules"
379
+ },
380
+ {
381
+ "regex": "^(?:node:|(?:_(?:http_(?:agent|client|common|incoming|outgoing|server)|stream_(?:duplex|passthrough|readable|transform|wrap|writable)|tls_(?:common|wrap))|assert(?:/strict)?|async_hooks|buffer|child_process|cluster|console|constants|crypto|dgram|diagnostics_channel|dns(?:/promises)?|domain|events|fs(?:/promises)?|http|http2|https|inspector(?:/promises)?|module|net|os|path(?:/(?:posix|win32))?|perf_hooks|process|punycode|querystring|readline(?:/promises)?|repl|sqlite|stream(?:/(?:consumers|promises|web))?|string_decoder|sys|timers(?:/promises)?|tls|trace_events|tty|url|util(?:/types)?|v8|vm|wasi|worker_threads|zlib)(?:[/?#]|$)|@src/server(?:[/?#]|$)|@orkestrel/[^/]+/server(?:[/?#]|$)|(?:\\.\\./)+(?:server|src/server|app/server)(?:[/?#]|$))",
382
+ "message": "src/styles must not depend on Node or server-only modules"
383
+ },
384
+ {
385
+ "regex": "^(?:@src/bootstrap(?:[/?#]|$)|@orkestrel/[^/]+/bootstrap(?:[/?#]|$)|(?:\\.\\./)+(?:bootstrap|src/bootstrap)(?:[/?#]|$))",
386
+ "message": "src/styles must not import another styles face's TypeScript"
387
+ },
388
+ {
389
+ "regex": "^(?:@src/tailwindcss(?:[/?#]|$)|@orkestrel/[^/]+/tailwindcss(?:[/?#]|$)|(?:\\.\\./)+(?:tailwindcss|src/tailwindcss)(?:[/?#]|$))",
390
+ "message": "src/styles must not import another styles face's TypeScript"
391
+ }
392
+ ]
393
+ }
394
+ ]
395
+ }
396
+ },
229
397
  {
230
398
  "files": ["src/vue/**/*.{cjs,cts,js,jsx,mjs,mts,ts,tsx,vue}"],
231
399
  "rules": {