ai-capability-framework 1.0.2 → 1.1.0-rc.1

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 (239) hide show
  1. package/CHANGELOG.md +36 -0
  2. package/README.md +24 -0
  3. package/ROADMAP.md +11 -0
  4. package/dist/cli.d.ts.map +1 -1
  5. package/dist/cli.js +25 -0
  6. package/dist/discovery/bindings.d.ts +7 -0
  7. package/dist/discovery/bindings.d.ts.map +1 -0
  8. package/dist/discovery/bindings.js +24 -0
  9. package/dist/discovery/budget.d.ts +17 -0
  10. package/dist/discovery/budget.d.ts.map +1 -0
  11. package/dist/discovery/budget.js +77 -0
  12. package/dist/discovery/configuration.d.ts +10 -0
  13. package/dist/discovery/configuration.d.ts.map +1 -0
  14. package/dist/discovery/configuration.js +63 -0
  15. package/dist/discovery/corpus.d.ts +8 -0
  16. package/dist/discovery/corpus.d.ts.map +1 -0
  17. package/dist/discovery/corpus.js +64 -0
  18. package/dist/discovery/diagnostics.d.ts +15 -0
  19. package/dist/discovery/diagnostics.d.ts.map +1 -0
  20. package/dist/discovery/diagnostics.js +11 -0
  21. package/dist/discovery/discoverer.d.ts +23 -0
  22. package/dist/discovery/discoverer.d.ts.map +1 -0
  23. package/dist/discovery/discoverer.js +261 -0
  24. package/dist/discovery/embedding-configuration.d.ts +12 -0
  25. package/dist/discovery/embedding-configuration.d.ts.map +1 -0
  26. package/dist/discovery/embedding-configuration.js +81 -0
  27. package/dist/discovery/embedding-types.d.ts +75 -0
  28. package/dist/discovery/embedding-types.d.ts.map +1 -0
  29. package/dist/discovery/embedding-types.js +1 -0
  30. package/dist/discovery/embeddings.d.ts +38 -0
  31. package/dist/discovery/embeddings.d.ts.map +1 -0
  32. package/dist/discovery/embeddings.js +71 -0
  33. package/dist/discovery/evaluation-validation.d.ts +8 -0
  34. package/dist/discovery/evaluation-validation.d.ts.map +1 -0
  35. package/dist/discovery/evaluation-validation.js +19 -0
  36. package/dist/discovery/evaluation.d.ts +84 -0
  37. package/dist/discovery/evaluation.d.ts.map +1 -0
  38. package/dist/discovery/evaluation.js +310 -0
  39. package/dist/discovery/export.d.ts +14 -0
  40. package/dist/discovery/export.d.ts.map +1 -0
  41. package/dist/discovery/export.js +81 -0
  42. package/dist/discovery/facade.d.ts +82 -0
  43. package/dist/discovery/facade.d.ts.map +1 -0
  44. package/dist/discovery/facade.js +266 -0
  45. package/dist/discovery/fingerprint.d.ts +71 -0
  46. package/dist/discovery/fingerprint.d.ts.map +1 -0
  47. package/dist/discovery/fingerprint.js +67 -0
  48. package/dist/discovery/index-builder.d.ts +3 -0
  49. package/dist/discovery/index-builder.d.ts.map +1 -0
  50. package/dist/discovery/index-builder.js +129 -0
  51. package/dist/discovery/index-validation.d.ts +12 -0
  52. package/dist/discovery/index-validation.d.ts.map +1 -0
  53. package/dist/discovery/index-validation.js +117 -0
  54. package/dist/discovery/index.d.ts +32 -0
  55. package/dist/discovery/index.d.ts.map +1 -0
  56. package/dist/discovery/index.js +18 -0
  57. package/dist/discovery/json-snapshot.d.ts +3 -0
  58. package/dist/discovery/json-snapshot.d.ts.map +1 -0
  59. package/dist/discovery/json-snapshot.js +11 -0
  60. package/dist/discovery/lexical.d.ts +12 -0
  61. package/dist/discovery/lexical.d.ts.map +1 -0
  62. package/dist/discovery/lexical.js +26 -0
  63. package/dist/discovery/metadata.d.ts +4 -0
  64. package/dist/discovery/metadata.d.ts.map +1 -0
  65. package/dist/discovery/metadata.js +33 -0
  66. package/dist/discovery/ranking.d.ts +7 -0
  67. package/dist/discovery/ranking.d.ts.map +1 -0
  68. package/dist/discovery/ranking.js +68 -0
  69. package/dist/discovery/replay.d.ts +50 -0
  70. package/dist/discovery/replay.d.ts.map +1 -0
  71. package/dist/discovery/replay.js +175 -0
  72. package/dist/discovery/retrieval-policy.d.ts +5 -0
  73. package/dist/discovery/retrieval-policy.d.ts.map +1 -0
  74. package/dist/discovery/retrieval-policy.js +10 -0
  75. package/dist/discovery/router.d.ts +39 -0
  76. package/dist/discovery/router.d.ts.map +1 -0
  77. package/dist/discovery/router.js +98 -0
  78. package/dist/discovery/selection-attempt.d.ts +20 -0
  79. package/dist/discovery/selection-attempt.d.ts.map +1 -0
  80. package/dist/discovery/selection-attempt.js +39 -0
  81. package/dist/discovery/selection-cards.d.ts +12 -0
  82. package/dist/discovery/selection-cards.d.ts.map +1 -0
  83. package/dist/discovery/selection-cards.js +79 -0
  84. package/dist/discovery/selection-configuration.d.ts +18 -0
  85. package/dist/discovery/selection-configuration.d.ts.map +1 -0
  86. package/dist/discovery/selection-configuration.js +71 -0
  87. package/dist/discovery/selection-response.d.ts +13 -0
  88. package/dist/discovery/selection-response.d.ts.map +1 -0
  89. package/dist/discovery/selection-response.js +47 -0
  90. package/dist/discovery/selection-types.d.ts +18 -0
  91. package/dist/discovery/selection-types.d.ts.map +1 -0
  92. package/dist/discovery/selection-types.js +1 -0
  93. package/dist/discovery/selection.d.ts +6 -0
  94. package/dist/discovery/selection.d.ts.map +1 -0
  95. package/dist/discovery/selection.js +145 -0
  96. package/dist/discovery/types.d.ts +291 -0
  97. package/dist/discovery/types.d.ts.map +1 -0
  98. package/dist/discovery/types.js +1 -0
  99. package/dist/discovery/usage.d.ts +2 -0
  100. package/dist/discovery/usage.d.ts.map +1 -0
  101. package/dist/discovery/usage.js +1 -0
  102. package/dist/discovery/vectors.d.ts +5 -0
  103. package/dist/discovery/vectors.d.ts.map +1 -0
  104. package/dist/discovery/vectors.js +43 -0
  105. package/dist/discovery/versions.d.ts +37 -0
  106. package/dist/discovery/versions.d.ts.map +1 -0
  107. package/dist/discovery/versions.js +36 -0
  108. package/dist/evals-live/live-eval-runner.d.ts +1 -0
  109. package/dist/evals-live/live-eval-runner.d.ts.map +1 -1
  110. package/dist/evals-live/live-eval-runner.js +12 -1
  111. package/dist/evals-live/types.d.ts +3 -0
  112. package/dist/evals-live/types.d.ts.map +1 -1
  113. package/dist/generated/manifest-types.d.ts +3655 -0
  114. package/dist/generated/manifest-types.d.ts.map +1 -1
  115. package/dist/loader.d.ts.map +1 -1
  116. package/dist/loader.js +8 -0
  117. package/dist/mcp-server/server.d.ts.map +1 -1
  118. package/dist/mcp-server/server.js +11 -2
  119. package/dist/mcp-server/types.d.ts +4 -0
  120. package/dist/mcp-server/types.d.ts.map +1 -1
  121. package/dist/observability/redaction.d.ts.map +1 -1
  122. package/dist/observability/redaction.js +6 -2
  123. package/dist/observability/types.d.ts +1 -1
  124. package/dist/observability/types.d.ts.map +1 -1
  125. package/dist/openai/index.d.ts +2 -0
  126. package/dist/openai/index.d.ts.map +1 -1
  127. package/dist/openai/index.js +1 -0
  128. package/dist/openai/responses-runner.d.ts +1 -1
  129. package/dist/openai/responses-runner.d.ts.map +1 -1
  130. package/dist/openai/responses-runner.js +134 -7
  131. package/dist/openai/selection-client.d.ts +28 -0
  132. package/dist/openai/selection-client.d.ts.map +1 -0
  133. package/dist/openai/selection-client.js +95 -0
  134. package/dist/openai/tool-loop.js +1 -1
  135. package/dist/openai/types.d.ts +19 -2
  136. package/dist/openai/types.d.ts.map +1 -1
  137. package/dist/replay/discovery-snapshot.d.ts +10 -0
  138. package/dist/replay/discovery-snapshot.d.ts.map +1 -0
  139. package/dist/replay/discovery-snapshot.js +17 -0
  140. package/dist/replay/recorder.d.ts.map +1 -1
  141. package/dist/replay/recorder.js +4 -0
  142. package/dist/replay/redaction.js +5 -1
  143. package/dist/replay/replayer.d.ts.map +1 -1
  144. package/dist/replay/replayer.js +14 -1
  145. package/dist/replay/types.d.ts +3 -0
  146. package/dist/replay/types.d.ts.map +1 -1
  147. package/dist/replay/validation.d.ts.map +1 -1
  148. package/dist/replay/validation.js +6 -0
  149. package/dist/runtime/bounded-json.d.ts +4 -0
  150. package/dist/runtime/bounded-json.d.ts.map +1 -0
  151. package/dist/runtime/bounded-json.js +74 -0
  152. package/dist/runtime/eligibility.d.ts +4 -0
  153. package/dist/runtime/eligibility.d.ts.map +1 -0
  154. package/dist/runtime/eligibility.js +128 -0
  155. package/dist/runtime/index.d.ts +5 -1
  156. package/dist/runtime/index.d.ts.map +1 -1
  157. package/dist/runtime/index.js +2 -0
  158. package/dist/runtime/provider-attempt.d.ts +11 -0
  159. package/dist/runtime/provider-attempt.d.ts.map +1 -0
  160. package/dist/runtime/provider-attempt.js +221 -0
  161. package/dist/runtime/provider-run.d.ts +10 -0
  162. package/dist/runtime/provider-run.d.ts.map +1 -0
  163. package/dist/runtime/provider-run.js +123 -0
  164. package/dist/runtime/provider-stop.d.ts +9 -0
  165. package/dist/runtime/provider-stop.d.ts.map +1 -0
  166. package/dist/runtime/provider-stop.js +28 -0
  167. package/dist/runtime/provider-types.d.ts +189 -0
  168. package/dist/runtime/provider-types.d.ts.map +1 -0
  169. package/dist/runtime/provider-types.js +1 -0
  170. package/dist/runtime/provider-usage.d.ts +9 -0
  171. package/dist/runtime/provider-usage.d.ts.map +1 -0
  172. package/dist/runtime/provider-usage.js +69 -0
  173. package/dist/runtime/router.d.ts.map +1 -1
  174. package/dist/runtime/router.js +3 -118
  175. package/dist/runtime/types.d.ts +9 -0
  176. package/dist/runtime/types.d.ts.map +1 -1
  177. package/dist/types.d.ts +1 -1
  178. package/dist/types.d.ts.map +1 -1
  179. package/dist/validator.d.ts +3 -0
  180. package/dist/validator.d.ts.map +1 -1
  181. package/dist/validator.js +32 -0
  182. package/docs/api/public-api-policy.md +7 -0
  183. package/docs/api.md +7 -0
  184. package/docs/capability-manifests.md +24 -0
  185. package/docs/discovery.md +191 -0
  186. package/docs/evals/discovery-live.md +199 -0
  187. package/docs/evals/discovery-qualification.md +153 -0
  188. package/docs/evals/overview.md +9 -0
  189. package/docs/index.md +9 -0
  190. package/docs/release.md +25 -5
  191. package/docs/runtime.md +22 -0
  192. package/examples/12-capability-discovery-selection/README.md +345 -0
  193. package/examples/12-capability-discovery-selection/customer-cases.mjs +52 -0
  194. package/examples/12-capability-discovery-selection/customer-harness.mjs +91 -0
  195. package/examples/12-capability-discovery-selection/customer-request-example.mjs +320 -0
  196. package/examples/12-capability-discovery-selection/discovery-example.mjs +175 -0
  197. package/examples/12-capability-discovery-selection/discovery-fixtures/three-domains.suite.json +7887 -0
  198. package/examples/12-capability-discovery-selection/discovery-fixtures/three-domains.v2.suite.json +8167 -0
  199. package/examples/12-capability-discovery-selection/discovery-fixtures/three-domains.v3.suite.json +8342 -0
  200. package/examples/12-capability-discovery-selection/evaluation/application.mjs +305 -0
  201. package/examples/12-capability-discovery-selection/evaluation/campaign.mjs +248 -0
  202. package/examples/12-capability-discovery-selection/evaluation/clients.mjs +433 -0
  203. package/examples/12-capability-discovery-selection/evaluation/continuation.mjs +208 -0
  204. package/examples/12-capability-discovery-selection/evaluation/durable-budget.mjs +420 -0
  205. package/examples/12-capability-discovery-selection/evaluation/freeze.mjs +9 -0
  206. package/examples/12-capability-discovery-selection/evaluation/harness.mjs +618 -0
  207. package/examples/12-capability-discovery-selection/evaluation/mock-host.mjs +260 -0
  208. package/examples/12-capability-discovery-selection/evaluation/preflight.mjs +115 -0
  209. package/examples/12-capability-discovery-selection/evaluation/qualification-workflows.mjs +87 -0
  210. package/examples/12-capability-discovery-selection/evaluation/regrade.mjs +281 -0
  211. package/examples/12-capability-discovery-selection/evaluation/report.mjs +517 -0
  212. package/examples/12-capability-discovery-selection/evaluation/runner.mjs +613 -0
  213. package/examples/12-capability-discovery-selection/evaluation/saved-campaign.mjs +385 -0
  214. package/examples/12-capability-discovery-selection/evaluation/wording.mjs +115 -0
  215. package/examples/12-capability-discovery-selection/evaluation/workflow-application.mjs +378 -0
  216. package/examples/12-capability-discovery-selection/evaluation/workflow-cases.mjs +90 -0
  217. package/examples/12-capability-discovery-selection/evaluation-example.mjs +154 -0
  218. package/examples/12-capability-discovery-selection/hybrid-example.mjs +174 -0
  219. package/examples/12-capability-discovery-selection/mock-embeddings.mjs +101 -0
  220. package/examples/12-capability-discovery-selection/mock-selection.mjs +78 -0
  221. package/examples/12-capability-discovery-selection/pipeline-example.mjs +496 -0
  222. package/examples/12-capability-discovery-selection/retrieval-cases.mjs +31 -0
  223. package/examples/12-capability-discovery-selection/run-campaign-mock.mjs +40 -0
  224. package/examples/12-capability-discovery-selection/run-customer-mock.mjs +15 -0
  225. package/examples/12-capability-discovery-selection/run-evaluation-live.mjs +10 -0
  226. package/examples/12-capability-discovery-selection/run-evaluation-mock.mjs +3 -0
  227. package/examples/12-capability-discovery-selection/run-evaluation-regrade.mjs +71 -0
  228. package/examples/12-capability-discovery-selection/run-hybrid-mock.mjs +3 -0
  229. package/examples/12-capability-discovery-selection/run-mock.mjs +3 -0
  230. package/examples/12-capability-discovery-selection/run-pipeline-mock.mjs +2 -0
  231. package/examples/12-capability-discovery-selection/run-selector-mock.mjs +3 -0
  232. package/examples/12-capability-discovery-selection/selection-example.mjs +88 -0
  233. package/package.json +17 -4
  234. package/schemas/discovery/embedding-index.schema.json +71 -0
  235. package/schemas/discovery/eval-observations.schema.json +409 -0
  236. package/schemas/discovery/eval-suite.schema.json +375 -0
  237. package/schemas/discovery/metadata.schema.json +30 -0
  238. package/schemas/discovery/selection-response.schema.json +47 -0
  239. package/schemas/replay/discovery-snapshot.schema.json +335 -0
@@ -0,0 +1,153 @@
1
+ # Discovery qualification for 1.1.0-rc.1
2
+
3
+ Lexical retrieval with ordinary model tool selection (**lexical/native**) is the
4
+ recommended default. Lexical/dedicated also qualified for the tested configuration; it
5
+ remains an optional additional model call. Hybrid/native and hybrid/dedicated remain
6
+ **experimental and opt-in** because they did not meet the incremental-gain gate.
7
+ Discovery's API classification remains **release-candidate public**.
8
+
9
+ These results qualify a configuration on an authored synthetic dataset. They do not
10
+ establish general production quality, guarantee the first candidate, or authorize an
11
+ action. Applications still own intent decomposition, dependencies, arguments and
12
+ customer responses. Evaluate your own capability corpus and traffic before adoption.
13
+
14
+ ## Tested configuration and assessment history
15
+
16
+ The campaign used suite v3: 240 cases across support, inventory and scheduling, with 80
17
+ per domain and 120/60/60 train/calibration/held-out cases. There are 60 scenario
18
+ families overall and 15 held-out families. Related paraphrases share a partition. The
19
+ fresh held-out families were withheld from calibration; this is not an external blind
20
+ benchmark, and published fixtures are now exposed regression material.
21
+
22
+ The frozen configuration used eight candidates; gpt-6-luna with reasoning effort none
23
+ for planning, selection and ordinary turns; text-embedding-3-small at 1,536 dimensions;
24
+ hybrid weights 0.75 semantic/0.25 lexical; and unavailable on hybrid failure. These are
25
+ campaign settings, not framework model defaults. Model access, explicit indexes and
26
+ finite budgets remain caller-owned. Returned generation model identities matched the
27
+ requested alias; an immutable model snapshot was not available.
28
+
29
+ The full 240-case pass and three 60-case held-out passes were assessed independently,
30
+ including each mode's declared calibration baseline and critical cohorts. Ready-task p95
31
+ had to be at most 15 seconds, with a 30-second absolute deadline. Quality thresholds
32
+ were 95% recall and selected-candidate accuracy, 90% coverage, at most 1% false
33
+ selection on true no-match cases, and zero safety violations. Critical-cohort
34
+ regressions greater than five percentage points failed the gate. No pooled average
35
+ replaced a failed pass.
36
+
37
+ The original workflow assessment was **40/48**, with all four modes unqualified. A
38
+ separately versioned offline wording-checker correction reassessed the same saved
39
+ evidence as **48/48**, or **12/12 per mode**. Seven date-rendering assessments and one
40
+ negated-completion assessment changed. This was not a fresh live trial or a model
41
+ improvement. The eight actual deterministic fallback responses, tool receipts,
42
+ operational failures, original grades and accounting remain unchanged. The earlier,
43
+ different campaign's 22/48 result was not regraded.
44
+
45
+ ## Full-suite results
46
+
47
+ Accuracy is measured on selected answerable matched cases. Coverage retains missed and
48
+ failed decisions in its denominator. Recall uses the suite's answerable cases. The
49
+ remaining cases include true no-match and eligibility-exclusion scenarios.
50
+
51
+ | Mode | Compatible recall at 8 | Selected accuracy | Selection coverage | Ready-task p95 | Revised overall |
52
+ | ----------------- | ---------------------- | ----------------- | ------------------ | -------------- | ----------------------------- |
53
+ | lexical/native | 118/120 | 118/118 | 118/120 | 4.14 s | Qualified |
54
+ | lexical/dedicated | 118/120 | 118/118 | 118/120 | 6.15 s | Qualified |
55
+ | hybrid/native | 120/120 | 120/120 | 120/120 | 4.42 s | Unqualified: incremental gain |
56
+ | hybrid/dedicated | 120/120 | 117/117 | 117/120 | 5.98 s | Unqualified: incremental gain |
57
+
58
+ Case-level descriptive 95% Wilson intervals are below. Paraphrases within families are
59
+ correlated; these are not family-independent uncertainty estimates or guarantees.
60
+
61
+ | Mode | Recall interval | Accuracy interval | Coverage interval |
62
+ | ----------------- | --------------- | ----------------- | ----------------- |
63
+ | lexical/native | 94.13–99.54% | 96.85–100.00% | 94.13–99.54% |
64
+ | lexical/dedicated | 94.13–99.54% | 96.85–100.00% | 94.13–99.54% |
65
+ | hybrid/native | 96.90–100.00% | 96.90–100.00% | 96.90–100.00% |
66
+ | hybrid/dedicated | 96.90–100.00% | 96.82–100.00% | 92.91–99.15% |
67
+
68
+ Every mode made **0/48 false selections** on full-suite true no-match cases (95% Wilson
69
+ interval 0–7.41%). Permission/lifecycle violations, policy-forbidden export, forbidden
70
+ choices, read-to-mutation selections and commit exposure/execution were zero. An
71
+ eligible competing read/prepare candidate in a shortlist is not an execution violation.
72
+
73
+ Retrieval alone still produced candidates for **47/48 lexical** and **48/48 hybrid**
74
+ true no-match cases. Models abstained or otherwise safely declined these requests. This
75
+ high retrieval false-positive rate is a practical reason to retain ordinary model
76
+ selection and clarification rather than automatically execute the highest-scoring tool.
77
+
78
+ Full-suite selection outcomes were 118 selected/49 abstained/73 unperformed for each
79
+ lexical mode; 120/48/72 for hybrid/native; and 117 selected/48 abstained/3 invalid
80
+ outputs/72 unperformed for hybrid/dedicated. Unperformed means no model decision was
81
+ requested; it is not fabricated abstention.
82
+
83
+ ## Held-out repetitions and workflows
84
+
85
+ Each held-out pass had 60 cases, 15 families, 24 answerable cases and 12 true no-match
86
+ cases. Recall was **24/24** for every mode in every pass. Columns show passes 1, 2 and 3
87
+ in order. Consistency counts identical outcome/choice across repetitions, including
88
+ non-answerable cases; it is reported separately from gate results.
89
+
90
+ | Mode | Coverage by pass | Selected accuracy by pass | p95 seconds by pass | Consistent cases |
91
+ | ----------------- | ------------------- | ------------------------- | ------------------- | ---------------- |
92
+ | lexical/native | 24/24; 24/24; 24/24 | 24/24; 24/24; 24/24 | 3.66; 3.64; 3.85 | 57/60 |
93
+ | lexical/dedicated | 24/24; 24/24; 24/24 | 24/24; 24/24; 24/24 | 5.56; 6.22; 5.89 | 59/60 |
94
+ | hybrid/native | 24/24; 24/24; 24/24 | 24/24; 24/24; 24/24 | 4.70; 3.94; 4.25 | 59/60 |
95
+ | hybrid/dedicated | 23/24; 24/24; 23/24 | 23/23; 24/24; 23/23 | 6.39; 5.41; 6.02 | 58/60 |
96
+
97
+ For 24/24, the 95% Wilson interval is 86.20–100%; for 23/24, 79.76–99.26%; and for
98
+ 23/23, 85.69–100%. False selection was 0/12 in every pass (interval 0–24.25%). All
99
+ critical-cohort comparisons and ready-task latency gates passed independently.
100
+
101
+ Hybrid/dedicated retained four invalid selector outputs: three in the full pass and one
102
+ in held-out pass 1. A separate unavailable selector decision in held-out pass 3 also
103
+ remains a failure in coverage. Neither outcome was replaced by a successful rerun.
104
+
105
+ All modes passed the revised 12-workflow assessment. Across the 48 workflows, the
106
+ application performed 24 authorized reads and 12 approval-required preparations, with no
107
+ commit exposure. Application delivery was already 48/48 using eight observed fallbacks;
108
+ the offline correction changed wording-dependent grading only.
109
+
110
+ ## Why hybrid is not promoted
111
+
112
+ Promotion required at least two percentage points higher compatible recall, or at least
113
+ 20% lower model-input tokens at unchanged recall, against lexical retrieval with the
114
+ same candidate limit and selection mechanism. The observed recall increase was **1.67
115
+ percentage points** (120/120 versus 118/120).
116
+
117
+ | Mode | Full-pass model-input tokens |
118
+ | ----------------- | ---------------------------- |
119
+ | lexical/native | 619,786 |
120
+ | lexical/dedicated | 445,346 |
121
+ | hybrid/native | 715,689 |
122
+ | hybrid/dedicated | 466,759 |
123
+
124
+ These model-input counts exclude query-embedding tokens. Hybrid increased model input
125
+ instead of achieving the required reduction. Both hybrid modes therefore remain
126
+ unqualified overall despite passing their matching, workflow and safety gates. No
127
+ ranking weights, thresholds, aliases or labels were tuned to turn this into a pass.
128
+
129
+ The current campaign recorded 3,097 generation/embedding attempts and 5,521 HTTP
130
+ requests including token preflights; reported input/output tokens were 3,889,390/108,203
131
+ with complete current-campaign usage. Earlier campaign evidence retains an unknown-usage
132
+ provider failure and conservative charging. Stage receipts are not added again to
133
+ overlapping run/campaign totals. Offline regrading and release verification purchase
134
+ zero additional model calls.
135
+
136
+ ## Evidence bindings and reproduction
137
+
138
+ The live transport receipts and original model wording remain private. The following
139
+ safe bindings identify the frozen inputs and derived assessment:
140
+
141
+ - Suite v3: `sha256:5e5f0cb1a848b733174e6e2e444e7c3bd8a90680fcd6009c7323d635c3605f69`.
142
+ - Qualification workflows:
143
+ `sha256:8fabf71450f0d3b04a9d4b543d844bc94b0e70e20c698897db127a7d516cff61`.
144
+ - Campaign: `sha256:187b918cea5aecc0ab4075f2770310a0eddc314bf02d5d147008db773e5b6b76`.
145
+ - Original report bytes:
146
+ `sha256:052d0e1abb1d39f527cf0258510058ebd3bc4ef07ff557761df4d447c6ef607e`.
147
+ - Revised report:
148
+ `sha256:f354d381035f6b28b21c3812d45ac69e14e5577c980f93dc53ba7b7a57d89def`.
149
+
150
+ The correction uses synthetic-wording.v2 and workflow-wording-regrade.v1. See the
151
+ [evaluation and offline-regrade commands](discovery-live.md) for reproducible
152
+ provider-free checks and explicit, separately budgeted live execution. No-key examples
153
+ validate integration contracts; they do not recreate these live observations.
@@ -12,3 +12,12 @@ Read:
12
12
  - [Replay and trace-to-golden](replay-and-trace-to-golden.md)
13
13
  - [Live evals](../live-evals.md)
14
14
  - [EvalOps export interfaces](../evalops.md)
15
+
16
+ ## Discovery and selection evaluation
17
+
18
+ Use [discovery evaluation](../discovery.md#offline-evaluation-and-quality) for frozen
19
+ synthetic cases, compatible and forbidden ID sets, separate retrieval/selection metrics,
20
+ and explicit accounting completeness. No-key CI validates contracts; model quality
21
+ requires a separately configured evaluation. The
22
+ [discovery live campaign](discovery-live.md) provides bounded, resumable evaluation with
23
+ caller-supplied clients; its default command remains provider-free.
package/docs/index.md CHANGED
@@ -73,3 +73,12 @@ Models propose; applications validate, authorize, execute, and audit.
73
73
  - [Security disclosure](public-framework/security-disclosure.md)
74
74
  - [API reference](api.md)
75
75
  - [Public API policy](api/public-api-policy.md)
76
+
77
+ ## Capability discovery
78
+
79
+ The optional release-candidate `ai-capability-framework/discovery` API provides a simple
80
+ search facade, result-bound routers, explicit hybrid retrieval and dedicated selection,
81
+ and provider-free evaluation. Start with
82
+ [finding capabilities for a task](discovery.md). For opt-in provider evaluation, see the
83
+ [discovery live evaluation guide](evals/discovery-live.md) and the
84
+ [qualification results and limits](evals/discovery-qualification.md).
package/docs/release.md CHANGED
@@ -2,6 +2,25 @@
2
2
 
3
3
  This checklist prepares an AICF public release for GitHub and npm distribution.
4
4
 
5
+ ## Discovery prerelease
6
+
7
+ Discovery is release-candidate public. Recommend lexical retrieval with ordinary model
8
+ tool selection; dedicated selection is optional and hybrid remains experimental. Link
9
+ the [qualification report](evals/discovery-qualification.md) in release notes. Its
10
+ qualified lexical results apply to a tested synthetic configuration, and the revised
11
+ workflow assessment is an offline checker correction rather than new live trials.
12
+
13
+ Use a reviewed pull request, passing hosted Linux Node 20/22/24 checks, merge, and an
14
+ exact-commit manual release dry-run before pushing the matching prerelease tag. Local
15
+ checks do not replace hosted checks. Publish both packages to `next`, preserving
16
+ `latest`, then verify exact-version registry installs.
17
+
18
+ The publication and dry-run workflows run `npm run check` plus certification with
19
+ `VITEST_MAX_WORKERS=2`. Publication is serialized; registry failures fail closed unless
20
+ npm explicitly reports E404 for an absent version. Local npm login is not the OIDC
21
+ publishing mechanism. Verify package ownership and the trusted publisher for both
22
+ packages before tagging; never substitute a stored npm token.
23
+
5
24
  ## Preflight
6
25
 
7
26
  - Confirm the release branch contains only public framework material.
@@ -261,11 +280,12 @@ npm view "ai-capability-framework@${VERSION}" version
261
280
  npm view "@aicf/agent-skills@${VERSION}" version
262
281
  ```
263
282
 
264
- If only `@aicf/agent-skills` published, fix the workflow or npm ownership issue and
265
- retry the root package publish at the same version from the same tag. If only the root
266
- package published, retry the agent-skills publish at the same version from the same tag.
267
- Do not move the public tag, delete the published version, or reuse a published npm
268
- version as a normal recovery path.
283
+ If only one package published, mark the release incomplete and inspect its registry
284
+ metadata before taking further action. The ordinary workflow rejects already-published
285
+ targets, so do not blindly rerun it. Use a new coordinated release candidate when the
286
+ existing workflow cannot safely complete the missing package. Do not move the public
287
+ tag, delete the published version, or reuse a published npm version as a normal recovery
288
+ path.
269
289
 
270
290
  If the tagged code is wrong, or if the failed package cannot be safely published from
271
291
  the same commit, bump both package versions and ship a follow-up patch or release
package/docs/runtime.md CHANGED
@@ -89,6 +89,12 @@ are incompatible with active read-only controls.
89
89
  Use `formatCapabilitySliceForModel()` to render concise model-facing capability guidance
90
90
  without private diagnostics, internal policy rules, or full output schemas.
91
91
 
92
+ `filterEligibleCapabilities(request)` exposes the same runtime eligibility filters
93
+ without ranking or count truncation. It returns `eligible` manifests in registry order
94
+ and `excluded` capability IDs with their existing reasons. The default router uses this
95
+ helper before scoring and applying its capability limit. Eligibility is a request-time
96
+ filter; normal execution authorization still applies.
97
+
92
98
  ## Policy Broker
93
99
 
94
100
  `DefaultPolicyBroker` wraps the Core `decideCapability()` control plane and adds runtime
@@ -167,3 +173,19 @@ node examples/runtime-support-billing/run-mock.mjs
167
173
  It loads the support manifests, routes read and prepare capabilities, executes a ticket
168
174
  read, prepares a refund case that requires approval, records a host approval, and
169
175
  commits only through `AicfActionLifecycleManager`.
176
+
177
+ ### Optional shared provider runs
178
+
179
+ `createAicfProviderRun` joins explicitly managed application planning, discovery,
180
+ selection, and Responses tool-loop calls under one reservation ledger and absolute
181
+ deadline. Its immutable snapshots retain unknown usage, pending work, and unique
182
+ attempts. The default router and ordinary runner calls remain source-compatible. See the
183
+ [shared-run example](../examples/12-capability-discovery-selection/README.md#shared-run-integration)
184
+ for task-bound routing, optional selection, metadata tracing, and offline replay.
185
+
186
+ ## Optional capability discovery
187
+
188
+ Use [capability discovery](discovery.md) to retrieve an eligible shortlist and pass its
189
+ result-bound router to an ordinary model/tool runner. The optional discovery subpath
190
+ preserves runtime authorization and read/prepare boundaries; default routing stays
191
+ unchanged. Dedicated model selection is explicitly invoked.
@@ -0,0 +1,345 @@
1
+ # From a customer request to a tool
2
+
3
+ Use `ai-capability-framework@1.1.0-rc.1` for these discovery APIs. Lexical/native is the
4
+ recommended default. Hybrid is experimental and opt-in; the
5
+ [qualification report](../../docs/evals/discovery-qualification.md) explains its limits.
6
+
7
+ The application AI produces tasks. Application code searches for relevant capabilities,
8
+ then its existing model chooses a tool from the shortlist. The runtime validates the
9
+ call and enforces execution and approval policy.
10
+
11
+ Run the complete no-key example from the repository root:
12
+
13
+ ```sh
14
+ npm run build
15
+ node examples/12-capability-discovery-selection/run-customer-mock.mjs
16
+ ```
17
+
18
+ The customer asks to read a ticket and prepare a refund for its order. A mocked planning
19
+ call returns two dependent tasks. Application code searches each task when ready, passes
20
+ the authorized read result into the next task's context, and uses ordinary model tool
21
+ calls to read the ticket and prepare a refund preview. The example's host policy
22
+ requires operator review. It stops with approval pending and never exposes or executes
23
+ refund commit.
24
+
25
+ The discovery integration needs only the registry, tasks, and existing runtime context:
26
+
27
+ ```js
28
+ import { createCapabilityDiscovery } from "ai-capability-framework/discovery";
29
+
30
+ const discovery = createCapabilityDiscovery({ registry });
31
+ const [result] = await discovery.search({
32
+ tasks: [{ id: "read-ticket", text: "Read ticket TCK-100." }],
33
+ runtimeContext
34
+ });
35
+ const router = discovery.routerFor(result);
36
+ // Pass router, the same runtimeContext, and the exact task text to your ordinary runner.
37
+ ```
38
+
39
+ The default profile uses lexical retrieval, up to eight candidates, no alias bonus or
40
+ diversity, and a 30-second discovery deadline. An earlier caller deadline wins. Search
41
+ accepts controls, existing eligibility filters and permission overrides, cancellation,
42
+ and a custom context builder. Batch results retain task IDs and input order. Use the
43
+ low-level discoverer for multiple fragments or advanced ranking.
44
+
45
+ `routerFor` reuses the issued shortlist without ranking or embedding again. Results are
46
+ immutable and bound to their issuing instance, original task text, runtime context, and
47
+ source. Keep the result in the same request; reconstructed or foreign results are
48
+ rejected. Changed source, identity, permissions, controls, cancellation, or expiry
49
+ cannot export a stale shortlist. Prepare dependent context before searching. Provider
50
+ export and execution retain their ordinary checks.
51
+
52
+ The example also runs no-match clarification, permission denial, and an explicitly
53
+ invoked mock hybrid companion. Planning and ordinary model usage are reported
54
+ separately: one planning turn and four ordinary turns, all synthetic. Lexical discovery
55
+ uses no provider calls. The hybrid companion uses one explicit index-build batch and one
56
+ query attempt; invalid-index rejection purchases no query embedding. No dedicated
57
+ selector runs.
58
+
59
+ ## Optional semantic search
60
+
61
+ Enable hybrid mode explicitly, using your configured embedding client and an index built
62
+ in a separate administrative operation:
63
+
64
+ ```js
65
+ import { createInMemoryDiscoveryBudget } from "ai-capability-framework/discovery";
66
+
67
+ const budget = createInMemoryDiscoveryBudget({
68
+ runId: runtimeContext.runId,
69
+ maxProviderCalls: 8,
70
+ maxInputTokens: 32000
71
+ });
72
+ const discovery = createCapabilityDiscovery({
73
+ registry,
74
+ mode: "hybrid",
75
+ embedding: { client: embeddingClient, index, maxInputTokens: 4000 }
76
+ });
77
+ const results = await discovery.search({ tasks, runtimeContext, budget });
78
+ ```
79
+
80
+ The standard hybrid starting weights are 0.75 semantic and 0.25 lexical. Failures return
81
+ unavailable unless lexical fallback is explicitly configured. Override `weights`,
82
+ `failurePolicy`, and `limits` on the facade as needed. Embedding options allow
83
+ overriding artifact bounds (16 MiB, 10,000 entries, 4,096 dimensions) and provider
84
+ character bounds (16,384 per text, 65,536 per call). The caller supplies the token
85
+ ceiling. Token enforcement and retry disabling remain embedding-client responsibilities.
86
+ Indexes must still match the exact source and embedding configuration; serving never
87
+ builds or repairs them.
88
+
89
+ The in-memory helper enforces a finite single-run budget in one process. A supplied
90
+ `maxEstimatedCost` also requires `embedding.maxEstimatedCostPerCall`; the framework
91
+ assumes no prices. Unknown consumption retains reserved allowance. Late completion
92
+ settles its reservation without restoring a cancelled result. An unresolved attempt
93
+ retains its reservation for the lifetime of the helper.
94
+
95
+ For distributed or durable enforcement, pass `budget: { ledger, policy }` with your own
96
+ ledger and existing budget policy. Reuse the scope across discovery calls in a run. Use
97
+ the shared-run companion below to account for managed planning and downstream model
98
+ calls; this example reports those stages separately. No default credentials, model
99
+ service, or live transport is supplied.
100
+
101
+ These mocks demonstrate contracts and integration. They do not establish real semantic
102
+ quality or guarantee that the first candidate is the correct tool. Applications own
103
+ decomposition, task dependencies, argument completion, and customer responses. A model
104
+ may choose a candidate or request clarification; scores never authorize execution.
105
+
106
+ ## Optional dedicated selection
107
+
108
+ Use the ordinary model/tool loop for the standard flow above. If your application needs
109
+ a separate model decision, explicitly call the same discovery instance's `select`
110
+ method:
111
+
112
+ ```js
113
+ const batch = await discovery.select({
114
+ results,
115
+ client: selectionClient,
116
+ budget,
117
+ maxInputTokens: 4000,
118
+ maxOutputTokens: 1000
119
+ });
120
+ ```
121
+
122
+ The framework recovers task text and context bindings from its own search results and
123
+ constructs candidate cards. Supply a configured `SelectionModelClient` with an explicit
124
+ `mock` marker and `generateStructured` method; input/output token ceilings are passed to
125
+ that client. Use the existing budget helper or your own `{ ledger, policy }` scope. Cost
126
+ caps require `maxEstimatedCostPerCall`, with optional host cost estimation. There is no
127
+ default model, account, price, or credential lookup.
128
+
129
+ `batch.outcomes` contains ordered selected/abstained decisions or safe failure outcomes
130
+ for matched tasks. Non-matched tasks stay in `batch.discovery` and are never represented
131
+ as model abstentions. `batch.usage` owns selection and repair usage once for the whole
132
+ batch; discovery usage remains in the original discovery results. Individual outcomes
133
+ carry no duplicate provider-usage receipt.
134
+
135
+ Cards preserve complete model descriptions, usage/exclusion guidance, input-field names,
136
+ and read/prepare distinctions. Scores, full schemas, runtime identities, hidden policy,
137
+ and paths are omitted. Optional `contextByQueryId` explicitly projects application data
138
+ for the model. Foreign/reconstructed results and incompatible invocation scopes are
139
+ rejected. Current source, eligibility, identity, controls, cancellation, and original
140
+ deadlines are rechecked; a new deadline can shorten the original bound.
141
+
142
+ Defaults are eight tasks, 32,000 serialized input characters, and one attempt. Override
143
+ `limits: { maxTasks, maxInputCharacters, maxAttempts }` up to 32 tasks, 128,000
144
+ characters, and two attempts. The same character ceiling bounds response parsing. With
145
+ two attempts, one repair may use safe issue codes and the original cards. Oversized
146
+ batches/cards are rejected without clipping or paid splitting. Provider, accounting,
147
+ stale-binding, budget, control, cancellation, and deadline failures cause no repair or
148
+ automatic candidate choice.
149
+
150
+ Advanced callers can pass the same low-level request to `buildCapabilitySelectionTasks`
151
+ and `ModelCapabilitySelector.select`; the helper derives its hashes from that request's
152
+ configured client and limits, without a provider call or manual fingerprint
153
+ construction.
154
+
155
+ The selector returns decisions; application argument completion and runtime execution
156
+ remain separate. Native search and `routerFor` never call the dedicated selector.
157
+ Selected-result routers, the optional Responses adapter, and managed full-run accounting
158
+ are available; see the shared-run integration below. Imports use the public
159
+ release-candidate discovery subpath.
160
+
161
+ Run the explicit selector companion:
162
+
163
+ ```sh
164
+ npm run build
165
+ node examples/12-capability-discovery-selection/run-selector-mock.mjs
166
+ ```
167
+
168
+ It demonstrates competition, single-candidate abstention, a skipped no-match task, and
169
+ one enabled repair. Across two explicit invocations it reports three mock provider
170
+ attempts and 420 synthetic total tokens, with complete reported usage. It executes no
171
+ tools and makes no embedding or live model calls. The fixture establishes contracts, not
172
+ model quality.
173
+
174
+ ## Advanced lexical example
175
+
176
+ Run from the repository root:
177
+
178
+ ```sh
179
+ npm run build
180
+ node examples/12-capability-discovery-selection/run-mock.mjs
181
+ ```
182
+
183
+ This example reuses the synthetic support manifests. Discovery returns independent
184
+ shortlists for four tasks, then the router turns one request into a bounded runtime
185
+ slice. Existing provider export checks produce the tool descriptors. A mocked ordinary
186
+ model/tool loop chooses the ticket lookup, executes the existing authorized runtime
187
+ handler, and returns an answer.
188
+
189
+ Discovery makes zero provider calls and reports complete zero token and cost totals. The
190
+ two ordinary mock model turns run locally. No key, network connection, embedding client,
191
+ or dedicated selector is used.
192
+
193
+ Imports use supported package subpaths. The executable retrieval fixtures include
194
+ compatible and forbidden capabilities without adding manifests to the normal inventory.
195
+
196
+ ## Hybrid mock
197
+
198
+ Run the explicit index build and hybrid example:
199
+
200
+ ```sh
201
+ npm run build
202
+ node examples/12-capability-discovery-selection/run-hybrid-mock.mjs
203
+ ```
204
+
205
+ This flow builds deterministic synthetic vectors, validates the complete index, and
206
+ round-trips it through host-owned memory storage. It demonstrates a semantic match with
207
+ zero lexical evidence, an invalid-index rejection before any query embedding, and
208
+ explicit lexical fallback. The ordinary mocked model/tool loop still performs tool
209
+ selection and an authorized read.
210
+
211
+ The flow records three logical mock embedding attempts: one document batch and two
212
+ independent query calls, including the query made by the ordinary runtime loop. All
213
+ embedding usage is labeled mock. These vectors provide contract evidence only. No live
214
+ embedding service or dedicated selector is used.
215
+
216
+ Hybrid callers supply an embedding client, complete model configuration, an index,
217
+ artifact and input limits, an absolute deadline, and a shared reservation ledger. Each
218
+ task joins its original fragment texts with newlines and makes at most one embedding
219
+ attempt, sequentially. The native-router wrapper forwards the caller's ledger and
220
+ deadline without changing ordinary runtime runners.
221
+
222
+ Storage implementations must atomically replace complete validated artifacts. Serving
223
+ does not load or rebuild an index implicitly. Stale source, model, revision, dimension,
224
+ or provenance bindings require explicit rebuilding or a configured whole-query lexical
225
+ fallback. An absent model revision does not establish an immutable embedding space.
226
+
227
+ Cancellation returns a fixed usage snapshot. If a provider attempt remains pending, its
228
+ reservation stays held until its observed completion settles it; host recovery handles
229
+ attempts that never finish. Clients enforce token ceilings and disable hidden retries.
230
+ Unreported usage and cost remain unknown.
231
+
232
+ ## Shared-run integration
233
+
234
+ Run `node examples/12-capability-discovery-selection/run-pipeline-mock.mjs` after
235
+ `npm run build`. The companion runs lexical/native, lexical/dedicated, hybrid/native,
236
+ and hybrid/dedicated paths through the existing tool loop. Each reads a ticket, carries
237
+ its order ID into refund preparation, and produces a preview requiring approval. It
238
+ makes no real provider calls.
239
+
240
+ Create one optional `createAicfProviderRun` with the existing runtime run ID, a
241
+ reservation budget, and an absolute deadline. Pass it to `search`; facade selection and
242
+ result-bound routers recover that scope. The ordinary Responses runner accepts
243
+ `providerExecution` with explicit model identity, provenance, input/output token
244
+ ceilings, and an application-supplied complete-input token preflight. Continuation
245
+ history is supplied to that preflight. No tokenizer, pricing, credentials, or model
246
+ defaults are discovered.
247
+
248
+ Dedicated selection remains optional:
249
+
250
+ ```js
251
+ const batch = await discovery.select({
252
+ results,
253
+ client: selectionClient,
254
+ maxInputTokens: 4000,
255
+ maxOutputTokens: 1000
256
+ });
257
+ const router = discovery.routerFor(batch, task.id);
258
+ ```
259
+
260
+ Here `results` came from a search using `providerRun`. Without a run, continue supplying
261
+ the existing explicit `budget`. A batch can select several independent tasks, but each
262
+ router exports only its own task's decision. Revalidation repeats neither ranking nor
263
+ provider work. The ordinary model still supplies arguments; normal policy, validation,
264
+ approval, and execution remain in force.
265
+
266
+ `createOpenAISelectionClient` wraps an existing Responses-compatible client and requires
267
+ a complete-input token preflight. It forwards cancellation and timeout, disables
268
+ transport retries, and uses a versioned strict structured-output projection. Embeddings
269
+ continue to use the caller's supplied client and separately built compatible index.
270
+
271
+ `providerRun.attempt` lets application planning or response calls share the same ledger.
272
+ Only calls made through the managed boundary are counted. The in-memory budget
273
+ optionally limits output tokens and retains allowance for unknown usage; use a host
274
+ ledger for distributed or durable enforcement. The runner preserves its legacy `usage`
275
+ field and adds an all-turn `providerUsage` receipt for managed turns. The run snapshot
276
+ combines unique attempts once across stages. Missing usage/cost remains unknown; mock
277
+ zero cost in this example is explicitly supplied.
278
+
279
+ New trace events contain bounded metadata and numeric receipts, including under
280
+ content-capture settings. Run-local retention stops at 256 events and reports overflow.
281
+ Hosts own trace retention and access. Hashes are not anonymization.
282
+
283
+ `createDiscoverySnapshot` creates a bounded metadata snapshot for the existing replay
284
+ extension. Snapshot validation checks bindings and membership; ranking replay
285
+ additionally requires original query fixtures and, for hybrid retrieval, compatible host
286
+ vector fixtures. It never calls a provider. Neither operation establishes model semantic
287
+ correctness. Existing `router_only` replay requires an explicit discovery handler for
288
+ these snapshots. Live replay remains separately enabled and budgeted.
289
+
290
+ The companion reports five, seven, seven, and nine customer-run mock attempts
291
+ respectively. Administrative index-build usage is reported separately. Failure cases
292
+ cover clarification, abstention, permission/source revocation, budget exhaustion, and
293
+ invalid-index rejection without query embedding. Synthetic responses and vectors
294
+ establish integration behavior; they do not qualify retrieval or selection quality.
295
+
296
+ ## Installed package and evaluation
297
+
298
+ Fake data: all requests, capabilities, identities, and outputs are synthetic. No secrets
299
+ are needed. No live provider calls occur.
300
+
301
+ Command from an installed consumer directory:
302
+
303
+ ```sh
304
+ node node_modules/ai-capability-framework/examples/12-capability-discovery-selection/run-customer-mock.mjs
305
+ ```
306
+
307
+ Expected output: one planning turn, four ordinary turns, one authorized read, one
308
+ approval-required preparation, and zero commits. The separately invoked hybrid companion
309
+ uses two mock embedding attempts. All five commands use supported public imports and
310
+ resolve manifests relative to their own modules, independent of the working directory.
311
+
312
+ Run `npm run eval:discovery:mock` from the repository, or run the packaged
313
+ `run-evaluation-mock.mjs` in the same way, for the frozen 240-case lexical baseline. The
314
+ suite has three domains, 120 train cases, 60 calibration cases, and 60 held-out cases,
315
+ with scenario families confined to one partition. Independently scripted selection
316
+ observations demonstrate selected, abstained, unavailable, and invalid-output outcomes.
317
+ Their accounting is explicitly incomplete because no provider attempts were observed. No
318
+ selector is invoked by the evaluator.
319
+
320
+ The baseline retains retrieval misses and false positives; its rates are informational.
321
+ Do not tune against the frozen held-out set. These fixtures do not qualify live models.
322
+ See the [discovery guide](../../docs/discovery.md) for defaults, ownership, limits,
323
+ budgets, replay boundaries, and evaluation metrics.
324
+
325
+ ## Optional live evaluation campaign
326
+
327
+ The
328
+ [offline regrading guide](../../docs/evals/discovery-live.md#regrade-saved-wording-offline)
329
+ shows how to reassess saved wording without model access. It preserves frozen results,
330
+ observed delivery and historical accounting, and writes a separate versioned report.
331
+
332
+ `npm run eval:discovery:live` validates the corrected v3 suite and fixed-eight-candidate
333
+ schedule with zero provider calls. `npm run eval:discovery:campaign:mock` exercises the
334
+ complete campaign, durable accounting, three held-out repetitions, and 48 workflow runs
335
+ with deterministic clients. It writes evidence under ignored `.aicf/` and makes no
336
+ quality claim about real models.
337
+
338
+ Paid execution requires `--live`, an explicit host configuration, compatible model
339
+ clients, token preflights, matching offline acceptance evidence, and a pinned
340
+ continuation of the original campaign budget. This command performs no paid work by
341
+ default. The application owns response facts and validates model wording with a recorded
342
+ deterministic fallback. Plans, terminal task outcomes and component grades are retained
343
+ in ignored evidence. The original suite and all existing companions are preserved. See
344
+ the [evaluation guide](../../docs/evals/discovery-live.md) for stages, resume behavior,
345
+ limits, and interpretation.
@@ -0,0 +1,52 @@
1
+ // Application-owned planning fixtures; these are not additional manifests.
2
+ export const customerRequest =
3
+ "Read ticket TCK-100 and prepare a refund for its order.";
4
+ export const plannedTasks = [
5
+ {
6
+ id: "read-ticket",
7
+ text: "Read ticket TCK-100 for the refund review.",
8
+ dependsOn: []
9
+ },
10
+ {
11
+ id: "prepare-refund",
12
+ text: "Prepare a refund case for the order from support ticket TCK-100.",
13
+ dependsOn: ["read-ticket"]
14
+ }
15
+ ];
16
+ export const taskExpectations = {
17
+ "read-ticket": {
18
+ compatibleIds: ["support.ticket.get"],
19
+ forbiddenIds: ["support.refund.commit_case"]
20
+ },
21
+ "prepare-refund": {
22
+ compatibleIds: ["support.refund.prepare_case"],
23
+ forbiddenIds: ["support.refund.commit_case"]
24
+ }
25
+ };
26
+
27
+ /** Example application validation, deliberately separate from framework discovery. */
28
+ export function validatePlannedTasks(value) {
29
+ if (!Array.isArray(value) || !value.length || value.length > 8)
30
+ throw new Error("Invalid application task plan.");
31
+ const known = new Set();
32
+ return value.map((task) => {
33
+ if (
34
+ !task ||
35
+ typeof task !== "object" ||
36
+ Object.keys(task).some((key) => !["id", "text", "dependsOn"].includes(key)) ||
37
+ typeof task.id !== "string" ||
38
+ !task.id.trim() ||
39
+ known.has(task.id) ||
40
+ typeof task.text !== "string" ||
41
+ !task.text.trim() ||
42
+ task.text.length > 4000 ||
43
+ !Array.isArray(task.dependsOn) ||
44
+ task.dependsOn.some((id) => !known.has(id)) ||
45
+ new Set(task.dependsOn).size !== task.dependsOn.length
46
+ ) {
47
+ throw new Error("Invalid application task plan.");
48
+ }
49
+ known.add(task.id);
50
+ return { id: task.id, text: task.text, dependsOn: [...task.dependsOn] };
51
+ });
52
+ }