orizu 0.5.21 → 0.5.23

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 (87) hide show
  1. package/README.md +46 -15
  2. package/dist/cleanup.d.ts +6 -0
  3. package/dist/cleanup.d.ts.map +1 -0
  4. package/dist/cleanup.js +27 -0
  5. package/dist/gepa-engine-dispatch.d.ts.map +1 -1
  6. package/dist/gepa-engine-dispatch.js +20 -1
  7. package/dist/gepa-python-paths.d.ts.map +1 -1
  8. package/dist/gepa-python-paths.js +25 -6
  9. package/dist/help.d.ts.map +1 -1
  10. package/dist/help.js +37 -15
  11. package/dist/hosted-commands.d.ts +13 -0
  12. package/dist/hosted-commands.d.ts.map +1 -0
  13. package/dist/hosted-commands.js +10 -0
  14. package/dist/hosted-gepa-cli.d.ts +11 -0
  15. package/dist/hosted-gepa-cli.d.ts.map +1 -0
  16. package/dist/hosted-gepa-cli.js +110 -0
  17. package/dist/hosted-gepa-numeric-values.d.ts +3 -0
  18. package/dist/hosted-gepa-numeric-values.d.ts.map +1 -0
  19. package/dist/hosted-gepa-numeric-values.js +49 -0
  20. package/dist/hosted-provider-settings.d.ts +3 -0
  21. package/dist/hosted-provider-settings.d.ts.map +1 -0
  22. package/dist/hosted-provider-settings.js +69 -0
  23. package/dist/hosted-session-cli.d.ts.map +1 -1
  24. package/dist/hosted-session-cli.js +6 -1
  25. package/dist/http.d.ts +1 -0
  26. package/dist/http.d.ts.map +1 -1
  27. package/dist/http.js +7 -0
  28. package/dist/index.d.ts.map +1 -1
  29. package/dist/index.js +72 -74
  30. package/dist/instruction-set-loader.d.ts.map +1 -1
  31. package/dist/instruction-set-loader.js +57 -5
  32. package/dist/instruction-sets-cli.d.ts +5 -2
  33. package/dist/instruction-sets-cli.d.ts.map +1 -1
  34. package/dist/instruction-sets-cli.js +134 -24
  35. package/dist/optimizations-promote-cli.d.ts +3 -0
  36. package/dist/optimizations-promote-cli.d.ts.map +1 -1
  37. package/dist/optimizations-promote-cli.js +75 -7
  38. package/dist/runner-dir-verify.d.ts.map +1 -1
  39. package/dist/runner-dir-verify.js +4 -7
  40. package/dist/skilled-proposer-bake-report.d.ts +2 -0
  41. package/dist/skilled-proposer-bake-report.d.ts.map +1 -0
  42. package/dist/skilled-proposer-bake-report.js +1 -0
  43. package/dist/skilled-proposer-config.d.ts +2 -0
  44. package/dist/skilled-proposer-config.d.ts.map +1 -0
  45. package/dist/skilled-proposer-config.js +212 -0
  46. package/dist/skilled-proposer-launch.d.ts +26 -0
  47. package/dist/skilled-proposer-launch.d.ts.map +1 -1
  48. package/dist/skilled-proposer-launch.js +103 -6
  49. package/package.json +1 -1
  50. package/scripts/vendor-gepa-python.mjs +81 -12
  51. package/src/cleanup.ts +37 -0
  52. package/src/gepa-engine-dispatch.ts +21 -1
  53. package/src/gepa-python-paths.ts +24 -6
  54. package/src/help.ts +37 -15
  55. package/src/hosted-commands.ts +4 -0
  56. package/src/hosted-gepa-cli.ts +107 -0
  57. package/src/hosted-gepa-numeric-values.ts +60 -0
  58. package/src/hosted-provider-settings.ts +69 -0
  59. package/src/hosted-session-cli.ts +4 -1
  60. package/src/http.ts +8 -0
  61. package/src/index.ts +112 -89
  62. package/src/instruction-set-loader.ts +55 -5
  63. package/src/instruction-sets-cli.ts +173 -19
  64. package/src/optimizations-promote-cli.ts +85 -7
  65. package/src/runner-dir-verify.ts +11 -6
  66. package/src/skilled-proposer-bake-report.ts +1 -0
  67. package/src/skilled-proposer-config.ts +191 -0
  68. package/src/skilled-proposer-launch.ts +96 -7
  69. package/src/skilled-proposer-venv-manager.mjs +44 -27
  70. package/vendor/orizu-gepa/src/orizu_gepa_connector/engine.py +36 -3
  71. package/vendor/orizu-gepa/src/orizu_gepa_connector/instruction_set_loader.py +31 -3
  72. package/vendor/orizu-gepa/src/orizu_gepa_connector/runtime.py +7 -2
  73. package/vendor/orizu-gepa/src/orizu_gepa_connector/skilled_proposer_bridge.py +354 -5
  74. package/vendor/orizu-gepa-python/src/orizu_gepa/cli.py +1 -0
  75. package/vendor/orizu-gepa-python/src/orizu_gepa/client.py +15 -0
  76. package/vendor/skills/orizu-cli/SKILL.md +94 -168
  77. package/vendor/skills/orizu-cli/references/assess-and-plan.md +107 -0
  78. package/vendor/skills/orizu-cli/references/building-judges.md +442 -180
  79. package/vendor/skills/orizu-cli/references/cli-reference.md +69 -39
  80. package/vendor/skills/orizu-cli/references/dataset-design.md +100 -0
  81. package/vendor/skills/orizu-cli/references/eval-strategy.md +64 -0
  82. package/vendor/skills/orizu-cli/references/instructions-after-prompts.md +115 -0
  83. package/vendor/skills/orizu-cli/references/migrate-existing-gepa-setup.md +150 -82
  84. package/vendor/skills/orizu-cli/references/optimization-reports.md +196 -104
  85. package/vendor/skills/orizu-cli/references/optimization-with-gepa.md +57 -37
  86. package/vendor/skills/orizu-cli/references/primer.md +43 -18
  87. package/vendor/skills/orizu-cli/references/prompt-control-plane.md +199 -131
@@ -33,7 +33,7 @@ Behavior:
33
33
  - `orizu logout` revokes the current PAT remotely when possible and then clears local credentials.
34
34
  - PATs can also be revoked from the Personal Tokens page in Orizu.
35
35
  - PAT authorization follows the owning user's current team/project roles, so demotion or removal takes effect without rotating the token.
36
- - Hosted sandboxes are pre-authenticated via `ORIZU_TOKEN_FILE` (no `orizu login` needed); an explicit `ORIZU_TOKEN` env var overrides both the token file and stored credentials when set.
36
+ - A hosted session is pre-authenticated via `ORIZU_TOKEN_FILE` (no `orizu login` needed); an explicit `ORIZU_TOKEN` env var overrides both the token file and stored credentials when set.
37
37
 
38
38
  ### Agent Setup
39
39
 
@@ -67,7 +67,8 @@ orizu teams members role --team my-team --email person@example.com --role admin
67
67
 
68
68
  Allowed roles:
69
69
  - `admin`
70
- - `member`
70
+ - `curator`
71
+ - `judge`
71
72
 
72
73
  ### Projects
73
74
 
@@ -79,56 +80,77 @@ orizu projects create --name "Quality Eval" --team my-team
79
80
 
80
81
  ### Instruction sets
81
82
 
83
+ Follow the [Authority map](../SKILL.md#authority-map) for the executor on the current surface.
84
+
82
85
  ```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]
86
+ orizu instructions list --project my-team/quality-eval [--status active|archived|all] [--json]
87
+ orizu instructions show <set> --project my-team/quality-eval [--status active|archived|all] [--json]
88
+ orizu instructions create ./orizu.instruction-set.json --project my-team/quality-eval [--runner-version <id>] [--model-config <identity>] [--json]
89
+ orizu instructions push ./orizu.instruction-set.json --project my-team/quality-eval [--set <slug-or-exact-name>] [--runner-version <id>] [--json]
90
+ orizu instructions sync <set> --out ./instructions --project my-team/quality-eval [--model-config <identity>] [--json]
91
+ orizu instructions profiles new <set> --project my-team/quality-eval --model-config <identity> [--json]
92
+ orizu instructions profiles promote <set> --project my-team/quality-eval --model-config <identity> --version <n> [--json]
93
+ orizu instructions profiles rollback <set> --project my-team/quality-eval --model-config <identity> --to <n> [--json]
94
+ orizu instructions default show <set> --project my-team/quality-eval [--json]
95
+ orizu instructions default move <set> --project my-team/quality-eval --model-config <identity> --version <n> [--json]
96
+ orizu instructions shape add <set> --project my-team/quality-eval --key <key> --from <manifest> [--json]
97
+ orizu instructions shape remove <set> --project my-team/quality-eval --key <key> [--json]
98
+ orizu instructions archive <slug-or-exact-name> --project my-team/quality-eval [--json]
99
+ orizu instructions restore <slug-or-exact-name> --project my-team/quality-eval [--json]
95
100
  ```
96
101
 
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.
102
+ `instructions` is the customer-facing command namespace. The legacy
103
+ `instruction-sets` spelling remains a compatibility alias, but new workflows
104
+ should not teach it. A set can be addressed by its stable slug or exact name;
105
+ the slug does not change when the display name changes. `list` returns each
106
+ instruction set and its ordered shape. `show` returns the default and every
107
+ model-config profile's production state. Use `--status archived` or `--status
108
+ all` to include archived sets. The [Authority map](../SKILL.md#authority-map) selects the
109
+ executor for each surface. Archive and restore change visibility only:
110
+ archived sets continue to resolve and sync. `create` and `push` read a local
111
+ manifest; JSON output is one document per line. `push --set` updates the named
112
+ or slug-addressed set independently of the manifest's display name.
100
113
 
101
114
  `profiles new` copies the default component map into a model-config profile without
102
- changing its production resolution; hosted agents may create this seed because
103
- it does not move production. `profiles promote` moves that profile to a
115
+ changing its production resolution. `profiles promote` moves that profile to a
104
116
  version, and `profiles rollback` creates a new version copied from `--to`,
105
117
  including that target version's settings version, before moving production.
106
- These label-moving commands are human-only. For a single-component set that
107
- wraps a prompt, only default-profile promote and rollback also move the wrapped
118
+ `SKILL.md` supplies the promotion-decision and execution hand-off. For a
119
+ single-component set that wraps a prompt, only default-profile promote and rollback also move the wrapped
108
120
  prompt's production label in the same transaction and print `default profile →
109
121
  prompt label`. This coupling is one-way: moving the prompt label directly does
110
122
  not repoint the profile.
111
123
 
112
124
  `default show` reports the default and the model configs that currently resolve
113
- to it. `default move` is human-only and first reads that impact before moving
125
+ to it. `default move` first reads that impact before moving
114
126
  the pointer to a sealed, commit-anchored profile version. `shape add` and
115
127
  `shape remove` create a new complete version for every profile; they never move
116
128
  the default or a production label. The set does not resolve for affected model
117
129
  configs until those pointers move to the new shape-change profile versions; the
118
130
  text CLI prints the required follow-up commands.
119
131
 
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
132
+ The manifest is a JSON object with `name`, optional unversioned `description`,
133
+ ordered `shape`, and `components`. The description belongs to the instruction
134
+ set rather than any profile and round-trips through sync. Every component
135
+ supplies `{ key, text }` or `{ key, path }`; paths are relative to the manifest.
136
+ Set-wide components must cover the complete shape. A component may add
137
+ `modelConfig` for a profile override: `create` materializes that named profile
138
+ with the set-wide component map plus its overrides, while `push` updates named
125
139
  profiles already present on the set. `push` refuses a manifest whose shape
126
140
  differs from the stored set.
127
141
 
128
- `sync` writes `<out>/<set>/manifest.json`, `default/<key>.md`, and
142
+ `sync` writes `<out>/<stable-set-slug>/manifest.json`, `default/<key>.md`, and
129
143
  `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`.
144
+ use `loadInstructionSet(dir, setReference, modelConfigIdentity)` from `orizu`;
145
+ Python runners use
146
+ `orizu_gepa_connector.instruction_set_loader.load_instruction_set`. Prefer the
147
+ stable slug as `setReference`; both loaders also resolve the manifest's exact
148
+ name for compatibility with directories synced before slugs shipped. The
149
+ manifest's immutable `projectId` and `instructionSetId` prevent a shared
150
+ `--out` root from replacing another project's same-slug set.
151
+ Identity-less pre-slug trees cannot prove project ownership and are preserved;
152
+ sync returns `instruction_set_sync_legacy_identity_required` until the operator
153
+ moves the old tree aside or selects a clean output root.
132
154
  Both select that model config's production component map or the default without a
133
155
  network call. Git-pinned components have no local bytes: loading one raises
134
156
  `instruction_set_component_unavailable` until the runner supplies those bytes.
@@ -347,9 +369,12 @@ Defaults:
347
369
  - format defaults to `jsonl`
348
370
  - output file defaults to `<taskId>.<format>`
349
371
 
350
- ### Prompt Control Plane
372
+ ### Instruction Control Plane
351
373
 
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`.
374
+ For instruction sets, judges, runners, run submission, optimizer artifacts,
375
+ live event logging, and accepted-candidate promotion, read
376
+ `prompt-control-plane.md`. For markdown reports attached to optimization runs,
377
+ read `optimization-reports.md`.
353
378
 
354
379
  Diff-comment export:
355
380
 
@@ -374,23 +399,28 @@ Unrecoverable context is retained with a named degradation reason rather than
374
399
  dropping a comment. Optimization export includes the same data at
375
400
  `diffComments` using hunk detail. It also includes
376
401
  `diffCommentsSuppressedReason`: normally `null`, or `agent_project_scope` when
377
- a hosted agent exports a run outside its assigned project. In that case
402
+ a hosted session exports a run outside its assigned project. In that case
378
403
  `diffComments` is empty, and the marker reveals nothing about whether comments
379
404
  exist.
380
405
 
381
406
  Optimization trace commands:
382
407
 
383
408
  ```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]
409
+ 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]
410
+ orizu optimizations run-gepa --hosted ... --budget auto|light|medium|heavy [--launch-intent-id <uuid>]
385
411
  orizu optimizations export <optimization-run-id> --out ./optimization.json
386
412
  orizu optimizations export <optimization-run-id> --json
387
413
  ```
388
414
 
389
415
  Behavior:
416
+ - Hosted optimization is a human/PAT-only handoff for enabled teams. It makes
417
+ one server launch request, does not require local runner/log directories,
418
+ refuses numeric budget controls, and queues the run for the hosted
419
+ coordinator. Reuse `--launch-intent-id` after response loss.
390
420
  - `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
421
  - `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
422
  - `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").
423
+ - 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
424
  - `run-gepa` writes a complete local trace under `logs/<optimization_run_id>` by default.
395
425
  - 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
426
  - `optimizations export` writes a portable JSON artifact from server data when the local log is unavailable or the run happened elsewhere.
@@ -455,8 +485,8 @@ Use these shortcuts only in TTY environments where prompts can run.
455
485
 
456
486
  - `tasks create` creates a draft by default, does not require `--assignees`, and pins the app's current version when the task is created.
457
487
  - `tasks create --publish --assignees <...>` intentionally creates and ships immediately.
458
- - `tasks create|publish|assign --assignment-file <path>` is mutually exclusive with `--assignees` and accepts emails or user IDs in the JSONL manifest.
459
- - `tasks assign --assignees` and `tasks publish --assignees` expect user IDs, not emails.
488
+ - `--assignees` and assignment-file rows accept member emails or user IDs. Email selectors resolve to canonical member IDs within the task's project team; ambiguous or unknown emails are rejected.
489
+ - `tasks create|publish|assign --assignment-file <path>` is mutually exclusive with `--assignees`.
460
490
  - Assignment queue reads are assignee-self-only; use task status/export as the operator summary path.
461
491
  - Assignment completion payloads are validated against the pinned app-version `output_json_schema`.
462
492
  - `datasets delete-rows` requires `--row-ids`.
@@ -465,7 +495,7 @@ Use these shortcuts only in TTY environments where prompts can run.
465
495
  - `--row-ids` is the canonical row selection for delete operations.
466
496
  - Locked datasets reject append/edit/delete row mutations.
467
497
  - Row deletes are rejected when targeted rows are assignment-referenced.
468
- - Login currently requires callback availability on `127.0.0.1:43123`.
498
+ - Login callback binding defaults to `127.0.0.1:43123`. If that port is unavailable, set `ORIZU_AUTH_PORT` to an available port from 1024–65535.
469
499
  - New CLI logins use personal access tokens rather than short-lived Supabase session credentials.
470
500
  - In non-interactive contexts, pass explicit selection flags.
471
501
 
@@ -481,7 +511,7 @@ Worker assignment reads are self-only:
481
511
  - Use `tasks status` and `tasks export` for operator-side reporting.
482
512
  ### Offline instruction-set sync
483
513
 
484
- `orizu instruction-sets sync <set> --project <team/project> --out <dir>` writes
514
+ `orizu instructions sync <set> --project <team/project> --out <dir>` writes
485
515
  an atomic local manifest. A resolver failure for either the default or any
486
516
  selected profile refuses the entire sync as `instruction_set_unresolvable`; the
487
517
  route never silently downgrades a failed production component map to default bytes. A
@@ -0,0 +1,100 @@
1
+ # Dataset design
2
+
3
+ Use this reference for **J3 — Build the dataset** after the improvement plan is ratified and before annotation or judge work. Treat the plan's approved source choice and named scenario classes as input constraints rather than reopening them while moving data.
4
+
5
+ ## Carry the approved source choice into the dataset
6
+
7
+ Inventory each approved source and record its owner, row shape, time range, scenario-class coverage, ground-truth field, and whether the human spot-check approved it. When existing golden data is available from an observability provider, eval store, or user behavior, import those rows and preserve their approved ground truth. Do not propose a new annotation round for ground truth the customer already has; record why annotation is skipped or reduced.
8
+
9
+ If there is no approved golden data, continue with representative production traces, a random sample, and structured synthetic cases for scenario classes that real traces do not cover. Keep provenance on every row so later versions can be audited, and have the human ratify the source choice and spot-check examples before the dataset is used.
10
+
11
+ ## Build a diverse sample and make coverage visible
12
+
13
+ Create a coverage table from the ratified plan before sampling. Give every scenario class a planned row count, source, ground-truth status, and actual row count. Preserve the production distribution with a random sample, then deliberately add rare, costly, new, and previously failing cases. Keep successful cases as controls. Deduplicate repeated traces and keep stable row IDs; do not let one conversation or near-duplicate appear on both sides of the split.
14
+
15
+ Before upload, fail the coverage check if any scenario class from the plan has zero rows. Report both the natural distribution and any deliberate over-sampling so later results are interpreted per scenario class rather than as an unexplained aggregate.
16
+
17
+ ## Design train, validation, final-held-out, and the mini-batch together
18
+
19
+ Build one predefined split with exactly three application partitions for the primary dataset at dataset-build time: train, validation, and final-held-out. Auxiliary partitions, such as a migration-only parity corpus, may coexist in specialized workflows without changing this three-partition application doctrine. Validation is the valset that ranks candidates during optimization. Apply the Vocabulary contract to final-held-out: exclude its rows from candidate ranking, selection, reflection, and judge development.
20
+
21
+ **Judge-development data (J5)** comes from the labeled export, and `references/building-judges.md` owns its split mechanics; exclude final-held-out rows from all judge-development material (judge-dev and judge-test/alignment) because judge selection on final-held-out labels biases the final comparison through the judge itself.
22
+
23
+ Final-held-out rows need no human labels; exclude their row IDs from annotation tasks.
24
+
25
+ Put representative, approved rows from every scenario class in both validation and final-held-out, isolate both from training and from each other, and keep their intended membership unchanged. Record all three partitions' row IDs in the predefined split file so the decisions can be reproduced. Every scenario class in validation or final-held-out must also have training rows; otherwise the optimizer is being assessed on a class it had no opportunity to learn.
26
+
27
+ Size the mini-batch from the least common training class. For `K` scenario classes and a desired 95% chance that all classes appear, use the conservative miss bound `0.05 / K`. For each scenario class `i`, let `p_i` be that class's share of the training-split rows; choose the smallest positive integer mini-batch size `b` where `(1 - p_i)^b <= 0.05 / K` for every `i`. Pass the computed value to `orizu optimizations run-gepa --minibatch-size <b>`; `--minibatch-size` defaults to `3`, so do not omit it when the computed value differs.
28
+
29
+ Budget this together with the valset. With the skilled/custom proposer, the engine can silently clamp the reflection mini-batch to `max(1, max_metric_calls - len(valset))`. Do not infer safety from the user-facing budget flag: explicit `--max-metric-calls`, `--max-full-evals`, named `--budget` presets, and the default `--budget auto` all resolve to a metric-call limit that can trigger this clamp. With the default proposer, this clamp does not apply.
30
+
31
+ No budget dry-run exists, so calculate the resolved metric-call limit before launching a skilled/custom proposer. Explicit `--max-metric-calls n` resolves to `n`; `--max-full-evals f` resolves to `f * (len(trainset) + len(valset))`; and named/default `--budget` presets resolve through the formula in `packages/orizu-gepa-python/src/orizu_gepa/optimizer.py:361-405` using the chosen preset, component count, and valset size. Require `resolved_metric_calls - len(valset) >= b`; otherwise increase or change the budget, or record that the coverage guarantee does not hold. If the available rows or optimization budget cannot support the computed size, add rows, combine only genuinely equivalent scenario classes with human approval, or record that the plan is not ready for optimization.
32
+
33
+ The canonical split-file schema and version/split command contract live in `references/prompt-control-plane.md` under “Dataset Versions And Splits.” J3 adds the coverage requirement: use a predefined three-way split when scenario-class coverage matters, and build its partitions from the independently reviewed coverage table rather than a random split that could omit a class. For example:
34
+
35
+ ```json
36
+ {
37
+ "name": "v1",
38
+ "strategy": "predefined",
39
+ "seed": 42,
40
+ "partitions": [
41
+ { "name": "train", "row_ids": ["policy-1", "escalation-1", "safety-1"] },
42
+ { "name": "validation", "row_ids": ["policy-2", "escalation-2", "safety-2"] },
43
+ { "name": "final-held-out", "row_ids": ["policy-3", "escalation-3", "safety-3"] }
44
+ ]
45
+ }
46
+ ```
47
+
48
+ For the Final-held-out seed-vs-selected procedure and its supported-surface stop conditions, follow step 5 under “How To Build The Report” in `references/optimization-reports.md`.
49
+
50
+ ## Upload, version, and create the split set
51
+
52
+ Normalize approved rows to CSV, JSON, or JSONL, with stable row identity and provenance fields, then upload them and request the machine-readable result:
53
+
54
+ ```bash
55
+ orizu datasets upload --file ./dataset.jsonl --project <team/project> --name "<dataset-name>" --readme-file ./dataset-readme.md --json
56
+ ```
57
+
58
+ Upload already creates the first immutable snapshot (labelled `v1` by default). Retain the returned `dataset_id` and `dataset_version_id`; use that `dataset_version_id` directly to create the split set, and retain its returned `split_set_id` in the improvement plan:
59
+
60
+ ```bash
61
+ orizu datasets splits create <upload-returned-dataset-version-id> --from-file ./split.json --json
62
+ ```
63
+
64
+ Reserve `orizu datasets versions create` for a subsequent snapshot, and give it a new label such as `v2`; labels are unique within a dataset. The dataset README should record source approval, source locators, sampling decisions, deduplication rules, the coverage table, ground-truth status, and the split rationale.
65
+
66
+ The dataset version freezes its rows. Server-side split membership is mutable, but the CLI exposes no split-set read operation, so membership cannot be re-read through the CLI. Treat the independently reviewed local split file plus the returned split-set ID as the canonical record available to this workflow. Do not mutate that server-side split set; pass the recorded `--dataset-version-id` and `--split-set-id` to `orizu optimizations run-gepa`, and record the CLI verification gap explicitly rather than claiming the server membership was re-verified.
67
+
68
+ ## Guard live rows before annotation and version later data
69
+
70
+ Use the dataset mutation contract in `SKILL.md` under “Execution facts” rather than inferring lock or row-edit semantics here.
71
+
72
+ After source approval and the split audit, the dataset must be locked before annotation starts because tasks pin live dataset rows rather than the immutable version:
73
+
74
+ ```bash
75
+ orizu datasets lock --dataset <dataset-id> --project <team/project> --reason "Approved dataset v1"
76
+ ```
77
+
78
+ The lock is a hard gate. If the user refuses it, annotation cannot proceed safely: labelers and exports dereference live row data, while responses store no response-time row snapshot. A mutate-label-restore sequence could therefore attach a label to different content without leaving evidence in the final rows.
79
+
80
+ When new data arrives, keep the prior dataset version, reviewed split file, and recorded split-set ID unchanged. Clone the locked dataset, add the approved rows to the unlocked clone, repeat the scenario-class coverage and split audit, and create a subsequent snapshot with a non-default label plus a new split set:
81
+
82
+ ```bash
83
+ orizu datasets clone --dataset <dataset-id> --project <team/project> --name "<dataset-name>-v2"
84
+ orizu datasets append --dataset <cloned-dataset-id> --project <team/project> --file ./new-rows.jsonl
85
+ orizu datasets versions create <cloned-dataset-id> --project <team/project> --label v2 --readme-file ./dataset-readme-v2.md --json
86
+ orizu datasets splits create <new-dataset-version-id> --from-file ./split-v2.json --json
87
+ ```
88
+
89
+ Never rewrite a prior version to make later labels or corrections appear historical.
90
+
91
+ ## Exit criterion
92
+
93
+ J3 exits only when the evidence records all of the following:
94
+
95
+ - the human-ratified source choice and spot-check;
96
+ - the plan's complete scenario-class list, with nonzero total, training, validation, and final-held-out counts for every scenario class;
97
+ - an immutable dataset version ID plus the reviewed local split file and recorded split-set ID whose predefined train, validation, and final-held-out rows match that coverage table;
98
+ - final-held-out row IDs excluded from all judge-development material (judge-dev and judge-test/alignment) and reserved for the final J6 comparison;
99
+ - for the annotation path, proof that the dataset was locked before any task was created; and
100
+ - either approved golden ground truth with annotation skipped or reduced, or rows ready for the eval-strategy and annotation path.
@@ -0,0 +1,64 @@
1
+ # Eval strategy and labeler validation
2
+
3
+ Use this reference only after **J3 — Build the dataset** has versioned the PRIMARY dataset and created its three-way split set. If approved golden data already supplies all required ground truth, record the source, approval, and scenario-class coverage, then skip annotation. If only unresolved rows need labels, clone or filter those rows into a separate dataset because automatic assignments cover every current dataset row and explicit assignment files require uniform whole-dataset coverage.
4
+
5
+ Final-held-out rows need no human labels; exclude their row IDs from annotation tasks and from the unresolved-rows clone/filter.
6
+
7
+ A derived unresolved-rows dataset is a labeling vehicle, not an optimization dataset. Preserve each source row's canonical `id` field from `datasets download` in the derived row's `row_data`; this is the stable identifier used by split files. Before creating any task, create and record the derived dataset's immutable version ID and lock the live dataset; it does not need its own per-class three-way split. Task creation waits for both records.
8
+
9
+ ## Guide the eval-strategy conversation
10
+
11
+ Start from the ratified improvement plan and J3 coverage table; do not ask the human to restate facts already recorded. Walk through the decisions below with concrete rows, propose a draft answer where the evidence supports one, and ask the human to correct or ratify it.
12
+
13
+ 1. **Experience and decision.** Ask which exact user experience the eval represents and which change or release decision it must inform. Confirm the unit being judged: one response, conversation, agent step, or complete run.
14
+ 2. **Good and bad by scenario class.** For every scenario class, show representative rows and draft one binary question per observed failure mode. Ask what visible evidence makes each answer pass, fail, or unlabelable. Do not bundle independent judgments or replace them with a Likert question.
15
+ 3. **Eval-set composition.** Confirm which versioned rows need human labels, the intended counts per scenario class, and any rare cases that must be present even when production frequency is low. Keep J3 validation for candidate ranking and keep its final-held-out partition under the separate partition doctrine in `references/dataset-design.md`.
16
+ 4. **Ground truth.** Ask who is qualified to label each question, what context they need, how ambiguity or disagreement will be adjudicated, and whether user behavior or another approved golden-data field already answers it. Import approved golden data instead of relabeling it.
17
+ 5. **Downstream validation.** Explain that these labels will later validate automated judges. Ask which decision class each judge will power and record it for **J5 — Build & validate judges**, where the human sets the numerical judge trust bar from measured agreement, TPR, and TNR rather than accepting a default here.
18
+
19
+ Persist the ratified eval strategy in project context. It must name the experience and unit, dataset version and split set, scenario classes and row counts, binary questions with pass/fail/unlabelable rules, ground-truth source, labeler qualifications, disagreement path, golden-data decision, and the future decision attached to each judge trust bar. Do not author the labeler until the human ratifies this record.
20
+
21
+ `references/building-judges.md` owns the J5 input envelope and is being aligned there. This reference records the evidence handed to that contract. For a golden-data-only path, validate the field mapping against the binary questions, spot-check every scenario class with the human, and record the PRIMARY versioned dataset ID plus the approved ground-truth field per failure mode in the plan and report; then skip the remaining J4 annotation path.
22
+
23
+ For a mixed path, after annotation export, group derived records by the canonical `id` at `dataset_row.row_data.id`, the same identifier emitted by `datasets download` and used by split files, and require each key to match one primary row. Preserve every per-rater record in each row group, including the rater identity from the export, then aggregate according to the eval strategy's agreement rules. Record J5's labeled input as the union of the golden field mapping for golden rows and the grouped task export for annotated rows, keyed by that canonical primary-row `id`. Continue below only for questions or rows whose ground truth still requires human labels.
24
+
25
+ ## Validate the labeler before tasks or labels
26
+
27
+ After the eval strategy is ratified, author the task-specific app with `references/building-apps.md`. That reference is the single home for the runtime contract, component choices, schemas, smoke test, preview mechanics, and app accessibility rules.
28
+
29
+ Run the smoke test and preview flow from that reference with representative rows from every scenario class. Inspect the resulting screenshot yourself, then ask the human for pointed feedback: does the app show the evidence needed for each judgment, ask the intended binary question in the plan's language, distinguish unanswered from false, produce useful ground truth, and make the primary action clear? Ask what is confusing or missing and which representative row is hardest to label. Revise and preview again until the human explicitly confirms the app works.
30
+
31
+ Record the rows previewed, the feedback, the revisions, and the approval. Do not create or publish a task, and do not start labeling, until this labeler-feedback gate is confirmed.
32
+
33
+ Use the draft-first ordering, URL-approval gate, and assignee-selector contract in `SKILL.md` under “Execution facts”; use `references/cli-reference.md` for the command surface. This reference adds one versioning safeguard: the task pins the app version selected at creation.
34
+
35
+ If draft testing reveals a problem, revise through `orizu apps update`, repeat the preview and pointed-feedback gate, capture the returned version number `n`, and explicitly repin the draft before testing its URL again:
36
+
37
+ ```bash
38
+ orizu tasks update --task <taskId> --app <appId> --version <n>
39
+ ```
40
+
41
+ Then return to the approval and publish sequence in “Execution facts.” If the strategy requires an explicit row-to-labeler map, it must still cover every row in this task's separate annotation dataset uniformly.
42
+
43
+ After labeling, inspect the machine-readable status before task completion or export:
44
+
45
+ ```bash
46
+ orizu tasks status --task <task-id> --json
47
+ ```
48
+
49
+ Verify that `task.counts.completed` equals `task.totalRequiredAssignments` and that in-progress, pending, paused, and skipped counts are zero. Status proves assignment states, not response custody. After those counts pass, export the response-bearing JSONL before completing the task:
50
+
51
+ ```bash
52
+ orizu tasks export --task <task-id> --format jsonl --out ./labels.jsonl
53
+ ```
54
+
55
+ Parse every non-empty JSONL line. Require the export row count to equal `task.totalRequiredAssignments`, require each `dataset_row_id` to appear exactly `task.requiredAssignmentsPerRow` times, and require every record to carry a non-null `response_id` and `response_data`. Any mismatch means a planned row lacks a response and blocks completion. Only after this response-level proof may the task be completed and its report published:
56
+
57
+ ```bash
58
+ orizu tasks complete --task <task-id>
59
+ orizu tasks report set --task <task-id> --report-file ./task-report.md --json
60
+ ```
61
+
62
+ ## Exit criterion
63
+
64
+ The annotation path exits only when the ratified eval strategy, labeler feedback, app approval, complete assignment-status evidence, response-complete exported labels, and published task report are recorded together. The golden-data path exits with the PRIMARY versioned dataset ID and approved per-failure-mode field mapping recorded. The mixed path additionally records the canonical-row-`id`-keyed union of golden mappings and per-rater annotated exports. In every path, report ground-truth and disagreement counts per scenario class so J5 receives auditable evidence rather than only an aggregate.
@@ -0,0 +1,115 @@
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 the complete manifest and its component files, then follow the
80
+ [Authority map](../SKILL.md#authority-map) for each mutation.
81
+
82
+ ## Consolidation
83
+
84
+ Consolidation changes ownership and visibility. Create the consolidated set
85
+ through the surface selected by the [Authority map](../SKILL.md#authority-map) and inspect its complete
86
+ profiles before changing any pointer:
87
+
88
+ ```bash
89
+ orizu instructions create ./orizu.instruction-set.json --project <team/project> --model-config <identity> --json
90
+ orizu instructions show <slug-or-exact-name> --project <team/project> --status all --json
91
+ ```
92
+
93
+ After verifying the new set, archive each redundant one-component
94
+ set. Archive changes visibility only; the archived set still resolves and
95
+ syncs until the pointer move is complete, so it remains a recovery
96
+ source.
97
+
98
+ ```bash
99
+ orizu instructions archive <slug-or-exact-name> --project <team/project> --json
100
+ ```
101
+
102
+ After the explicit promotion decision, move the consolidated set's default or
103
+ promote a named model-config profile through the Authority map:
104
+
105
+ ```bash
106
+ orizu instructions default move <set> --project <team/project> --model-config <identity> --version <n> --json
107
+ orizu instructions profiles promote <set> --project <team/project> --model-config <identity> --version <n> --json
108
+ ```
109
+
110
+ Confirm the resolved default and every production profile after the move. If a
111
+ redundant set must become visible again, restore it through the Authority map:
112
+
113
+ ```bash
114
+ orizu instructions restore <slug-or-exact-name> --project <team/project> --json
115
+ ```