@prismatic-io/lux 0.0.2-preview.18 → 0.0.2-preview.21

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 (244) hide show
  1. package/lib/answerers/persona/index.d.ts +5 -1
  2. package/lib/answerers/persona/index.d.ts.map +1 -1
  3. package/lib/assertions/rubric/index.d.ts +3 -1
  4. package/lib/assertions/rubric/index.d.ts.map +1 -1
  5. package/lib/authoring.d.ts +3 -1
  6. package/lib/authoring.d.ts.map +1 -1
  7. package/lib/authoring.js +2 -1
  8. package/lib/authoring.js.map +1 -1
  9. package/lib/cli/harness-plan.d.ts +26 -0
  10. package/lib/cli/harness-plan.d.ts.map +1 -0
  11. package/lib/cli/harness-plan.js +75 -0
  12. package/lib/cli/harness-plan.js.map +1 -0
  13. package/lib/cli/init-templates.d.ts +2 -2
  14. package/lib/cli/init-templates.d.ts.map +1 -1
  15. package/lib/cli/init-templates.js +11 -4
  16. package/lib/cli/init-templates.js.map +1 -1
  17. package/lib/cli/init.d.ts +2 -0
  18. package/lib/cli/init.d.ts.map +1 -1
  19. package/lib/cli/init.js +6 -3
  20. package/lib/cli/init.js.map +1 -1
  21. package/lib/cli/output-schemas.d.ts +7 -0
  22. package/lib/cli/output-schemas.d.ts.map +1 -1
  23. package/lib/cli/program.d.ts +5 -10
  24. package/lib/cli/program.d.ts.map +1 -1
  25. package/lib/cli/program.js +44 -77
  26. package/lib/cli/program.js.map +1 -1
  27. package/lib/cli/run-options.d.ts +19 -0
  28. package/lib/cli/run-options.d.ts.map +1 -1
  29. package/lib/cli/run-options.js +92 -0
  30. package/lib/cli/run-options.js.map +1 -1
  31. package/lib/core/case.d.ts +2 -0
  32. package/lib/core/case.d.ts.map +1 -1
  33. package/lib/core/case.js +3 -0
  34. package/lib/core/case.js.map +1 -1
  35. package/lib/core/driver.d.ts +13 -0
  36. package/lib/core/driver.d.ts.map +1 -1
  37. package/lib/core/driver.js +10 -0
  38. package/lib/core/driver.js.map +1 -1
  39. package/lib/core/harness-catalog.d.ts +35 -0
  40. package/lib/core/harness-catalog.d.ts.map +1 -0
  41. package/lib/core/harness-catalog.js +45 -0
  42. package/lib/core/harness-catalog.js.map +1 -0
  43. package/lib/core/harness-catalogs/antigravity.d.ts +11 -0
  44. package/lib/core/harness-catalogs/antigravity.d.ts.map +1 -0
  45. package/lib/core/harness-catalogs/antigravity.js +23 -0
  46. package/lib/core/harness-catalogs/antigravity.js.map +1 -0
  47. package/lib/core/harness-catalogs/claude-code.d.ts +12 -0
  48. package/lib/core/harness-catalogs/claude-code.d.ts.map +1 -0
  49. package/lib/core/harness-catalogs/claude-code.js +24 -0
  50. package/lib/core/harness-catalogs/claude-code.js.map +1 -0
  51. package/lib/core/harness-catalogs/codex.d.ts +11 -0
  52. package/lib/core/harness-catalogs/codex.d.ts.map +1 -0
  53. package/lib/core/harness-catalogs/codex.js +26 -0
  54. package/lib/core/harness-catalogs/codex.js.map +1 -0
  55. package/lib/core/harness-catalogs/copilot.d.ts +29 -0
  56. package/lib/core/harness-catalogs/copilot.d.ts.map +1 -0
  57. package/lib/core/harness-catalogs/copilot.js +45 -0
  58. package/lib/core/harness-catalogs/copilot.js.map +1 -0
  59. package/lib/core/harness-catalogs/cursor.d.ts +2 -0
  60. package/lib/core/harness-catalogs/cursor.d.ts.map +1 -0
  61. package/lib/core/harness-catalogs/cursor.js +13 -0
  62. package/lib/core/harness-catalogs/cursor.js.map +1 -0
  63. package/lib/core/harness-catalogs/index.d.ts +67 -0
  64. package/lib/core/harness-catalogs/index.d.ts.map +1 -0
  65. package/lib/core/harness-catalogs/index.js +15 -0
  66. package/lib/core/harness-catalogs/index.js.map +1 -0
  67. package/lib/core/harness-matrix.d.ts +70 -0
  68. package/lib/core/harness-matrix.d.ts.map +1 -0
  69. package/lib/core/harness-matrix.js +194 -0
  70. package/lib/core/harness-matrix.js.map +1 -0
  71. package/lib/core/index.d.ts +3 -0
  72. package/lib/core/index.d.ts.map +1 -1
  73. package/lib/core/index.js +3 -0
  74. package/lib/core/index.js.map +1 -1
  75. package/lib/core/model-cli.d.ts +4 -11
  76. package/lib/core/model-cli.d.ts.map +1 -1
  77. package/lib/core/model-cli.js +23 -17
  78. package/lib/core/model-cli.js.map +1 -1
  79. package/lib/core/platform-process.d.ts +1 -0
  80. package/lib/core/platform-process.d.ts.map +1 -1
  81. package/lib/core/platform-process.js +1 -1
  82. package/lib/core/platform-process.js.map +1 -1
  83. package/lib/core/run.d.ts +4 -0
  84. package/lib/core/run.d.ts.map +1 -1
  85. package/lib/core/run.js +2 -0
  86. package/lib/core/run.js.map +1 -1
  87. package/lib/drivers/antigravity/config.d.ts +46 -0
  88. package/lib/drivers/antigravity/config.d.ts.map +1 -0
  89. package/lib/drivers/antigravity/config.js +39 -0
  90. package/lib/drivers/antigravity/config.js.map +1 -0
  91. package/lib/drivers/antigravity/events.d.ts +4 -0
  92. package/lib/drivers/antigravity/events.d.ts.map +1 -0
  93. package/lib/drivers/antigravity/events.js +193 -0
  94. package/lib/drivers/antigravity/events.js.map +1 -0
  95. package/lib/drivers/antigravity/index.d.ts +60 -0
  96. package/lib/drivers/antigravity/index.d.ts.map +1 -0
  97. package/lib/drivers/antigravity/index.js +90 -0
  98. package/lib/drivers/antigravity/index.js.map +1 -0
  99. package/lib/drivers/claude-code/index.d.ts +93 -7
  100. package/lib/drivers/claude-code/index.d.ts.map +1 -1
  101. package/lib/drivers/claude-code/index.js +14 -8
  102. package/lib/drivers/claude-code/index.js.map +1 -1
  103. package/lib/drivers/codex/config.d.ts +61 -4
  104. package/lib/drivers/codex/config.d.ts.map +1 -1
  105. package/lib/drivers/codex/config.js +19 -5
  106. package/lib/drivers/codex/config.js.map +1 -1
  107. package/lib/drivers/codex/index.d.ts +63 -5
  108. package/lib/drivers/codex/index.d.ts.map +1 -1
  109. package/lib/drivers/codex/index.js +11 -3
  110. package/lib/drivers/codex/index.js.map +1 -1
  111. package/lib/drivers/copilot/config.d.ts +81 -0
  112. package/lib/drivers/copilot/config.d.ts.map +1 -0
  113. package/lib/drivers/copilot/config.js +54 -0
  114. package/lib/drivers/copilot/config.js.map +1 -0
  115. package/lib/drivers/copilot/index.d.ts +103 -0
  116. package/lib/drivers/copilot/index.d.ts.map +1 -0
  117. package/lib/drivers/copilot/index.js +256 -0
  118. package/lib/drivers/copilot/index.js.map +1 -0
  119. package/lib/drivers/cursor/config.d.ts +6 -1
  120. package/lib/drivers/cursor/config.d.ts.map +1 -1
  121. package/lib/drivers/cursor/config.js +2 -3
  122. package/lib/drivers/cursor/config.js.map +1 -1
  123. package/lib/drivers/cursor/index.d.ts +7 -2
  124. package/lib/drivers/cursor/index.d.ts.map +1 -1
  125. package/lib/drivers/cursor/index.js +9 -6
  126. package/lib/drivers/cursor/index.js.map +1 -1
  127. package/lib/drivers/cursor/interaction.d.ts +1 -2
  128. package/lib/drivers/cursor/interaction.d.ts.map +1 -1
  129. package/lib/drivers/cursor/interaction.js +3 -14
  130. package/lib/drivers/cursor/interaction.js.map +1 -1
  131. package/lib/drivers/{cursor/events.d.ts → shared/acp-events.d.ts} +5 -3
  132. package/lib/drivers/shared/acp-events.d.ts.map +1 -0
  133. package/lib/drivers/{cursor/events.js → shared/acp-events.js} +20 -10
  134. package/lib/drivers/shared/acp-events.js.map +1 -0
  135. package/lib/drivers/shared/acp-interaction.d.ts +7 -0
  136. package/lib/drivers/shared/acp-interaction.d.ts.map +1 -0
  137. package/lib/drivers/shared/acp-interaction.js +20 -0
  138. package/lib/drivers/shared/acp-interaction.js.map +1 -0
  139. package/lib/drivers/{cursor → shared}/acp-transport.d.ts +2 -0
  140. package/lib/drivers/shared/acp-transport.d.ts.map +1 -0
  141. package/lib/drivers/{cursor → shared}/acp-transport.js +10 -10
  142. package/lib/drivers/shared/acp-transport.js.map +1 -0
  143. package/lib/index.d.ts +7 -2
  144. package/lib/index.d.ts.map +1 -1
  145. package/lib/index.js +7 -2
  146. package/lib/index.js.map +1 -1
  147. package/lib/optimization/reflective.d.ts +2 -0
  148. package/lib/optimization/reflective.d.ts.map +1 -1
  149. package/lib/orchestrator/comparison-identity.d.ts.map +1 -1
  150. package/lib/orchestrator/comparison-identity.js +1 -0
  151. package/lib/orchestrator/comparison-identity.js.map +1 -1
  152. package/lib/orchestrator/config.d.ts +7 -0
  153. package/lib/orchestrator/config.d.ts.map +1 -1
  154. package/lib/orchestrator/config.js +8 -1
  155. package/lib/orchestrator/config.js.map +1 -1
  156. package/lib/orchestrator/doctor.d.ts.map +1 -1
  157. package/lib/orchestrator/doctor.js +72 -2
  158. package/lib/orchestrator/doctor.js.map +1 -1
  159. package/lib/orchestrator/experiment-context.d.ts +1 -1
  160. package/lib/orchestrator/harness-catalog-drift.d.ts +22 -0
  161. package/lib/orchestrator/harness-catalog-drift.d.ts.map +1 -0
  162. package/lib/orchestrator/harness-catalog-drift.js +90 -0
  163. package/lib/orchestrator/harness-catalog-drift.js.map +1 -0
  164. package/lib/orchestrator/orchestrator.d.ts +9 -1
  165. package/lib/orchestrator/orchestrator.d.ts.map +1 -1
  166. package/lib/orchestrator/orchestrator.js +14 -22
  167. package/lib/orchestrator/orchestrator.js.map +1 -1
  168. package/lib/orchestrator/run-dir.d.ts +2 -0
  169. package/lib/orchestrator/run-dir.d.ts.map +1 -1
  170. package/lib/orchestrator/run-dir.js +1 -1
  171. package/lib/orchestrator/run-dir.js.map +1 -1
  172. package/lib/orchestrator/run-execution.d.ts +1 -0
  173. package/lib/orchestrator/run-execution.d.ts.map +1 -1
  174. package/lib/orchestrator/run-execution.js +2 -0
  175. package/lib/orchestrator/run-execution.js.map +1 -1
  176. package/lib/orchestrator/suite-compare.d.ts +3 -0
  177. package/lib/orchestrator/suite-compare.d.ts.map +1 -1
  178. package/lib/orchestrator/suite-compare.js +27 -17
  179. package/lib/orchestrator/suite-compare.js.map +1 -1
  180. package/lib/orchestrator/suite-runs.d.ts +3 -0
  181. package/lib/orchestrator/suite-runs.d.ts.map +1 -1
  182. package/lib/orchestrator/suite-runs.js +2 -0
  183. package/lib/orchestrator/suite-runs.js.map +1 -1
  184. package/lib/orchestrator/suite-summary.d.ts +9 -0
  185. package/lib/orchestrator/suite-summary.d.ts.map +1 -1
  186. package/lib/orchestrator/suite-summary.js +14 -4
  187. package/lib/orchestrator/suite-summary.js.map +1 -1
  188. package/package.json +1 -1
  189. package/skills/lux-answerer/SKILL.md +1 -1
  190. package/src/authoring.ts +10 -3
  191. package/src/cli/harness-plan.ts +117 -0
  192. package/src/cli/init-templates.ts +12 -5
  193. package/src/cli/init.ts +12 -5
  194. package/src/cli/program.ts +50 -92
  195. package/src/cli/run-options.ts +123 -0
  196. package/src/core/case.ts +3 -0
  197. package/src/core/driver.ts +26 -0
  198. package/src/core/harness-catalog.ts +100 -0
  199. package/src/core/harness-catalogs/antigravity.ts +24 -0
  200. package/src/core/harness-catalogs/claude-code.ts +25 -0
  201. package/src/core/harness-catalogs/codex.ts +27 -0
  202. package/src/core/harness-catalogs/copilot.ts +46 -0
  203. package/src/core/harness-catalogs/cursor.ts +13 -0
  204. package/src/core/harness-catalogs/index.ts +22 -0
  205. package/src/core/harness-matrix.ts +298 -0
  206. package/src/core/index.ts +3 -0
  207. package/src/core/model-cli.ts +38 -21
  208. package/src/core/platform-process.ts +4 -4
  209. package/src/core/run.ts +2 -0
  210. package/src/drivers/antigravity/README.md +46 -0
  211. package/src/drivers/antigravity/config.ts +44 -0
  212. package/src/drivers/antigravity/events.ts +235 -0
  213. package/src/drivers/antigravity/index.ts +109 -0
  214. package/src/drivers/claude-code/index.ts +18 -7
  215. package/src/drivers/codex/config.ts +23 -5
  216. package/src/drivers/codex/index.ts +15 -2
  217. package/src/drivers/copilot/README.md +52 -0
  218. package/src/drivers/copilot/config.ts +58 -0
  219. package/src/drivers/copilot/index.ts +292 -0
  220. package/src/drivers/cursor/README.md +9 -6
  221. package/src/drivers/cursor/config.ts +2 -3
  222. package/src/drivers/cursor/index.ts +10 -6
  223. package/src/drivers/cursor/interaction.ts +3 -19
  224. package/src/drivers/{cursor/events.ts → shared/acp-events.ts} +20 -9
  225. package/src/drivers/shared/acp-interaction.ts +27 -0
  226. package/src/drivers/{cursor → shared}/acp-transport.ts +15 -10
  227. package/src/index.ts +44 -3
  228. package/src/orchestrator/comparison-identity.ts +1 -0
  229. package/src/orchestrator/config.ts +8 -0
  230. package/src/orchestrator/doctor.ts +125 -3
  231. package/src/orchestrator/harness-catalog-drift.ts +132 -0
  232. package/src/orchestrator/orchestrator.ts +31 -26
  233. package/src/orchestrator/run-dir.ts +8 -1
  234. package/src/orchestrator/run-execution.ts +3 -0
  235. package/src/orchestrator/suite-compare.ts +29 -19
  236. package/src/orchestrator/suite-runs.ts +3 -1
  237. package/src/orchestrator/suite-summary.ts +19 -4
  238. package/lib/drivers/cursor/acp-transport.d.ts.map +0 -1
  239. package/lib/drivers/cursor/acp-transport.js.map +0 -1
  240. package/lib/drivers/cursor/events.d.ts.map +0 -1
  241. package/lib/drivers/cursor/events.js.map +0 -1
  242. package/skills/lux/SKILL.md +0 -89
  243. package/skills/lux/references/cli.md +0 -128
  244. package/skills/lux/references/eval-authoring.md +0 -266
@@ -1,266 +0,0 @@
1
- # Authoring useful Lux evals
2
-
3
- ## Case shape
4
-
5
- A case default-exports `defineEvalCase`:
6
-
7
- ```ts
8
- import { defineEvalCase } from "@prismatic-io/lux";
9
-
10
- export default defineEvalCase({
11
- id: "retry-flag",
12
- prompt: "Add a --retry <n> flag to the fetch command.",
13
- persona: "You are the maintainer. If asked, retries default to 3.",
14
- driver: { name: "codex", config: { model: "YOUR_CODEX_MODEL" } },
15
- assertions: [
16
- { id: "flag-present", type: "file-contains", path: "src/cli.ts", text: "--retry" },
17
- { id: "tests-pass", type: "command-exits-zero", command: "npm test" },
18
- { id: "test-coverage", type: "rubric", criteria: "A test covers the new retry flag." },
19
- ],
20
- meta: { tags: ["cli", "validation"] },
21
- });
22
- ```
23
-
24
- Use the project-level default driver when all cases share it. Case-level
25
- drivers are useful for intentional cross-agent or cross-model comparisons.
26
-
27
- ## Design checklist
28
-
29
- Before writing:
30
-
31
- 1. State the capability or regression in one sentence.
32
- 2. Identify the artifact, command result, or interaction that proves it.
33
- 3. List plausible false positives. Adjust assertions to reject them.
34
- 4. Decide whether the case needs a fixture and whether each run must begin from
35
- an isolated copy.
36
- 5. Identify any question a competent agent must ask. Put only the answer and
37
- relevant preferences in the persona.
38
-
39
- After writing:
40
-
41
- 1. Run `lux doctor`.
42
- 2. List discovery with `lux run <filter> --list`.
43
- 3. Run the case more than once if agent behavior can vary.
44
- 4. Inspect events and artifacts, including failed runs.
45
- 5. Confirm each assertion fails when its requirement is deliberately absent.
46
-
47
- ## Assertion selection
48
-
49
- Prefer deterministic assertions:
50
-
51
- - `run-succeeded`: the driver completed; necessary but rarely sufficient.
52
- - `file-exists`: a required artifact exists.
53
- - `file-contains`: a stable literal is present.
54
- - `json-pointer-equals`: structured output contains the expected value.
55
- - `command-exits-zero`: project-authored validation succeeds.
56
-
57
- Use the more specific bundled evidence checks when they match the contract:
58
-
59
- - Files: `file-matches`, `file-regex-set`, `file-regex-count`, and `glob-count`.
60
- - Output/data: `contains`, `not-contains`, `regex`, and `json-pointer-equals`.
61
- - Interaction: `interrupt-count`, `tool-called`, `tool-called-with`, and
62
- `tool-call-count`; use `by: "main"` or `by: "subagent"` when ownership matters.
63
- - Paired tool evidence: `tool-invocation`, `tool-result-contains`,
64
- `tool-result-json-pointer-equals`, `tool-result-is-error`, and
65
- `no-error-results`. Prefer these when result status or payload matters; a tool
66
- call without a paired result is unresolved, not successful.
67
- - Budgets: `latency-under`, `time-to-first-action-under`, `tokens-under`,
68
- `cost-under`, and `artifact-bytes-under`. Time to first action requires the
69
- driver to emit semantic `action` progress events; use `category: "mutation"`
70
- to exclude queries and outer code-mode executor calls.
71
- - MCP discovery: `server-info-equals`, `tool-listed`,
72
- `tools-listed-count`, and `capability-absent`.
73
-
74
- Most file assertions read captured `artifacts`; set `where: "cwd"` only when
75
- the durable contract intentionally includes the staged run workspace. Use
76
- stable assertion `id` values for repetitions, comparisons, annotations, and
77
- experiments. `weight` affects aggregate score and `threshold` sets an optional
78
- per-assertion score floor.
79
-
80
- Use `rubric` for semantic properties such as design quality, completeness, or
81
- whether a test meaningfully covers behavior. Keep criteria narrow. Avoid words
82
- like “good,” “proper,” or “best practice” without observable conditions.
83
-
84
- Bound rubric evidence to what the criterion needs. Include `tool-result` event
85
- evidence when status matters, and request tool inputs/results only when their
86
- payload is necessary; this controls judge context and cost.
87
-
88
- Persona answering and rubric judging have different difficulty profiles. A
89
- persona usually chooses from facts already supplied in the case, so prefer a
90
- cheap model and low effort. Semantic grading should use a stronger model and
91
- enough effort to distinguish real evidence from plausible prose. Configure
92
- them independently when that tradeoff matters:
93
-
94
- ```ts
95
- // lux.config.ts
96
- defaultAnswerer: {
97
- name: "persona",
98
- config: {
99
- provider: "codex",
100
- model: "YOUR_SMALL_PERSONA_MODEL",
101
- reasoningEffort: "low",
102
- },
103
- },
104
-
105
- // case assertion
106
- {
107
- id: "behavior-quality",
108
- type: "rubric",
109
- criteria: "The tests exercise retry exhaustion and recovery.",
110
- provider: "codex",
111
- model: "YOUR_STRONG_JUDGE_MODEL",
112
- reasoningEffort: "high",
113
- }
114
- ```
115
-
116
- The project `harness` supplies shared defaults to persona and rubric calls;
117
- answerer config and rubric fields override it independently. Always pin model
118
- and effort when comparing runs, and inspect answerer versus judge usage in the
119
- run summary before increasing either budget.
120
-
121
- Assertions should test user-visible behavior and durable contracts. Avoid
122
- requiring a specific function name, file layout, or algorithm unless that is
123
- the contract under evaluation.
124
-
125
- ## Human-in-the-loop behavior
126
-
127
- The persona is simulated user state, not another system prompt. Include:
128
-
129
- - facts the user would know;
130
- - preferences needed to resolve legitimate ambiguity;
131
- - approval boundaries relevant to the task.
132
-
133
- Do not tell the persona how to help the agent solve the task. If no interaction
134
- is part of the capability being evaluated, omit the persona or keep it minimal.
135
-
136
- For Claude Code, use `interactionMode: "defer-resume"` for automated
137
- question-tool handling. Use `textQuestionFallback: true` only when
138
- intentionally evaluating models that ask in prose instead of using the
139
- supported tool. For Codex, keep the default `interactionMode: "app-server"`
140
- when the case can interrupt; compatibility mode `"exec"` cannot accept
141
- mid-run responses.
142
-
143
- Use `--interactive` for a real terminal user or `--claude-answerer` for the
144
- Claude plugin protocol. Both force sequential execution.
145
-
146
- To count only questions about specific concepts, set `kind: "ask"` with
147
- `questionIncludesAll`, `questionIncludesAny`, or `questionExcludesAny` on
148
- `interrupt-count`. Matching is case-insensitive and ignores separators, so
149
- terms such as `"first name"` also match `"firstName"`. Filters compose: the
150
- question must include every `questionIncludesAll` term, at least one
151
- `questionIncludesAny` term, and no `questionExcludesAny` terms.
152
-
153
- ## Project extensions
154
-
155
- For a reusable project-specific assertion, define it with `defineAssertion`
156
- and a direct Zod object whose `type` is a matching literal. Import `z` from Lux,
157
- return an ordinary failed result for missing/invalid product evidence, and
158
- reserve throws or `errorMessage` for evaluator faults. Increment
159
- `pluginVersion` whenever schema or evaluation behavior changes. Prefer the
160
- bounded, traversal-safe `readRunArtifactText` helper over direct filesystem
161
- reads.
162
-
163
- Build a typed case authoring function once instead of importing plugins in
164
- every case:
165
-
166
- ```ts
167
- const assertions = defineAssertionRegistry(projectAssertion);
168
- export const defineEvalCase = defineLuxCase.extend({ assertions });
169
- ```
170
-
171
- Case-bound plugins remain plain serialized plans but require the current case
172
- path for regrading: `lux grade <run> --case <case.ts>`.
173
-
174
- Use `defineFixtures` for Vitest-style suite/case setup around `await use()` or
175
- `defineLifecycleHooks` when cleanup-returning callbacks fit better. Setup runs
176
- in declaration order and teardown in reverse, including failures. Call
177
- `await use()` exactly once. Fixture `value`/`identity` must be public JSON;
178
- keep secrets in the prepared resource or environment. Increment
179
- `pluginVersion` when lifecycle behavior changes. Register globally in
180
- `lux.config.ts`, or attach selectively with
181
- `defineEvalCase.extend({ fixtures: [...] })`.
182
-
183
- Custom drivers that own an in-memory filesystem should persist it with
184
- `writeArtifactSnapshot` from `@prismatic-io/lux/artifact-snapshot`. Snapshots
185
- are bounded, traversal-safe, immutable per name, and can use `baseSnapshot`
186
- for copy-on-write reuse while remaining independently complete. Ordinary file
187
- assertions then grade the indexed files without a snapshot-specific API.
188
-
189
- ## Experiments for prompts, skills, and agent source
190
-
191
- Bind mutable source through `subjectPath()`:
192
-
193
- ```ts
194
- import { defineEvalCase, subjectPath } from "@prismatic-io/lux";
195
-
196
- export default defineEvalCase({
197
- id: "skill-routing",
198
- prompt: `Use the skill at ${subjectPath("plugin/skills/routing/SKILL.md")} to complete the task.`,
199
- assertions: [{ id: "completed", type: "run-succeeded" }],
200
- meta: { tags: ["validation"] },
201
- });
202
- ```
203
-
204
- Campaigns should:
205
-
206
- - restrict `subject.mutable` to the intended source;
207
- - define named, explicit driver/model profiles;
208
- - keep train, validation, and test selectors disjoint;
209
- - budget calls, tokens, cost, and wall time;
210
- - use repetitions and confidence gates appropriate to stochastic outcomes;
211
- - reserve held-out cases for promotion and final confirmation.
212
- - acknowledge every candidate validation command with
213
- `unsafeHostExecution: true`; validators must be observational and must not
214
- mutate the candidate tree.
215
-
216
- A minimal current agent campaign has this shape (selectors are objects, mutable
217
- paths are candidate-relative globs, and budgets use call/token/cost limits):
218
-
219
- ```ts
220
- export default defineExperiment({
221
- id: "skill-improvement",
222
- subject: { root: "..", mutable: ["skills/example/**"] },
223
- profiles: ["claude-low", "codex-low"],
224
- splits: {
225
- train: { tags: ["train"] },
226
- validation: { tags: ["validation"] },
227
- test: { tags: ["test"] },
228
- },
229
- repetitions: { search: 1, promotion: 3 },
230
- objectives: {
231
- constraints: [
232
- { metric: "quality.caseRegressions", max: 0 },
233
- { metric: "quality.passRate", min: 0.8, split: "test" },
234
- ],
235
- minimize: [{ metric: "agent.total" }, { metric: "subject.bytes" }],
236
- },
237
- optimizer: {
238
- algorithm: "reflective",
239
- candidateSelection: "pareto",
240
- promotionTopK: 2,
241
- config: {
242
- provider: "codex",
243
- model: "YOUR_OPTIMIZER_MODEL",
244
- reasoningEffort: "low",
245
- },
246
- },
247
- budget: {
248
- maxCandidates: 4,
249
- patience: 1,
250
- maxMetricCalls: 60,
251
- maxJudgeCalls: 120,
252
- maxProposalCalls: 3,
253
- maxTokens: 2_000_000,
254
- maxCostUsd: 30,
255
- maxUnpricedModelCalls: 0,
256
- maxWallTimeMs: 3_600_000,
257
- },
258
- });
259
- ```
260
-
261
- Use the experiment directory printed by the run for `view` and `report`.
262
- Review its held-out evidence, then pass that same verified directory to
263
- `apply`; do not guess a directory from the campaign ID.
264
-
265
- Use `experiment` for authored variants and `optimize` for model-proposed source
266
- changes. Always run the corresponding `--plan` command first.