orizu 0.5.21 → 0.5.22

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 (41) hide show
  1. package/README.md +9 -6
  2. package/dist/gepa-engine-dispatch.d.ts.map +1 -1
  3. package/dist/gepa-engine-dispatch.js +20 -1
  4. package/dist/gepa-python-paths.d.ts.map +1 -1
  5. package/dist/gepa-python-paths.js +25 -6
  6. package/dist/help.d.ts.map +1 -1
  7. package/dist/help.js +36 -14
  8. package/dist/index.d.ts.map +1 -1
  9. package/dist/index.js +4 -39
  10. package/dist/instruction-set-loader.d.ts.map +1 -1
  11. package/dist/instruction-set-loader.js +57 -5
  12. package/dist/instruction-sets-cli.d.ts +5 -2
  13. package/dist/instruction-sets-cli.d.ts.map +1 -1
  14. package/dist/instruction-sets-cli.js +134 -24
  15. package/dist/skilled-proposer-config.d.ts +2 -0
  16. package/dist/skilled-proposer-config.d.ts.map +1 -0
  17. package/dist/skilled-proposer-config.js +212 -0
  18. package/dist/skilled-proposer-launch.d.ts +4 -0
  19. package/dist/skilled-proposer-launch.d.ts.map +1 -1
  20. package/dist/skilled-proposer-launch.js +65 -1
  21. package/package.json +1 -1
  22. package/src/gepa-engine-dispatch.ts +21 -1
  23. package/src/gepa-python-paths.ts +24 -6
  24. package/src/help.ts +36 -14
  25. package/src/index.ts +6 -53
  26. package/src/instruction-set-loader.ts +55 -5
  27. package/src/instruction-sets-cli.ts +173 -19
  28. package/src/skilled-proposer-config.ts +191 -0
  29. package/src/skilled-proposer-launch.ts +59 -1
  30. package/vendor/orizu-gepa/src/orizu_gepa_connector/engine.py +36 -3
  31. package/vendor/orizu-gepa/src/orizu_gepa_connector/instruction_set_loader.py +31 -3
  32. package/vendor/orizu-gepa/src/orizu_gepa_connector/skilled_proposer_bridge.py +354 -5
  33. package/vendor/skills/orizu-cli/SKILL.md +50 -16
  34. package/vendor/skills/orizu-cli/references/building-judges.md +2 -2
  35. package/vendor/skills/orizu-cli/references/cli-reference.md +57 -28
  36. package/vendor/skills/orizu-cli/references/instructions-after-prompts.md +120 -0
  37. package/vendor/skills/orizu-cli/references/migrate-existing-gepa-setup.md +109 -49
  38. package/vendor/skills/orizu-cli/references/optimization-reports.md +16 -11
  39. package/vendor/skills/orizu-cli/references/optimization-with-gepa.md +29 -28
  40. package/vendor/skills/orizu-cli/references/primer.md +21 -5
  41. package/vendor/skills/orizu-cli/references/prompt-control-plane.md +132 -85
@@ -80,23 +80,39 @@ orizu projects create --name "Quality Eval" --team my-team
80
80
  ### Instruction sets
81
81
 
82
82
  ```bash
83
- orizu instruction-sets list --project my-team/quality-eval [--status active|archived|all] [--json]
84
- orizu instruction-sets show <set> --project my-team/quality-eval [--status active|archived|all] [--json]
85
- orizu instruction-sets create ./orizu.instruction-set.json --project my-team/quality-eval [--runner-version <id>] [--model-config <identity>] [--json]
86
- orizu instruction-sets push ./orizu.instruction-set.json --project my-team/quality-eval [--runner-version <id>] [--json]
87
- orizu instruction-sets sync <set> --out ./instructions --project my-team/quality-eval [--model-config <identity>] [--json]
88
- orizu instruction-sets profiles new <set> --project my-team/quality-eval --model-config <identity> [--json]
89
- orizu instruction-sets profiles promote <set> --project my-team/quality-eval --model-config <identity> --version <n> [--json]
90
- orizu instruction-sets profiles rollback <set> --project my-team/quality-eval --model-config <identity> --to <n> [--json]
91
- orizu instruction-sets default show <set> --project my-team/quality-eval [--json]
92
- orizu instruction-sets default move <set> --project my-team/quality-eval --model-config <identity> --version <n> [--json]
93
- orizu instruction-sets shape add <set> --project my-team/quality-eval --key <key> --from <manifest> [--json]
94
- orizu instruction-sets shape remove <set> --project my-team/quality-eval --key <key> [--json]
83
+ orizu instructions list --project my-team/quality-eval [--status active|archived|all] [--json]
84
+ orizu instructions show <set> --project my-team/quality-eval [--status active|archived|all] [--json]
85
+ # Human/local CLI only: a human runs create/push; hosted agents may run profiles new and sync.
86
+ orizu instructions create ./orizu.instruction-set.json --project my-team/quality-eval [--runner-version <id>] [--model-config <identity>] [--json]
87
+ orizu instructions push ./orizu.instruction-set.json --project my-team/quality-eval [--set <slug-or-exact-name>] [--runner-version <id>] [--json]
88
+ orizu instructions sync <set> --out ./instructions --project my-team/quality-eval [--model-config <identity>] [--json]
89
+ orizu instructions profiles new <set> --project my-team/quality-eval --model-config <identity> [--json]
90
+ # Human/local CLI only: profile production-pointer moves.
91
+ orizu instructions profiles promote <set> --project my-team/quality-eval --model-config <identity> --version <n> [--json]
92
+ orizu instructions profiles rollback <set> --project my-team/quality-eval --model-config <identity> --to <n> [--json]
93
+ orizu instructions default show <set> --project my-team/quality-eval [--json]
94
+ # Human/local CLI only: the set-wide default-pointer move.
95
+ orizu instructions default move <set> --project my-team/quality-eval --model-config <identity> --version <n> [--json]
96
+ # Human/local CLI only: shape mutations.
97
+ orizu instructions shape add <set> --project my-team/quality-eval --key <key> --from <manifest> [--json]
98
+ orizu instructions shape remove <set> --project my-team/quality-eval --key <key> [--json]
99
+ # Human/local CLI only: visibility mutations.
100
+ orizu instructions archive <slug-or-exact-name> --project my-team/quality-eval [--json]
101
+ orizu instructions restore <slug-or-exact-name> --project my-team/quality-eval [--json]
95
102
  ```
96
103
 
97
- `list` returns each instruction set and its ordered shape. `show` returns the
98
- default and every model-config profile's production state. `create` and `push`
99
- read a local manifest; JSON output is one document per line.
104
+ `instructions` is the customer-facing command namespace. The legacy
105
+ `instruction-sets` spelling remains a compatibility alias, but new workflows
106
+ should not teach it. A set can be addressed by its stable slug or exact name;
107
+ the slug does not change when the display name changes. `list` returns each
108
+ instruction set and its ordered shape. `show` returns the default and every
109
+ model-config profile's production state. Use `--status archived` or `--status
110
+ all` to include archived sets. A human curator runs create, push, shape,
111
+ archive, and restore mutations from the local CLI with a user token. Archive
112
+ and restore change visibility only:
113
+ archived sets continue to resolve and sync. `create` and `push` read a local
114
+ manifest; JSON output is one document per line. `push --set` updates the named
115
+ or slug-addressed set independently of the manifest's display name.
100
116
 
101
117
  `profiles new` copies the default component map into a model-config profile without
102
118
  changing its production resolution; hosted agents may create this seed because
@@ -117,18 +133,28 @@ the default or a production label. The set does not resolve for affected model
117
133
  configs until those pointers move to the new shape-change profile versions; the
118
134
  text CLI prints the required follow-up commands.
119
135
 
120
- The manifest is a JSON object with `name`, ordered `shape`, and `components`.
121
- Every component supplies `{ key, text }` or `{ key, path }`; paths are relative
122
- to the manifest. Set-wide components must cover the complete shape. A component
123
- may add `modelConfig` for a profile override: `create` materializes that named
124
- profile with the set-wide component map plus its overrides, while `push` updates named
136
+ The manifest is a JSON object with `name`, optional unversioned `description`,
137
+ ordered `shape`, and `components`. The description belongs to the instruction
138
+ set rather than any profile and round-trips through sync. Every component
139
+ supplies `{ key, text }` or `{ key, path }`; paths are relative to the manifest.
140
+ Set-wide components must cover the complete shape. A component may add
141
+ `modelConfig` for a profile override: `create` materializes that named profile
142
+ with the set-wide component map plus its overrides, while `push` updates named
125
143
  profiles already present on the set. `push` refuses a manifest whose shape
126
144
  differs from the stored set.
127
145
 
128
- `sync` writes `<out>/<set>/manifest.json`, `default/<key>.md`, and
146
+ `sync` writes `<out>/<stable-set-slug>/manifest.json`, `default/<key>.md`, and
129
147
  `profiles/<identity-slug>/<key>.md` for offline execution. TypeScript runners
130
- use `loadInstructionSet(dir, name, modelConfigIdentity)` from `orizu`; Python
131
- runners use `orizu_gepa_connector.instruction_set_loader.load_instruction_set`.
148
+ use `loadInstructionSet(dir, setReference, modelConfigIdentity)` from `orizu`;
149
+ Python runners use
150
+ `orizu_gepa_connector.instruction_set_loader.load_instruction_set`. Prefer the
151
+ stable slug as `setReference`; both loaders also resolve the manifest's exact
152
+ name for compatibility with directories synced before slugs shipped. The
153
+ manifest's immutable `projectId` and `instructionSetId` prevent a shared
154
+ `--out` root from replacing another project's same-slug set.
155
+ Identity-less pre-slug trees cannot prove project ownership and are preserved;
156
+ sync returns `instruction_set_sync_legacy_identity_required` until the operator
157
+ moves the old tree aside or selects a clean output root.
132
158
  Both select that model config's production component map or the default without a
133
159
  network call. Git-pinned components have no local bytes: loading one raises
134
160
  `instruction_set_component_unavailable` until the runner supplies those bytes.
@@ -347,9 +373,12 @@ Defaults:
347
373
  - format defaults to `jsonl`
348
374
  - output file defaults to `<taskId>.<format>`
349
375
 
350
- ### Prompt Control Plane
376
+ ### Instruction Control Plane
351
377
 
352
- For prompts, judges, runners, run submission, optimizer artifacts, live event logging, and accepted-candidate promotion, read `prompt-control-plane.md`. For markdown reports attached to optimization runs, read `optimization-reports.md`.
378
+ For instruction sets, judges, runners, run submission, optimizer artifacts,
379
+ live event logging, and accepted-candidate promotion, read
380
+ `prompt-control-plane.md`. For markdown reports attached to optimization runs,
381
+ read `optimization-reports.md`.
353
382
 
354
383
  Diff-comment export:
355
384
 
@@ -381,7 +410,7 @@ exist.
381
410
  Optimization trace commands:
382
411
 
383
412
  ```bash
384
- orizu optimizations run-gepa ... [--scorer-input-contract gepa|flat_row] [--scorer-candidate-field <row-field>] [--allow-degenerate-seed] [--candidate-selection-strategy pareto|current_best|epsilon_greedy] [--epsilon N] [--objective <text>] [--candidate-proposer skilled-proposer] [--proposal-max-calls N] [--proposal-max-tokens N] [--python <command>] [--num-threads auto|N] [--reflection-retry-attempts 3] [--reflection-http-timeout-seconds 180] [--log-dir logs] [--no-local-log]
413
+ orizu optimizations run-gepa ... [--scorer-input-contract gepa|flat_row] [--scorer-candidate-field <row-field>] [--allow-degenerate-seed] [--candidate-selection-strategy pareto|current_best|epsilon_greedy] [--epsilon N] [--objective <text>] [--candidate-proposer skilled-proposer] [--candidate-proposer-config @file] [--proposal-max-calls N] [--proposal-max-tokens N] [--python <command>] [--num-threads auto|N] [--reflection-retry-attempts 3] [--reflection-http-timeout-seconds 180] [--log-dir logs] [--no-local-log]
385
414
  orizu optimizations export <optimization-run-id> --out ./optimization.json
386
415
  orizu optimizations export <optimization-run-id> --json
387
416
  ```
@@ -390,7 +419,7 @@ Behavior:
390
419
  - `run-gepa` sends the scorer runner a GEPA-shaped row (`{source_row, candidate_output, …}`) by default. Judge runners written for flat-row score runs (`runners exec --scorer-version`) need `--scorer-input-contract flat_row` (plus `--scorer-candidate-field <row-field>` when the judge reads the candidate output from a named row field) or they silently score everything 0. `run-gepa` validates the contract on the seed at launch and refuses a uniformly-worst seed unless `--allow-degenerate-seed` is set. See `prompt-control-plane.md` ("Scorer-Runner Input Contracts").
391
420
  - `run-gepa` defaults `--num-threads` to `auto`, resolving a row-evaluation parallelism cap from mini-batch size, validation-set size, 2x CPU count, memory estimate, file-descriptor limit, and a 64-thread default ceiling. Set `ORIZU_GEPA_AUTO_THREADS_MAX` or use `--num-threads <n>` only when the runner/provider capacity is known.
392
421
  - `run-gepa` retries transient reflection-provider failures by default. If retries are exhausted, it logs `reflection_failed`, counts that reflection proposal against budget, and continues with the next iteration.
393
- - The skilled proposer is official-engine-only and prepares its managed Python environment on the selected run. Flag validation, proposal budgets, and recovery: `prompt-control-plane.md` ("Skilled proposer").
422
+ - The skilled proposer is official-engine-only and prepares its managed Python environment on the selected run. `--candidate-proposer-config @file` adds explicit skills/guidance and requires that selection; the selection itself is incompatible with `--reflection-prompt-template`. Schema, proposal budgets, and recovery: `prompt-control-plane.md` ("Skilled proposer").
394
423
  - `run-gepa` writes a complete local trace under `logs/<optimization_run_id>` by default.
395
424
  - The local trace is the best artifact for coding-agent analysis because it includes full rows, outputs, scores, feedback, scorer responses, reflection prompts, reflection responses, candidate text, and `result.json`.
396
425
  - `optimizations export` writes a portable JSON artifact from server data when the local log is unavailable or the run happened elsewhere.
@@ -481,7 +510,7 @@ Worker assignment reads are self-only:
481
510
  - Use `tasks status` and `tasks export` for operator-side reporting.
482
511
  ### Offline instruction-set sync
483
512
 
484
- `orizu instruction-sets sync <set> --project <team/project> --out <dir>` writes
513
+ `orizu instructions sync <set> --project <team/project> --out <dir>` writes
485
514
  an atomic local manifest. A resolver failure for either the default or any
486
515
  selected profile refuses the entire sync as `instruction_set_unresolvable`; the
487
516
  route never silently downgrades a failed production component map to default bytes. A
@@ -0,0 +1,120 @@
1
+ # Instructions After Prompts
2
+
3
+ Use instruction sets for customer-owned model instructions. The older prompt
4
+ read surface remains available for locating legacy artifacts, but standalone
5
+ prompt content and production mutations deliberately redirect to `orizu
6
+ instructions`.
7
+
8
+ ## Find Existing Material
9
+
10
+ Legacy prompts appear as one-component sets in the instruction inventory:
11
+
12
+ ```bash
13
+ orizu instructions list --project <team/project> --status all --json
14
+ orizu instructions show <slug-or-exact-name> --project <team/project> --status all --json
15
+ ```
16
+
17
+ Use prompt reads only when you need to correlate an old prompt identifier or
18
+ download its files:
19
+
20
+ ```bash
21
+ orizu prompts list --project <team/project> --status all
22
+ orizu prompts pull <prompt-id-or-name> --project <team/project> --out ./legacy-prompt
23
+ ```
24
+
25
+ The text output ends with the owning instruction set's stable slug and
26
+ component key. List and pull include the prompt display name and identifier:
27
+
28
+ ```text
29
+ Owner: Generator (prompt-1) -> planner-agent / system
30
+ ```
31
+
32
+ Use the slug after `->` for instruction commands and the final segment for the
33
+ component key. Address scorer bindings directly with that instruction-set slug
34
+ and component key. An ownerless judge or draft prompt may have no owner line.
35
+
36
+ ## Understand Deliberate Refusals
37
+
38
+ Standalone prompt content, production-pointer mutations, and prompt-addressed
39
+ scorer bindings fail before making a request. The CLI prints these exact
40
+ replacements:
41
+
42
+ - `Use: orizu instructions push <manifest> --project <team/project>`
43
+ - `Use: orizu instructions archive <slug-or-exact-name> --project <team/project>`
44
+ - `Use: orizu instructions restore <slug-or-exact-name> --project <team/project>`
45
+ - `Use: orizu instructions profiles promote <set> --project <team/project> --model-config <identity> --version <n>`
46
+ - `Use: orizu instructions scorers set-headline <set> --key <component-key> --scorer-version <id> --project <team/project>`
47
+ - `Use: orizu instructions scorers add <set> --key <component-key> --scorer-version <id> --project <team/project>`
48
+
49
+ Older clients and direct API callers can reach two additional server-side
50
+ prompt-write conflicts. Both fail closed with an exact JSON error:
51
+
52
+ | Write path | Conflict | Measured response | Next action |
53
+ | --- | --- | --- | --- |
54
+ | Sessionless prompt registration from an older client or direct API call | The name has set-owned storage and no ownerless lineage. | 409 — `Use: orizu instructions push; prompt name belongs to an instruction set` | Use the owning set's manifest through `orizu instructions`; the current CLI redirects before HTTP. |
55
+ | Session-scoped prompt draft (`prompts push ... --session ...`) | The name belongs to components in more than one instruction set and has no ownerless lineage. | 409 — `session draft prompt name is ambiguous across instruction sets` | Do not guess by name. Inventory the sets and component keys, then prepare the intended instruction-set manifest. |
56
+
57
+ These client redirects and server conflicts do not apply to prompt reads, judge
58
+ artifacts, prompt reports, instruction-addressed scorer bindings, unambiguous
59
+ session-scoped drafts, or non-production prompt labels.
60
+
61
+ ## Agent preparation
62
+
63
+ From a hosted session, inventory every active and archived set, choose a stable
64
+ target name, component keys, model-config profiles, and complete component
65
+ text, then prepare a manifest such as:
66
+
67
+ ```json
68
+ {
69
+ "name": "planner-agent",
70
+ "description": "Instructions used by the planner agent.",
71
+ "shape": ["system", "tools"],
72
+ "components": [
73
+ { "key": "system", "path": "./system.md" },
74
+ { "key": "tools", "path": "./tools.md" }
75
+ ]
76
+ }
77
+ ```
78
+
79
+ Commit or otherwise hand the complete manifest and its component files to the
80
+ human curator. Do not run an instruction-set mutation from the hosted session.
81
+
82
+ ## Human-run consolidation
83
+
84
+ Consolidation changes ownership and visibility, so a human curator must run it
85
+ from the local CLI with a user token. Create the consolidated set and inspect
86
+ its complete profiles before changing any pointer:
87
+
88
+ ```bash
89
+ # Human/local CLI only: a human curator with a user token runs this mutation.
90
+ orizu instructions create ./orizu.instruction-set.json --project <team/project> --model-config <identity> --json
91
+ orizu instructions show <slug-or-exact-name> --project <team/project> --status all --json
92
+ ```
93
+
94
+ After verifying the new set, the human archives each redundant one-component
95
+ set. Archive changes visibility only; the archived set still resolves and
96
+ syncs until the human pointer move is complete, so it remains a recovery
97
+ source.
98
+
99
+ ```bash
100
+ # Human/local CLI only: a human curator with a user token runs this mutation.
101
+ orizu instructions archive <slug-or-exact-name> --project <team/project> --json
102
+ ```
103
+
104
+ The human must explicitly move the consolidated set's default or promote a
105
+ named model-config profile. Coding agents stop after preparing the manifest and
106
+ handoff details rather than running these commands:
107
+
108
+ ```bash
109
+ # Human/local CLI only: the human curator moves these pointers.
110
+ orizu instructions default move <set> --project <team/project> --model-config <identity> --version <n> --json
111
+ orizu instructions profiles promote <set> --project <team/project> --model-config <identity> --version <n> --json
112
+ ```
113
+
114
+ The human confirms the resolved default and every production profile after the
115
+ move. If a redundant set must become visible again, the human restores it:
116
+
117
+ ```bash
118
+ # Human/local CLI only: a human curator with a user token runs this mutation.
119
+ orizu instructions restore <slug-or-exact-name> --project <team/project> --json
120
+ ```
@@ -1,22 +1,29 @@
1
1
  # Migrating an existing GEPA setup into Orizu
2
2
 
3
3
  For a customer already running official GEPA from a plain script — inline
4
- `trainset`/`valset`, a seed prompt in a dict, their own `metric(row, output)`.
4
+ `trainset`/`valset`, seed component values in a dict, and their own
5
+ `metric(row, output)`. The dict becomes one instruction-set profile: its keys
6
+ become the set's fixed shape, and its values become that profile's components.
7
+ Use `orizu instructions` as the only creation and update path for those
8
+ customer-owned instructions. A coding agent prepares the complete manifest;
9
+ a human curator runs its mutations from the local CLI with a user token.
5
10
 
6
11
  The ordering rule: **nothing is optimized until parity is proven.** The last
7
12
  step before `run-gepa` is always `orizu scorers verify-parity`, which runs the
8
13
  migrated scorer runner under the exact payload `run-gepa` sends it and the
9
14
  customer's original metric over the same rows, and exits 0 only if they agree.
10
15
 
11
- Commands are shown with `--local`; drop it against a hosted server.
16
+ Commands are shown with `--local`; drop it against a hosted server except for
17
+ instruction-set mutations and pointer moves marked human-only, which a hosted
18
+ agent prepares but never executes.
12
19
 
13
20
  ## 0. Read their script
14
21
 
15
22
  Note the row shape and which field is the stable id, `trainset`/`valset`
16
- membership, the seed candidate text, the metric's `module:function`, and what
17
- it returns (a float, a dict with `score`, or GEPA's `EvaluationResult` — all
18
- three are accepted; `objective_scores` is ignored). If rows have no stable id,
19
- add one now: every step below pairs on it.
23
+ membership, the seed component map, the metric's `module:function`, and what it
24
+ returns (a float, a dict with `score`, or GEPA's `EvaluationResult` — all three
25
+ are accepted; `objective_scores` is ignored). If rows have no stable id, add
26
+ one now: every step below pairs on it.
20
27
 
21
28
  ## 1. Set up, then export the rows
22
29
 
@@ -69,35 +76,48 @@ orizu --local datasets splits create <dataset-version-id> \
69
76
  `--from-file` preserves their partitions; the ratio flags
70
77
  (`--train/--validation/--test`) resample and must not be used here.
71
78
 
72
- ## 3. Candidate runner and seed prompt
79
+ ## 3. Candidate runner and seed instruction set
73
80
 
74
- The candidate runner does what `task_lm` did: candidate prompt + row -> output.
81
+ The candidate runner does what `task_lm` did: candidate profile + row ->
82
+ output. A one-component profile keeps the single-body runner contract. For a
83
+ multi-component profile, read the complete map from
84
+ `input["instruction_set"]["components"]`; components belong only to this
85
+ profile and are never shared across profiles or sets.
75
86
 
76
87
  ```bash
77
88
  orizu --local runners push ./candidate-runner \
78
89
  --project <team>/<project> --name gepa-candidate-runner --label default --json
79
90
 
80
- orizu --local prompts push ./prompt \
81
- --project <team>/<project> --runner-version <candidate-runner-version-id> --json
91
+ # Human/local CLI only: a human curator with a user token runs this mutation.
92
+ orizu --local instructions create ./orizu.instruction-set.json \
93
+ --project <team>/<project> \
94
+ --runner-version <candidate-runner-version-id> \
95
+ --model-config <provider/model> --json
82
96
  ```
83
97
 
84
- `./prompt` holds `orizu.prompt.json` plus the body file it names. Only `name`
85
- is enforced (`app/api/cli/prompts/route.ts:220-221`); `body_file` defaults to
86
- `prompt.md`, `body_kind` to `text` (`packages/cli/src/index.ts:3966-3985`) and
87
- `provider_settings` to `{}`. Write all four anyway — a migration whose model
88
- settings are implicit is a migration nobody can reproduce:
98
+ The manifest carries the instruction set's `name`, human-readable
99
+ `description`, fixed `shape`, and component values. Put each original dict
100
+ value in a file without changing its bytes. This one-component example maps
101
+ the old `system` key to `system.md`:
89
102
 
90
103
  ```json
91
104
  {
92
- "name": "gepa-seed-prompt",
93
- "body_file": "prompt.md",
94
- "body_kind": "text",
95
- "provider_settings": { "model": "claude-sonnet-4-6", "temperature": 0 }
105
+ "name": "gepa-agent-instructions",
106
+ "description": "Instructions for the migrated GEPA application",
107
+ "shape": ["system"],
108
+ "components": [
109
+ { "key": "system", "path": "./system.md" }
110
+ ]
96
111
  }
97
112
  ```
98
113
 
99
- `prompt.md` carries their seed candidate text verbatim. Returns the seed
100
- `prompt_version_id`.
114
+ For a multi-component seed, list every original key once in `shape`, in stable
115
+ order, and add one component entry per key. `--model-config` selects the
116
+ profile whose seed is created; it must name an existing model config with the
117
+ same settings used by the original script. The JSON result includes the set's
118
+ stable `slug` and its default profile version. Record the slug — later reads,
119
+ optimization, archiving, and restoration should use it even if the display
120
+ name changes.
101
121
 
102
122
  ## 4. Wrap their metric in a scorer runner
103
123
 
@@ -157,12 +177,12 @@ def metric(row, model_output): # what verify-parity calls
157
177
  orizu --local runners push ./scorer-runner \
158
178
  --project <team>/<project> --name gepa-scorer-runner --label default --json
159
179
 
160
- orizu --local prompts push ./scorer-prompt \
180
+ orizu --local judges push ./judge \
161
181
  --project <team>/<project> --runner-version <scorer-runner-version-id> --json
162
182
 
163
183
  orizu --local scorers register --project <team>/<project> \
164
184
  --name gepa-migrated-metric --manifest ./scorer.manifest.json \
165
- --prompt-version <scorer-prompt-version-id> \
185
+ --prompt-version <judge-version-id> \
166
186
  --runner-version <scorer-runner-version-id> \
167
187
  --label production --json # -> scorer_version_id
168
188
  ```
@@ -180,29 +200,39 @@ or `metric_key`, and `mode` must be `row` or `set`:
180
200
  }
181
201
  ```
182
202
 
183
- `prompt_runner` is the only kind `runners exec --scorer-version` and
184
- `verify-parity` can execute, and it requires a backing prompt version. For a
185
- pure-code metric with no judge text, `./scorer-prompt` is a short prompt
186
- version documenting the rubric; the runner never reads its body.
203
+ `prompt_runner` is the only implementation kind that `runners exec
204
+ --scorer-version` and `verify-parity` can execute, and the scorer contract
205
+ currently names its backing judge artifact with `--prompt-version`. That flag
206
+ receives the `prompt_version_id` returned by `orizu judges push`; do not replace
207
+ the judge command with a standalone prompt mutation.
187
208
 
188
- ## 5. Produce `outputs.jsonl` by running the seed once
209
+ For an LLM metric, `./judge` contains the evaluator rubric the scorer runner
210
+ executes. For a pure-code metric, keep a short judge rubric that documents the
211
+ deterministic rule and expected output, even though the runner does not read
212
+ its body. The judge is the evaluator artifact; the scorer is the metric
213
+ contract that gives its numeric result a name, mode, and direction.
189
214
 
190
- A scorer scores *(row, output)*, so parity needs one candidate output per row.
215
+ ## 5. Freeze the original setup's outputs
191
216
 
192
- ```bash
193
- orizu --local runners exec \
194
- --prompt-version <seed-prompt-version-id> \
195
- --runner-version <candidate-runner-version-id> \
196
- --dataset-version <dataset-version-id> \
197
- --split-set <split-set-id> --split validation \
198
- --out ./results.jsonl
217
+ A scorer scores *(row, output)*, so parity needs one candidate output per row.
218
+ Use the customer's existing script to run its original `task_lm` once with
219
+ the unchanged seed component map, and record the exact output passed to
220
+ `metric(row, output)`. Write one file per partition. Each JSONL row is:
199
221
 
200
- jq -c '{row_id: .row_id, model_output: .model_response}' ./results.jsonl > ./outputs.jsonl
222
+ ```json
223
+ {"row_id":"<the row's stable id>","model_output":"<the exact output>"}
201
224
  ```
202
225
 
203
- `outputs.jsonl` must cover exactly the rows being checked: a missing or extra
204
- `row_id`, a duplicate, or a non-string `model_output` is refused before
205
- anything runs.
226
+ Do not produce this evidence by running the migrated scorer or by starting an
227
+ optimization. The output is a fixed subject shared by the original metric and
228
+ the migrated scorer, so a mismatch isolates the scorer migration rather than
229
+ mixing in candidate-runner or provider drift. After scorer parity is proven,
230
+ characterize the candidate runner separately against these same rows before
231
+ starting GEPA.
232
+
233
+ Each partition's output file must cover exactly the rows being checked: a
234
+ missing or extra `row_id`, a duplicate, or a non-string `model_output` is
235
+ refused before anything runs.
206
236
 
207
237
  ## 6. Prove parity
208
238
 
@@ -211,7 +241,7 @@ orizu --local scorers verify-parity \
211
241
  --scorer-version <scorer-version-id> \
212
242
  --dataset-version <dataset-version-id> \
213
243
  --split-set <split-set-id> --split validation \
214
- --outputs ./outputs.jsonl \
244
+ --outputs ./outputs-validation.jsonl \
215
245
  --original metric:metric \
216
246
  --json
217
247
  ```
@@ -237,9 +267,9 @@ orizu --local scorers verify-parity \
237
267
  the registered runner version; drifted bytes exit 2.
238
268
  - `--limit <n>` checks the first N rows of the partition — a smoke check, not
239
269
  the proof: it always reports `parity: false` with `scope: {compared, total}`,
240
- so a limited run can never be mistaken for a full one. The same full
241
- `outputs.jsonl` works: outputs must cover the limited rows and belong to the
242
- split, and need not be trimmed to N.
270
+ so a limited run can never be mistaken for a full one. The full partition's
271
+ output file works: outputs must cover the limited rows, belong to the split,
272
+ and need not be trimmed to N.
243
273
  - A repeated option takes its LAST value, matching run-gepa's scalar options.
244
274
  - If a sampled row already has the candidate field as a key, the command exits 2
245
275
  rather than overwriting a value the original metric reads.
@@ -257,7 +287,8 @@ optimizes the wrong thing, and every number afterwards is wrong.
257
287
  proposals: a scorer that agrees on validation but diverges on a training row
258
288
  that exercises a different schema branch changes the experiment's result while
259
289
  passing this gate. Repeat steps 5 and 6 with `--split train` (its own
260
- `outputs.jsonl` from the same seed run) and require exit 0 on both.
290
+ `outputs-train.jsonl` from the same frozen seed evaluation) and require exit 0
291
+ on both.
261
292
 
262
293
  A `parity: true` report means every row of that partition was compared and
263
294
  agreed. A limited run reports `parity: false` with
@@ -273,7 +304,9 @@ orizu --local optimizers push ./optimizer \
273
304
  orizu --local optimizations run-gepa \
274
305
  --project <team>/<project> \
275
306
  --optimizer-version-id <optimizer-version-id> \
276
- --candidate-version-id <seed-prompt-version-id> \
307
+ --instruction-set <instruction-set-slug> \
308
+ --model-config <provider/model> \
309
+ --component-selector round-robin \
277
310
  --runner-version-id <candidate-runner-version-id> \
278
311
  --candidate-runner-dir ./candidate-runner \
279
312
  --scorer-version-id <scorer-version-id> \
@@ -294,10 +327,37 @@ reflection model is refused at launch without it
294
327
  `packages/orizu-gepa/src/orizu_gepa_connector/runtime.py:193-196`). Drop it only
295
328
  if you also pass an `openai/...` `--reflection-model`.
296
329
 
330
+ `--instruction-set` and `--model-config` select exactly one profile. The CLI
331
+ uses that profile's production version when it has one and otherwise uses the
332
+ set default; it refuses the legacy `--candidate-version-id` selector when the
333
+ instruction-set selectors are present. `round-robin` updates one component per
334
+ round; use `--component-selector all` only when every component should be
335
+ reflected on each round.
336
+
297
337
  `./optimizer` needs `manifest.json` with `"optimizer_family": "gepa"`. See
298
338
  `references/optimization-with-gepa.md` for reflection-model and budget flags.
299
339
  Pass `--scorer-candidate-field <field>` here too if you passed it to
300
340
  `verify-parity`: the payload the runner sees must be the one parity was proven
301
- under. Afterwards, `orizu optimizations promote <run-id> --candidate <id>
302
- --label production` promotes the winner — and with parity proven, its score is
303
- comparable to the seed score their own script reports.
341
+ under. Afterwards, promote only a candidate that passed held-out validation.
342
+ Copy the accepted candidate's complete component map back into the manifest's
343
+ files, then prepare the exact commands for one new version of the selected
344
+ profile. Both the push and the profile promotion are human-only: a coding agent
345
+ prepares the validated manifest and exact handoff commands, but a human curator
346
+ runs both from the local CLI with a user token.
347
+
348
+ ```bash
349
+ # Human/local CLI only: a human curator with a user token runs this mutation.
350
+ orizu --local instructions push ./orizu.instruction-set.json \
351
+ --project <team>/<project> --set <instruction-set-slug> \
352
+ --runner-version <candidate-runner-version-id> --json
353
+
354
+ # Human/local CLI only: the human curator moves the production pointer.
355
+ orizu --local instructions profiles promote <instruction-set-slug> \
356
+ --project <team>/<project> --model-config <provider/model> \
357
+ --version <new-profile-version-number> --json
358
+ ```
359
+
360
+ The push creates a complete profile version. After the human promotion, only
361
+ that profile's production pointer has moved; a component is never promoted by
362
+ itself. With parity proven, its score is comparable to the seed score their own
363
+ script reports.
@@ -5,12 +5,12 @@ Use this reference when writing the markdown report attached to an Orizu optimiz
5
5
  Attach the final markdown with:
6
6
 
7
7
  ```bash
8
- orizu optimizations finish <run-id> --best-candidate <candidate-id> --report-file ./reports/<run-id>.md
8
+ orizu optimizations finish <run-id> --best-candidate <candidate-id> --result-prompt-version <prompt-version-id> --report-file ./reports/<run-id>.md
9
9
  orizu optimizations fail <run-id> --reason "<reason>" --report-file ./reports/<run-id>.md
10
10
  orizu optimizations cancel <run-id> --reason "<reason>" --report-file ./reports/<run-id>.md
11
11
  ```
12
12
 
13
- For budget-exhausted runs, `run-gepa` pauses the optimization before auto-promotion. Write the report from the paused run, then manually finish with `--best-candidate`, `--result-prompt-version` if promoted, and `--report-file` once the decision is made.
13
+ For budget-exhausted runs, `run-gepa` pauses the optimization before auto-promotion. Coding agents may write the report and finish the paused run with `--best-candidate`, `--result-prompt-version` if the candidate version already exists, and `--report-file`. Finishing records the outcome but does not move a serving pointer. Only the pointer-moving `optimizations promote --label production` form is human-only; prepare that command for a human curator to run.
14
14
 
15
15
  ## Source Artifacts
16
16
 
@@ -30,7 +30,7 @@ Read them in this order:
30
30
 
31
31
  1. `result.json` for seed score, best score, best candidate id/text, promotion id, and budget state.
32
32
  2. `evaluations.jsonl` for fixed rows, regressions, persistent failures, per-row feedback, latency, cost, and cache state.
33
- 3. `reflections.jsonl` for what the reflection model saw and why each child prompt was proposed.
33
+ 3. `reflections.jsonl` for what the reflection model saw and why each child candidate was proposed.
34
34
  4. `events.jsonl` for iteration order, candidate lineage, Pareto updates, budget events, pauses, failures, and promotions.
35
35
 
36
36
  If local logs are unavailable, export the server-side archive:
@@ -52,17 +52,22 @@ Include:
52
52
  - The headline scorer name, metric key, split, scorer version, and dataset split.
53
53
  - For judge alignment, prefer Cohen's kappa as the headline metric when labels are imbalanced. Kappa has an interpretable zero point: 0 is chance agreement, negative is worse than chance, and positive means real discrimination.
54
54
  - Always include the confusion matrix alongside kappa. On small validation sets, the matrix movement often matters more than the single estimate.
55
- - Promoted prompt version id, promotion label, and Orizu dashboard link when available.
55
+ - Promoted instruction-set profile version, model config, set slug, and Orizu dashboard link when available.
56
56
  - Small-n uncertainty note when `n < 30`. For example, at `n = 15`, a rough kappa standard error can be about +/- 0.25, so call out directional signals rather than overclaiming precision.
57
57
 
58
58
  ### 2. What The Optimizer Changed
59
59
 
60
60
  Summarize the seed body -> best body diff in bullets rather than pasting a full raw diff. For each notable change, mark it as:
61
61
  - Targeted fix: addresses a specific failure cluster found in train/validation feedback.
62
- - General restructure: reorganizes the prompt, output contract, or reasoning order.
62
+ - General restructure: reorganizes the selected component, output contract, or reasoning order.
63
63
  - Over-correction risk: may improve one cluster while hurting another.
64
64
 
65
- When the reflection model added the same rules you were about to hand-write, do not hand-edit the seed just to feel useful. If GEPA can see and fix the failure from train examples, the next move is usually more budget, better feedback, or better data, not manual prompt patching. Hand-edit only when the optimizer cannot see the failure mode, such as zero train examples for that category.
65
+ When the reflection model added the same rules you were about to write, do not directly edit the seed component just to feel useful. If GEPA can see and fix the failure from train examples, the next move is usually more budget, better feedback, or better data, not an unmeasured component patch. When the optimizer cannot see the failure mode, such as zero train examples for that category, update the selected component in the complete instruction-set manifest, then hand that manifest and the exact push command to a human curator:
66
+
67
+ ```bash
68
+ # Human/local CLI only: a human curator with a user token runs this mutation.
69
+ orizu instructions push <manifest> --project <team/project> --set <slug-or-exact-name> --json
70
+ ```
66
71
 
67
72
  ### 3. Per-Row Outcome Decomposition
68
73
 
@@ -72,7 +77,7 @@ Decompose validation or held-out outcomes:
72
77
  - Persistent failures: wrong before and after. Classify each as one of:
73
78
  - Data gap: failure mode underrepresented or absent in train.
74
79
  - Contested gold: label or rationale appears questionable and needs human re-review.
75
- - Beyond prompt scope: the failure needs tools, state, retrieval, or reasoning outside this prompt.
80
+ - Beyond instruction scope: the failure needs tools, state, retrieval, or reasoning outside this instruction set.
76
81
  - Calibration overshoot: instructions pushed too far in one direction.
77
82
 
78
83
  For judge optimization, include flag/ok recall and precision alongside the confusion matrix. A jump in rare-class recall can be more important than a modest kappa movement.
@@ -82,7 +87,7 @@ For judge optimization, include flag/ok recall and precision alongside the confu
82
87
  Report:
83
88
  - Pareto frontier size. A frontier of 1 or 2 means limited parent diversity.
84
89
  - Acceptance rate by iteration. Many rejections suggest reflection is exploring but not finding hills; many acceptances suggest it is climbing a real signal.
85
- - Budget state. If budget was exhausted, the run paused before auto-promotion; manually decide whether to promote/finish. If max iterations was reached with budget remaining, the run likely converged under the configured search.
90
+ - Budget state. If budget was exhausted, the run paused before auto-promotion; the coding agent may finish the run. The human-only action is moving the production pointer with `optimizations promote --label production`. If max iterations was reached with budget remaining, the run likely converged under the configured search.
86
91
  - `scoreOverTime` / validation trajectory. Still climbing at the end suggests raising budget or iterations. Plateaued curves point toward scorer, feedback, or data work upstream.
87
92
  - Reflection model, inference model, scorer model, provider settings, minibatch size, resolved thread count, budget preset/limit, candidate selection strategy, seed, and cache settings.
88
93
 
@@ -103,7 +108,7 @@ Common recommendations:
103
108
  ### 6. What Not To Do
104
109
 
105
110
  List unsupported moves so the next agent does not burn cycles. Examples:
106
- - Do not hand-edit the prompt when the best candidate already learned the intended failure rules.
111
+ - Do not directly edit the selected component when the best candidate already learned the intended failure rules.
107
112
  - Do not raise budget when score over time plateaued and persistent failures are data/gold issues.
108
113
  - Do not switch metrics because one small validation result looks noisy; first measure variance across repeated runs or larger samples.
109
114
  - Do not optimize against a scorer whose feedback is too generic for reflection to learn from.
@@ -113,7 +118,7 @@ List unsupported moves so the next agent does not burn cycles. Examples:
113
118
  End with:
114
119
  - Run id and dashboard link.
115
120
  - Local log path or export artifact path.
116
- - Prompt/scorer/runner/optimizer version ids.
121
+ - Instruction-set profile, scorer, runner, and optimizer version ids.
117
122
  - Dataset version id, split set id, train/validation split names, row counts, and random seed.
118
123
  - Commands used to start/export/finish the run, with secrets omitted.
119
124
  - Links to relevant skill sections, especially `optimization-with-gepa.md`, `prompt-control-plane.md`, `building-judges.md`, and this report guide.
@@ -132,7 +137,7 @@ Set an explicit expectation before the run: for example, "if best kappa does not
132
137
 
133
138
  Default budget presets are DSPy-style metric-call budgets. `light`, `medium`, and `heavy` map to DSPy's `auto="light"`, `auto="medium"`, and `auto="heavy"` scales; `auto` is treated as the balanced `medium` preset and is the default when no budget control is provided. The final metric-call limit scales with validation-set size, rather than using fixed tiny constants. `--budget`, `--max-metric-calls`, `--max-full-evals`, `--max-iterations`, and `--max-candidate-proposals` are mutually exclusive CLI budget controls; choose only one. The proposal cap is available only on the official engine.
134
139
 
135
- Metric-call and full-eval budgets are checked only between iterations. Once an iteration starts, `run-gepa` completes the parent minibatch, child minibatch, and full validation eval for an accepted child even if that overshoots the nominal budget. If a run ends as `budget_exhausted`, it pauses and does not auto-promote. If auto-promotion matters, choose a single budget control large enough to cover the intended search.
140
+ Metric-call and full-eval budgets are checked only between iterations. Once an iteration starts, `run-gepa` completes the parent minibatch, child minibatch, and full validation eval for an accepted child even if that overshoots the nominal budget. If a run ends as `budget_exhausted`, it pauses and does not auto-promote. Auto-promotion is human-only; coding agents must not size or configure a run to trigger it, and instead hand validated candidates to a human curator for an explicit decision.
136
141
 
137
142
  ### Reflection Signal Quality
138
143