testerkit 0.4.0__py3-none-any.whl

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 (521) hide show
  1. testerkit/__init__.py +68 -0
  2. testerkit/_docs/_assets/operator-ui/channels/table.png +0 -0
  3. testerkit/_docs/_assets/operator-ui/dashboard/runs.png +0 -0
  4. testerkit/_docs/_assets/operator-ui/dashboard/stations.png +0 -0
  5. testerkit/_docs/_assets/operator-ui/events/filters.png +0 -0
  6. testerkit/_docs/_assets/operator-ui/events/table.png +0 -0
  7. testerkit/_docs/_assets/operator-ui/explore/chart.png +0 -0
  8. testerkit/_docs/_assets/operator-ui/explore/filters.png +0 -0
  9. testerkit/_docs/_assets/operator-ui/explore/plot-controls.png +0 -0
  10. testerkit/_docs/_assets/operator-ui/files/table.png +0 -0
  11. testerkit/_docs/_assets/operator-ui/launch/form.png +0 -0
  12. testerkit/_docs/_assets/operator-ui/metrics/filters.png +0 -0
  13. testerkit/_docs/_assets/operator-ui/metrics/pareto.png +0 -0
  14. testerkit/_docs/_assets/operator-ui/metrics/ppk.png +0 -0
  15. testerkit/_docs/_assets/operator-ui/metrics/yield.png +0 -0
  16. testerkit/_docs/_assets/operator-ui/results/detail-header.png +0 -0
  17. testerkit/_docs/_assets/operator-ui/results/detail-measurements.png +0 -0
  18. testerkit/_docs/_assets/operator-ui/results/detail-overview.png +0 -0
  19. testerkit/_docs/_assets/operator-ui/results/detail-steps.png +0 -0
  20. testerkit/_docs/_assets/operator-ui/results/stats.png +0 -0
  21. testerkit/_docs/_assets/operator-ui/results/table.png +0 -0
  22. testerkit/_docs/_assets/operator-ui/tour/designer.png +0 -0
  23. testerkit/_docs/_assets/operator-ui/tour/docs.png +0 -0
  24. testerkit/_docs/_assets/operator-ui/tour/fixtures.png +0 -0
  25. testerkit/_docs/_assets/operator-ui/tour/instruments.png +0 -0
  26. testerkit/_docs/_assets/operator-ui/tour/parts.png +0 -0
  27. testerkit/_docs/_assets/operator-ui/tour/profiles.png +0 -0
  28. testerkit/_docs/_assets/operator-ui/tour/stations.png +0 -0
  29. testerkit/_docs/_assets/operator-ui/tour/tests.png +0 -0
  30. testerkit/_docs/_assets/operator-ui/tour/uuts.png +0 -0
  31. testerkit/_docs/concepts/configuration/capabilities.md +447 -0
  32. testerkit/_docs/concepts/configuration/fixtures.md +335 -0
  33. testerkit/_docs/concepts/configuration/index.md +14 -0
  34. testerkit/_docs/concepts/configuration/parts.md +276 -0
  35. testerkit/_docs/concepts/configuration/stations.md +214 -0
  36. testerkit/_docs/concepts/data/data-stores.md +199 -0
  37. testerkit/_docs/concepts/data/event-log.md +185 -0
  38. testerkit/_docs/concepts/data/event-sourcing.md +76 -0
  39. testerkit/_docs/concepts/data/flight-streaming.md +58 -0
  40. testerkit/_docs/concepts/data/index.md +17 -0
  41. testerkit/_docs/concepts/data/sessions.md +78 -0
  42. testerkit/_docs/concepts/data/three-verbs.md +260 -0
  43. testerkit/_docs/concepts/execution/index.md +13 -0
  44. testerkit/_docs/concepts/execution/outcomes.md +199 -0
  45. testerkit/_docs/concepts/execution/step-hierarchy.md +170 -0
  46. testerkit/_docs/concepts/execution/step-manifest.md +115 -0
  47. testerkit/_docs/concepts/index.md +40 -0
  48. testerkit/_docs/concepts/overview/ai-integration.md +57 -0
  49. testerkit/_docs/concepts/overview/architecture.md +357 -0
  50. testerkit/_docs/concepts/overview/index.md +14 -0
  51. testerkit/_docs/concepts/overview/platform-vs-framework.md +147 -0
  52. testerkit/_docs/concepts/overview/pytest.md +53 -0
  53. testerkit/_docs/concepts/overview/tiers.md +46 -0
  54. testerkit/_docs/how-to/catalog/datasheet-to-test.md +169 -0
  55. testerkit/_docs/how-to/catalog/index.md +11 -0
  56. testerkit/_docs/how-to/configuration/configuring-stations.md +364 -0
  57. testerkit/_docs/how-to/configuration/custom-drivers.md +484 -0
  58. testerkit/_docs/how-to/configuration/index.md +13 -0
  59. testerkit/_docs/how-to/configuration/mock-mode.md +342 -0
  60. testerkit/_docs/how-to/data/benchmarking.md +120 -0
  61. testerkit/_docs/how-to/data/capture-an-artifact.md +84 -0
  62. testerkit/_docs/how-to/data/capture-waveform.md +110 -0
  63. testerkit/_docs/how-to/data/choosing-a-channel-verb.md +108 -0
  64. testerkit/_docs/how-to/data/compare-runs.md +120 -0
  65. testerkit/_docs/how-to/data/export-results.md +104 -0
  66. testerkit/_docs/how-to/data/find-flaky-tests.md +108 -0
  67. testerkit/_docs/how-to/data/grafana-dashboards.md +148 -0
  68. testerkit/_docs/how-to/data/index.md +23 -0
  69. testerkit/_docs/how-to/data/mcp-debug-failures.md +125 -0
  70. testerkit/_docs/how-to/data/mcp-query-runs.md +120 -0
  71. testerkit/_docs/how-to/data/querying-channels.md +117 -0
  72. testerkit/_docs/how-to/data/querying-events.md +85 -0
  73. testerkit/_docs/how-to/data/stream-live-channel.md +134 -0
  74. testerkit/_docs/how-to/execution/custom-operator-ui.md +136 -0
  75. testerkit/_docs/how-to/execution/index.md +21 -0
  76. testerkit/_docs/how-to/execution/limits.md +193 -0
  77. testerkit/_docs/how-to/execution/managing-sessions.md +100 -0
  78. testerkit/_docs/how-to/execution/multi-uut-testing.md +211 -0
  79. testerkit/_docs/how-to/execution/operator-prompts.md +151 -0
  80. testerkit/_docs/how-to/execution/profiles.md +304 -0
  81. testerkit/_docs/how-to/execution/spec-driven-testing.md +169 -0
  82. testerkit/_docs/how-to/execution/test-context.md +212 -0
  83. testerkit/_docs/how-to/execution/traceability.md +252 -0
  84. testerkit/_docs/how-to/execution/vector-expansion.md +394 -0
  85. testerkit/_docs/how-to/execution/writing-tests.md +363 -0
  86. testerkit/_docs/how-to/index.md +59 -0
  87. testerkit/_docs/how-to/overview/index.md +11 -0
  88. testerkit/_docs/how-to/overview/mcp-integration.md +168 -0
  89. testerkit/_docs/how-to/overview/operator-ui-tour.md +234 -0
  90. testerkit/_docs/integration/data/grafana.md +162 -0
  91. testerkit/_docs/integration/data/index.md +15 -0
  92. testerkit/_docs/integration/data/lakehouse-import.md +226 -0
  93. testerkit/_docs/integration/data/logging.md +131 -0
  94. testerkit/_docs/integration/data/results-api.md +51 -0
  95. testerkit/_docs/integration/index.md +20 -0
  96. testerkit/_docs/integration/runtime/harness.md +281 -0
  97. testerkit/_docs/integration/runtime/index.md +13 -0
  98. testerkit/_docs/integration/runtime/instruments.md +284 -0
  99. testerkit/_docs/integration/runtime/pytest-existing.md +315 -0
  100. testerkit/_docs/reference/catalog/cookbook.md +389 -0
  101. testerkit/_docs/reference/catalog/index.md +11 -0
  102. testerkit/_docs/reference/catalog/schema.md +375 -0
  103. testerkit/_docs/reference/cli.md +660 -0
  104. testerkit/_docs/reference/configuration.md +406 -0
  105. testerkit/_docs/reference/data/channels-schema.md +145 -0
  106. testerkit/_docs/reference/data/event-types.md +554 -0
  107. testerkit/_docs/reference/data/events-schema.md +120 -0
  108. testerkit/_docs/reference/data/files-schema.md +141 -0
  109. testerkit/_docs/reference/data/index.md +18 -0
  110. testerkit/_docs/reference/data/models.md +2229 -0
  111. testerkit/_docs/reference/data/outputs.md +82 -0
  112. testerkit/_docs/reference/data/parquet-schema.md +529 -0
  113. testerkit/_docs/reference/data/performance-limits.md +224 -0
  114. testerkit/_docs/reference/data/query-api.md +247 -0
  115. testerkit/_docs/reference/index.md +69 -0
  116. testerkit/_docs/reference/operator-ui/channels/detail.md +82 -0
  117. testerkit/_docs/reference/operator-ui/channels/list.md +70 -0
  118. testerkit/_docs/reference/operator-ui/dashboard.md +87 -0
  119. testerkit/_docs/reference/operator-ui/designer.md +167 -0
  120. testerkit/_docs/reference/operator-ui/events.md +89 -0
  121. testerkit/_docs/reference/operator-ui/files.md +74 -0
  122. testerkit/_docs/reference/operator-ui/fixtures.md +100 -0
  123. testerkit/_docs/reference/operator-ui/instruments.md +126 -0
  124. testerkit/_docs/reference/operator-ui/launch.md +79 -0
  125. testerkit/_docs/reference/operator-ui/live.md +102 -0
  126. testerkit/_docs/reference/operator-ui/measurements.md +159 -0
  127. testerkit/_docs/reference/operator-ui/metrics.md +217 -0
  128. testerkit/_docs/reference/operator-ui/parts.md +98 -0
  129. testerkit/_docs/reference/operator-ui/profiles.md +103 -0
  130. testerkit/_docs/reference/operator-ui/results/detail.md +214 -0
  131. testerkit/_docs/reference/operator-ui/results/list.md +106 -0
  132. testerkit/_docs/reference/operator-ui/stations.md +98 -0
  133. testerkit/_docs/reference/operator-ui/tests.md +173 -0
  134. testerkit/_docs/reference/operator-ui/uuts.md +67 -0
  135. testerkit/_docs/reference/overview/index.md +11 -0
  136. testerkit/_docs/reference/overview/pytest-native.md +142 -0
  137. testerkit/_docs/reference/overview/skills.md +177 -0
  138. testerkit/_docs/reference/pytest/fixtures.md +342 -0
  139. testerkit/_docs/reference/pytest/index.md +12 -0
  140. testerkit/_docs/reference/pytest/markers.md +257 -0
  141. testerkit/_docs/reference/runtime/api.md +246 -0
  142. testerkit/_docs/reference/runtime/client.md +280 -0
  143. testerkit/_docs/reference/runtime/connect.md +140 -0
  144. testerkit/_docs/reference/runtime/index.md +13 -0
  145. testerkit/_docs/tutorial/01-first-test.md +113 -0
  146. testerkit/_docs/tutorial/02-mock-instruments.md +88 -0
  147. testerkit/_docs/tutorial/03-fixtures.md +169 -0
  148. testerkit/_docs/tutorial/04-limits.md +139 -0
  149. testerkit/_docs/tutorial/05-configuration.md +194 -0
  150. testerkit/_docs/tutorial/06-specifications.md +273 -0
  151. testerkit/_docs/tutorial/07-real-instruments.md +245 -0
  152. testerkit/_docs/tutorial/08-capabilities.md +223 -0
  153. testerkit/_docs/tutorial/09-production.md +374 -0
  154. testerkit/_docs/tutorial/10-live-monitoring.md +156 -0
  155. testerkit/_docs/tutorial/11-waveforms-and-evidence.md +169 -0
  156. testerkit/_docs/tutorial/12-continuous-monitoring.md +145 -0
  157. testerkit/_docs/tutorial/13-parallel-testing.md +233 -0
  158. testerkit/_docs/tutorial/index.md +61 -0
  159. testerkit/_docs/tutorial/quickstart.md +282 -0
  160. testerkit/analysis/__init__.py +9 -0
  161. testerkit/analysis/_common.py +24 -0
  162. testerkit/analysis/measurement_facets.py +524 -0
  163. testerkit/analysis/measurements_query.py +1458 -0
  164. testerkit/analysis/metrics.py +389 -0
  165. testerkit/analysis/runs_query.py +434 -0
  166. testerkit/analysis/steps_query.py +413 -0
  167. testerkit/api/__init__.py +6 -0
  168. testerkit/api/_mime.py +71 -0
  169. testerkit/api/app.py +1171 -0
  170. testerkit/api/dialogs/__init__.py +36 -0
  171. testerkit/api/dialogs/manager.py +617 -0
  172. testerkit/api/dialogs/models.py +79 -0
  173. testerkit/api/models.py +80 -0
  174. testerkit/api/responses.py +205 -0
  175. testerkit/api/runner.py +222 -0
  176. testerkit/api/schemas.py +311 -0
  177. testerkit/benchmark/__init__.py +34 -0
  178. testerkit/benchmark/concurrency.py +248 -0
  179. testerkit/benchmark/core.py +232 -0
  180. testerkit/benchmark/runner.py +628 -0
  181. testerkit/benchmark/scenario.py +313 -0
  182. testerkit/benchmark/system.py +191 -0
  183. testerkit/benchmark/workloads.py +507 -0
  184. testerkit/catalog/__init__.py +6 -0
  185. testerkit/catalog/generic/generic_dmm.yaml +61 -0
  186. testerkit/catalog/generic/generic_eload.yaml +31 -0
  187. testerkit/catalog/generic/generic_fgen.yaml +56 -0
  188. testerkit/catalog/generic/generic_oscilloscope.yaml +45 -0
  189. testerkit/catalog/generic/generic_psu.yaml +77 -0
  190. testerkit/catalog/generic/generic_smu.yaml +73 -0
  191. testerkit/channels.py +538 -0
  192. testerkit/cli/__init__.py +32 -0
  193. testerkit/cli/_common.py +113 -0
  194. testerkit/cli/_time.py +179 -0
  195. testerkit/cli/benchmark_cmd.py +56 -0
  196. testerkit/cli/catalog_cmd.py +39 -0
  197. testerkit/cli/daemon.py +157 -0
  198. testerkit/cli/data_cmd.py +1040 -0
  199. testerkit/cli/discover_cmd.py +94 -0
  200. testerkit/cli/docs_cmd.py +100 -0
  201. testerkit/cli/instrument.py +172 -0
  202. testerkit/cli/mcp_cmd.py +37 -0
  203. testerkit/cli/metrics.py +366 -0
  204. testerkit/cli/project.py +312 -0
  205. testerkit/cli/root.py +14 -0
  206. testerkit/cli/runs.py +412 -0
  207. testerkit/cli/schema_cmd.py +87 -0
  208. testerkit/cli/serve_cmd.py +50 -0
  209. testerkit/cli/setup_cmd.py +604 -0
  210. testerkit/cli/station.py +294 -0
  211. testerkit/cli/validate.py +112 -0
  212. testerkit/client.py +463 -0
  213. testerkit/connect.py +635 -0
  214. testerkit/data/__init__.py +8 -0
  215. testerkit/data/_accumulator_pool.py +455 -0
  216. testerkit/data/_atomic.py +59 -0
  217. testerkit/data/_collection_indices.py +67 -0
  218. testerkit/data/_daemon_lifecycle.py +535 -0
  219. testerkit/data/_duckdb_daemon.py +695 -0
  220. testerkit/data/_duckdb_flight_server.py +813 -0
  221. testerkit/data/_event_filters.py +15 -0
  222. testerkit/data/_event_reader.py +101 -0
  223. testerkit/data/_flight_errors.py +199 -0
  224. testerkit/data/_flight_query.py +202 -0
  225. testerkit/data/_flight_retry.py +148 -0
  226. testerkit/data/_flight_subscribe.py +67 -0
  227. testerkit/data/_index_epoch.py +342 -0
  228. testerkit/data/_ipc_writer.py +185 -0
  229. testerkit/data/_json_safe.py +63 -0
  230. testerkit/data/_process.py +18 -0
  231. testerkit/data/_push_relay.py +124 -0
  232. testerkit/data/_runs_duckdb_daemon.py +2704 -0
  233. testerkit/data/_session_reaper.py +110 -0
  234. testerkit/data/_sql_helpers.py +30 -0
  235. testerkit/data/_store.py +24 -0
  236. testerkit/data/backends/__init__.py +7 -0
  237. testerkit/data/backends/_event_accumulator.py +957 -0
  238. testerkit/data/backends/_row_helpers.py +1172 -0
  239. testerkit/data/backends/parquet.py +1143 -0
  240. testerkit/data/backends/protocol.py +35 -0
  241. testerkit/data/channels/__init__.py +8 -0
  242. testerkit/data/channels/_flight_daemon.py +75 -0
  243. testerkit/data/channels/client.py +242 -0
  244. testerkit/data/channels/flight_manager.py +88 -0
  245. testerkit/data/channels/index.py +664 -0
  246. testerkit/data/channels/models.py +418 -0
  247. testerkit/data/channels/server.py +162 -0
  248. testerkit/data/channels/store.py +1481 -0
  249. testerkit/data/data_dir.py +61 -0
  250. testerkit/data/duckdb_manager.py +79 -0
  251. testerkit/data/event_log.py +384 -0
  252. testerkit/data/event_store.py +768 -0
  253. testerkit/data/events.py +1025 -0
  254. testerkit/data/exporters/__init__.py +6 -0
  255. testerkit/data/exporters/_helpers.py +40 -0
  256. testerkit/data/exporters/csv_exporter.py +168 -0
  257. testerkit/data/exporters/hdf5.py +234 -0
  258. testerkit/data/exporters/json_exporter.py +229 -0
  259. testerkit/data/exporters/mdf4.py +201 -0
  260. testerkit/data/exporters/stdf.py +255 -0
  261. testerkit/data/exporters/tdms.py +292 -0
  262. testerkit/data/files/__init__.py +71 -0
  263. testerkit/data/files/_backend.py +207 -0
  264. testerkit/data/files/_catalog_daemon.py +84 -0
  265. testerkit/data/files/catalog.py +218 -0
  266. testerkit/data/files/catalog_manager.py +325 -0
  267. testerkit/data/files/models.py +60 -0
  268. testerkit/data/files/serializers.py +414 -0
  269. testerkit/data/files/store.py +463 -0
  270. testerkit/data/files/streaming.py +783 -0
  271. testerkit/data/models.py +604 -0
  272. testerkit/data/ref.py +152 -0
  273. testerkit/data/retention.py +297 -0
  274. testerkit/data/run_store.py +367 -0
  275. testerkit/data/runs_duckdb_manager.py +103 -0
  276. testerkit/data/schema_dispatch.py +191 -0
  277. testerkit/data/schema_migrate.py +76 -0
  278. testerkit/data/schema_versions.py +85 -0
  279. testerkit/data/schemas.py +288 -0
  280. testerkit/data/subscribers/__init__.py +48 -0
  281. testerkit/data/subscribers/_base.py +20 -0
  282. testerkit/data/subscribers/_output_file.py +25 -0
  283. testerkit/data/subscribers/replay.py +55 -0
  284. testerkit/environment.py +84 -0
  285. testerkit/execution/__init__.py +11 -0
  286. testerkit/execution/_git.py +190 -0
  287. testerkit/execution/_state.py +740 -0
  288. testerkit/execution/accessors.py +54 -0
  289. testerkit/execution/audit.py +51 -0
  290. testerkit/execution/cascade.py +85 -0
  291. testerkit/execution/connections.py +491 -0
  292. testerkit/execution/harness.py +1931 -0
  293. testerkit/execution/instrument_events.py +42 -0
  294. testerkit/execution/limits.py +154 -0
  295. testerkit/execution/metadata.py +102 -0
  296. testerkit/execution/mocks.py +63 -0
  297. testerkit/execution/profiles.py +616 -0
  298. testerkit/execution/run_scope.py +1331 -0
  299. testerkit/execution/session_scope.py +196 -0
  300. testerkit/execution/sidecar.py +280 -0
  301. testerkit/execution/site_runner.py +705 -0
  302. testerkit/execution/sites.py +183 -0
  303. testerkit/execution/sync.py +294 -0
  304. testerkit/execution/uut_provider.py +231 -0
  305. testerkit/execution/vectors.py +205 -0
  306. testerkit/execution/verify.py +396 -0
  307. testerkit/expand.py +75 -0
  308. testerkit/files.py +235 -0
  309. testerkit/fixtures/__init__.py +6 -0
  310. testerkit/fixtures/manager.py +357 -0
  311. testerkit/grafana/__init__.py +1 -0
  312. testerkit/grafana/bootstrap.py +61 -0
  313. testerkit/grafana/cli.py +314 -0
  314. testerkit/grafana/dashboards/asset_utilization.json +92 -0
  315. testerkit/grafana/dashboards/channel_explorer.json +77 -0
  316. testerkit/grafana/dashboards/event_log.json +92 -0
  317. testerkit/grafana/dashboards/failure_pareto.json +104 -0
  318. testerkit/grafana/dashboards/measurement_distribution.json +97 -0
  319. testerkit/grafana/dashboards/measurement_trend.json +161 -0
  320. testerkit/grafana/dashboards/station_comparison.json +95 -0
  321. testerkit/grafana/dashboards/test_duration.json +104 -0
  322. testerkit/grafana/dashboards/unit_traceability.json +73 -0
  323. testerkit/grafana/dashboards/yield_overview.json +189 -0
  324. testerkit/grafana/provisioning/dashboards.yaml.j2 +12 -0
  325. testerkit/grafana/provisioning/datasources.yaml.j2 +17 -0
  326. testerkit/grafana/server.py +282 -0
  327. testerkit/init.py +724 -0
  328. testerkit/instruments/__init__.py +10 -0
  329. testerkit/instruments/base.py +82 -0
  330. testerkit/instruments/discovery/__init__.py +62 -0
  331. testerkit/instruments/discovery/_base.py +174 -0
  332. testerkit/instruments/discovery/lxi.py +152 -0
  333. testerkit/instruments/discovery/ni.py +95 -0
  334. testerkit/instruments/discovery/serial.py +73 -0
  335. testerkit/instruments/discovery/visa.py +98 -0
  336. testerkit/instruments/lifecycle.py +213 -0
  337. testerkit/instruments/loader.py +79 -0
  338. testerkit/instruments/locks.py +178 -0
  339. testerkit/instruments/mocks.py +230 -0
  340. testerkit/instruments/observer.py +270 -0
  341. testerkit/instruments/observers/__init__.py +36 -0
  342. testerkit/instruments/observers/_base.py +68 -0
  343. testerkit/instruments/observers/daqmx.py +70 -0
  344. testerkit/instruments/observers/descriptor.py +69 -0
  345. testerkit/instruments/observers/generic.py +92 -0
  346. testerkit/instruments/observers/lantz.py +31 -0
  347. testerkit/instruments/observers/modbus.py +96 -0
  348. testerkit/instruments/observers/motion.py +68 -0
  349. testerkit/instruments/observers/ni_modular.py +73 -0
  350. testerkit/instruments/observers/ophyd.py +80 -0
  351. testerkit/instruments/observers/pymeasure.py +120 -0
  352. testerkit/instruments/observers/qcodes.py +66 -0
  353. testerkit/instruments/observers/scpi.py +88 -0
  354. testerkit/instruments/observers/tektronix.py +57 -0
  355. testerkit/instruments/observers/visa.py +103 -0
  356. testerkit/instruments/pool.py +459 -0
  357. testerkit/instruments/proxy.py +59 -0
  358. testerkit/instruments/route_manager.py +329 -0
  359. testerkit/instruments/routed_proxy.py +88 -0
  360. testerkit/instruments/server.py +508 -0
  361. testerkit/instruments/switch.py +43 -0
  362. testerkit/instruments/visa.py +294 -0
  363. testerkit/matching/__init__.py +6 -0
  364. testerkit/matching/service.py +969 -0
  365. testerkit/mcp/__init__.py +6 -0
  366. testerkit/mcp/server.py +681 -0
  367. testerkit/mcp/tools.py +1868 -0
  368. testerkit/models/__init__.py +18 -0
  369. testerkit/models/capability.py +598 -0
  370. testerkit/models/catalog.py +76 -0
  371. testerkit/models/data_options.py +153 -0
  372. testerkit/models/enums.py +334 -0
  373. testerkit/models/instrument.py +152 -0
  374. testerkit/models/instrument_asset.py +25 -0
  375. testerkit/models/part.py +271 -0
  376. testerkit/models/part_manifest.py +96 -0
  377. testerkit/models/project.py +114 -0
  378. testerkit/models/station.py +140 -0
  379. testerkit/models/test_config.py +748 -0
  380. testerkit/ontology/__init__.py +39 -0
  381. testerkit/ontology/schema.py +188 -0
  382. testerkit/ontology/testerkit.yaml +1420 -0
  383. testerkit/parts/__init__.py +8 -0
  384. testerkit/parts/context.py +181 -0
  385. testerkit/parts/folder.py +251 -0
  386. testerkit/parts/loader.py +27 -0
  387. testerkit/prompts/__init__.py +17 -0
  388. testerkit/prompts/core.py +133 -0
  389. testerkit/pytest_plugin/__init__.py +1287 -0
  390. testerkit/pytest_plugin/autouse.py +369 -0
  391. testerkit/pytest_plugin/helpers.py +354 -0
  392. testerkit/pytest_plugin/hooks.py +1982 -0
  393. testerkit/pytest_plugin/markers.py +203 -0
  394. testerkit/pytest_plugin/retry.py +37 -0
  395. testerkit/pytest_plugin/sweeps.py +117 -0
  396. testerkit/queries.py +78 -0
  397. testerkit/reports/__init__.py +6 -0
  398. testerkit/reports/core.py +492 -0
  399. testerkit/reports/datasheet.py +831 -0
  400. testerkit/reports/templates/datasheet.html +383 -0
  401. testerkit/reports/templates/default.html +153 -0
  402. testerkit/sbom.py +142 -0
  403. testerkit/schema_export.py +101 -0
  404. testerkit/signals.py +63 -0
  405. testerkit/skills/README.md +58 -0
  406. testerkit/skills/templates/project-instructions.md +125 -0
  407. testerkit/skills/testerkit-analysis/SKILL.md +87 -0
  408. testerkit/skills/testerkit-capture/SKILL.md +114 -0
  409. testerkit/skills/testerkit-data/SKILL.md +138 -0
  410. testerkit/skills/testerkit-datasheets/SKILL.md +100 -0
  411. testerkit/skills/testerkit-datasheets/agents/scaffold-writer.md +115 -0
  412. testerkit/skills/testerkit-datasheets/agents/section-extractor.md +98 -0
  413. testerkit/skills/testerkit-datasheets/agents/section-reviewer.md +153 -0
  414. testerkit/skills/testerkit-datasheets/agents/section-splitter.md +89 -0
  415. testerkit/skills/testerkit-datasheets/agents/section-writer.md +226 -0
  416. testerkit/skills/testerkit-datasheets/references/catalog-pipeline.md +271 -0
  417. testerkit/skills/testerkit-datasheets/references/process-queue.md +42 -0
  418. testerkit/skills/testerkit-datasheets/references/scaffold.md +156 -0
  419. testerkit/skills/testerkit-datasheets/references/test-pipeline.md +312 -0
  420. testerkit/skills/testerkit-debug/SKILL.md +127 -0
  421. testerkit/skills/testerkit-interactive/SKILL.md +188 -0
  422. testerkit/skills/testerkit-interactive/references/live-ui-patterns.md +102 -0
  423. testerkit/skills/testerkit-mocks/SKILL.md +128 -0
  424. testerkit/skills/testerkit-parts/SKILL.md +126 -0
  425. testerkit/skills/testerkit-profiles/SKILL.md +139 -0
  426. testerkit/skills/testerkit-sites/SKILL.md +140 -0
  427. testerkit/skills/testerkit-stations/SKILL.md +146 -0
  428. testerkit/skills/testerkit-tests/SKILL.md +136 -0
  429. testerkit/store.py +1639 -0
  430. testerkit/ui/__init__.py +71 -0
  431. testerkit/ui/_asgi.py +162 -0
  432. testerkit/ui/app.py +32 -0
  433. testerkit/ui/components/__init__.py +13 -0
  434. testerkit/ui/components/artifact_viewer.py +250 -0
  435. testerkit/ui/components/channel_values.py +159 -0
  436. testerkit/ui/components/event_timeline.py +222 -0
  437. testerkit/ui/components/execution_gantt.py +210 -0
  438. testerkit/ui/components/file_streams.py +147 -0
  439. testerkit/ui/components/instrument_activity.py +146 -0
  440. testerkit/ui/components/session_table.py +118 -0
  441. testerkit/ui/pages/__init__.py +25 -0
  442. testerkit/ui/pages/channels/__init__.py +4 -0
  443. testerkit/ui/pages/channels/detail.py +932 -0
  444. testerkit/ui/pages/channels/list.py +515 -0
  445. testerkit/ui/pages/dashboard.py +236 -0
  446. testerkit/ui/pages/designer/__init__.py +5 -0
  447. testerkit/ui/pages/designer/graph.py +635 -0
  448. testerkit/ui/pages/designer/matching.py +663 -0
  449. testerkit/ui/pages/designer/page.py +593 -0
  450. testerkit/ui/pages/designer/properties.py +591 -0
  451. testerkit/ui/pages/designer/state.py +468 -0
  452. testerkit/ui/pages/docs/__init__.py +6 -0
  453. testerkit/ui/pages/docs/index.py +95 -0
  454. testerkit/ui/pages/docs/page.py +698 -0
  455. testerkit/ui/pages/events/__init__.py +3 -0
  456. testerkit/ui/pages/events/list.py +263 -0
  457. testerkit/ui/pages/explore.py +1108 -0
  458. testerkit/ui/pages/files/__init__.py +4 -0
  459. testerkit/ui/pages/files/detail.py +426 -0
  460. testerkit/ui/pages/files/list.py +447 -0
  461. testerkit/ui/pages/fixtures/__init__.py +8 -0
  462. testerkit/ui/pages/fixtures/detail.py +280 -0
  463. testerkit/ui/pages/fixtures/edit.py +370 -0
  464. testerkit/ui/pages/fixtures/list.py +180 -0
  465. testerkit/ui/pages/fixtures/new.py +195 -0
  466. testerkit/ui/pages/instruments/__init__.py +4 -0
  467. testerkit/ui/pages/instruments/detail.py +320 -0
  468. testerkit/ui/pages/instruments/edit.py +482 -0
  469. testerkit/ui/pages/instruments/list.py +249 -0
  470. testerkit/ui/pages/instruments/new.py +200 -0
  471. testerkit/ui/pages/launch.py +261 -0
  472. testerkit/ui/pages/live.py +124 -0
  473. testerkit/ui/pages/metrics_page.py +1229 -0
  474. testerkit/ui/pages/parts/__init__.py +11 -0
  475. testerkit/ui/pages/parts/detail.py +202 -0
  476. testerkit/ui/pages/parts/edit.py +310 -0
  477. testerkit/ui/pages/parts/list.py +160 -0
  478. testerkit/ui/pages/parts/new.py +170 -0
  479. testerkit/ui/pages/parts/requirements.py +153 -0
  480. testerkit/ui/pages/parts/stations.py +199 -0
  481. testerkit/ui/pages/profiles/__init__.py +4 -0
  482. testerkit/ui/pages/profiles/detail.py +113 -0
  483. testerkit/ui/pages/profiles/list.py +86 -0
  484. testerkit/ui/pages/results/__init__.py +4 -0
  485. testerkit/ui/pages/results/detail.py +631 -0
  486. testerkit/ui/pages/results/list.py +230 -0
  487. testerkit/ui/pages/stations/__init__.py +4 -0
  488. testerkit/ui/pages/stations/detail.py +256 -0
  489. testerkit/ui/pages/stations/edit.py +273 -0
  490. testerkit/ui/pages/stations/list.py +180 -0
  491. testerkit/ui/pages/stations/new.py +311 -0
  492. testerkit/ui/pages/tests/__init__.py +4 -0
  493. testerkit/ui/pages/tests/detail.py +152 -0
  494. testerkit/ui/pages/tests/list.py +194 -0
  495. testerkit/ui/pages/uuts/__init__.py +4 -0
  496. testerkit/ui/pages/uuts/list.py +97 -0
  497. testerkit/ui/shared/__init__.py +8 -0
  498. testerkit/ui/shared/components.py +1826 -0
  499. testerkit/ui/shared/dialogs.py +105 -0
  500. testerkit/ui/shared/event_binding.py +194 -0
  501. testerkit/ui/shared/layout.py +314 -0
  502. testerkit/ui/shared/services.py +1719 -0
  503. testerkit/ui/shared/timestamps.py +21 -0
  504. testerkit/ui/static/branding/favicon-16.png +0 -0
  505. testerkit/ui/static/branding/favicon-32.png +0 -0
  506. testerkit/ui/static/branding/favicon-48.png +0 -0
  507. testerkit/ui/static/branding/testerkit-icon-256.png +0 -0
  508. testerkit/ui/static/branding/testerkit-mark.svg +1 -0
  509. testerkit/ui/static/branding/testerkit-wordmark.svg +1 -0
  510. testerkit/ui/static/global.css +465 -0
  511. testerkit/utils/__init__.py +17 -0
  512. testerkit/utils/enum_meta.py +800 -0
  513. testerkit/utils/paths.py +75 -0
  514. testerkit/utils/ranges.py +257 -0
  515. testerkit/validation.py +82 -0
  516. testerkit/verbs.py +142 -0
  517. testerkit-0.4.0.dist-info/METADATA +250 -0
  518. testerkit-0.4.0.dist-info/RECORD +521 -0
  519. testerkit-0.4.0.dist-info/WHEEL +4 -0
  520. testerkit-0.4.0.dist-info/entry_points.txt +5 -0
  521. testerkit-0.4.0.dist-info/licenses/LICENSE +191 -0
@@ -0,0 +1,70 @@
1
+ # Channels — list view
2
+
3
+ **URL:** `/channels`
4
+
5
+ Every channel TesterKit has seen — streaming numeric / array signals
6
+ captured during test runs (scope traces, PSU readback, sensor logs).
7
+ Each row shows a live sparkline of the last 50 samples and the
8
+ latest value; values update in place as new samples arrive. Click a
9
+ row to drill into the [single-channel chart](detail.md).
10
+
11
+ ## Table
12
+
13
+ ![Channels — table](../../../_assets/operator-ui/channels/table.png)
14
+
15
+ A count above the table tells you how many channels have been seen.
16
+
17
+ | Column | What it shows |
18
+ |---|---|
19
+ | Channel ID | The channel's identifier — typically `<instrument-role>.<signal>` or `<channel-name>` |
20
+ | Latest | The most recent sample, with units appended when known. `—` when no samples yet. |
21
+ | History | An inline sparkline of the last 50 samples (or `—` for series with fewer than 2 samples). |
22
+ | Type | Sample data type (e.g. `scalar:float`, `array:float`) from the channel descriptor |
23
+ | Instrument | The instrument role this channel belongs to, when known |
24
+ | Last updated | When the most recent sample arrived, in browser-local time |
25
+
26
+ The table is dense — rows are about 30 pixels tall; sparklines
27
+ render inside the row at 80×24 pixels.
28
+
29
+ ## Filters
30
+
31
+ A filter card above the table narrows the list: **Channel ID contains**,
32
+ **Type**, **Instrument**, and a **Since / Until** date window, plus a
33
+ **Refresh** button. When you arrive from a run (via its detail page), a
34
+ banner scopes the list to that session with a Clear button.
35
+
36
+ ## Live updates
37
+
38
+ The view refreshes live as channels appear and update — no manual
39
+ reload needed. Cells re-render in place; unchanged rows don't repaint,
40
+ so the view stays calm during quiet periods. If live events aren't
41
+ available, the page falls back to polling every couple of seconds.
42
+
43
+ ## Empty state
44
+
45
+ When no channels have been written yet, the table is replaced with a card
46
+ explaining how channels get populated: "Channels appear once a test
47
+ writes to the channel store (e.g. `context.observe('scope', value)`
48
+ or instrument observers)."
49
+
50
+ ## Underlying data
51
+
52
+ Channel samples are stored separately from runs and measurements.
53
+ Programmatic access goes through `ChannelStore`
54
+ (`from testerkit.data.channels.store import ChannelStore`); there is no
55
+ first-class CLI equivalent today.
56
+
57
+ ## Common tasks
58
+
59
+ - **Watch a sensor live during a test** — open `/channels`, find the
60
+ row, watch the Latest column and sparkline update.
61
+ - **Drill into one channel's full history** — click any row to open
62
+ the [single-channel detail](detail.md) with a full chart + raw data
63
+ table + session/date filters.
64
+
65
+ ## See also
66
+
67
+ - [Channel detail](detail.md) — the per-channel view you reach by
68
+ clicking a row
69
+ - [Concepts → Data stores](../../../concepts/data/data-stores.md) — why
70
+ ChannelStore is separate from EventStore and the parquet runs index
@@ -0,0 +1,87 @@
1
+ # Dashboard
2
+
3
+ **URL:** `/`
4
+
5
+ The home page. Two short sections: configured stations as cards, and
6
+ recent runs as a compact table. For a fresh install with neither
7
+ stations nor runs, the page swaps to a three-step Getting Started
8
+ card instead.
9
+
10
+ ## Stations
11
+
12
+ ![Dashboard — stations](../../_assets/operator-ui/dashboard/stations.png)
13
+
14
+ One card per station configured in the project. Each card shows:
15
+
16
+ | Element | What it shows |
17
+ |---|---|
18
+ | Title | Station name (falls back to the station id if the name is left blank) |
19
+ | Status badge | A green outlined `Ready` badge |
20
+ | Description | The station's description, when set |
21
+ | Identifier row | Station id + location, prefixed with tag and pin icons |
22
+ | Start Test button | Jumps to `/launch?station=<id>` ([Launch Test](launch.md), prefilled with this station) |
23
+
24
+ When no stations are configured but runs exist, the section renders
25
+ an empty-state card naming the cause and the next step — add a station
26
+ YAML under `stations/`.
27
+
28
+ ## Recent Runs
29
+
30
+ ![Dashboard — recent runs](../../_assets/operator-ui/dashboard/runs.png)
31
+
32
+ A 10-row table of the most recent finished runs across the project.
33
+ Runs still in progress (not yet finished) are NOT shown here — open
34
+ the [Results list](results/list.md) to see them. The Dashboard's table
35
+ is deliberately a quick-glance summary.
36
+
37
+ | Column | What it shows |
38
+ |---|---|
39
+ | UUT | UUT serial number |
40
+ | Station | Station hostname (the machine an operator recognizes), not the internal station id |
41
+ | Started | Run start timestamp, browser-local time |
42
+ | Outcome | Outcome status; a bell badge appears (linking to the live view) when the run has operator dialogs waiting |
43
+
44
+ Click a row to open the [Results detail](results/detail.md) for that run.
45
+
46
+ When no runs have been recorded yet, the section renders an empty-state
47
+ card naming the cause and the next step — launch a test to populate
48
+ the list.
49
+
50
+ ## Getting Started (empty state)
51
+
52
+ When the project has **neither stations nor runs**, the page swaps
53
+ to a Getting Started card with three numbered steps:
54
+
55
+ 1. **Create a station** — buttons for "New Station" (jumps to the
56
+ create-station form) and a one-liner pointing at `testerkit station
57
+ init` on the CLI
58
+ 2. **Write a test** — `testerkit new-test <name>` command snippet
59
+ 3. **Run it** — `pytest --mock-instruments` command snippet
60
+
61
+ Below the steps, a hint card points at `testerkit init --starter` for
62
+ authors who'd rather start from a fully populated example project.
63
+
64
+ ## Live updates
65
+
66
+ The Dashboard loads its data once when you open the page; it doesn't
67
+ update live — refresh the browser to pick up new runs or station
68
+ changes. (The one exception: a run's pending-dialog bell badge
69
+ refreshes on its own every second.)
70
+
71
+ ## Underlying data
72
+
73
+ - Stations come from the local project's `stations/` directory
74
+ - Recent runs come from the same runs index as [Results list](results/list.md)
75
+
76
+ ## Common tasks
77
+
78
+ - **Open a station's launch form** — click `Start Test` on the station card
79
+ - **Drill into the latest run** — click any row in Recent Runs
80
+ - **Bootstrap a fresh project** — follow the three steps in the
81
+ Getting Started card
82
+
83
+ ## See also
84
+
85
+ - [Launch Test](launch.md) — start a new test session
86
+ - [Results list](results/list.md) — full run history beyond the 10
87
+ shown here
@@ -0,0 +1,167 @@
1
+ # System Designer
2
+
3
+ **URL:** `/designer`
4
+
5
+ The System Designer is the visual surface for wiring a part's
6
+ UUT pins to a station's instrument channels. Pick a part, pick
7
+ a station, click a pin, click an instrument channel — the page
8
+ draws the wire and auto-saves a fixture YAML to disk.
9
+
10
+ The bottom of the page has three tabs (Connections, Station Type,
11
+ YAML Preview) that always reflect the current graph state.
12
+
13
+ > **Experimental.** The System Designer is less mature than the rest
14
+ > of TesterKit, and the screen carries an "Experimental" banner. Expect
15
+ > rough edges, and check the saved fixture YAML before you depend on it
16
+ > in a run.
17
+
18
+ ## Top bar — selection
19
+
20
+ | Control | Purpose |
21
+ |---|---|
22
+ | Part | Dropdown of every part in the project's `parts/` directory. Picking one loads the part's pin map onto the design surface and, if a matching fixture YAML already exists for the auto-generated fixture ID, loads its connections too. |
23
+ | Station | Dropdown of every station in the project's `stations/` directory. Picking one loads the station's instruments + channels into the right-side pool of wiring targets. |
24
+ | Load Fixture | Opens a dialog listing every fixture in `fixtures/`. Pick one and the designer replaces the current connections with that fixture's. |
25
+ | Add Instrument | Opens a dialog to add an instrument to the current station definition. Fields: Instrument Type (optional dropdown from the project catalog — selecting one pre-fills channel names from the type's capability spec), Role Name (e.g. `dmm`, `psu`), Driver (e.g. `examples.drivers.DMM`), Channels (comma-separated). |
26
+
27
+ ## ID bar
28
+
29
+ | Field | Purpose |
30
+ |---|---|
31
+ | System ID | Identifier the Station Type tab uses when rendering the station-type YAML preview. The designer does not write a station-type YAML on its own — the preview is for copy-paste or for matching against a hand-written `stations/<id>.yaml`. |
32
+ | Fixture ID | Identifier for the fixture YAML the designer writes on auto-save. |
33
+
34
+ **Auto-save** writes `fixtures/<fixture_id>.yaml` whenever both IDs
35
+ are set and the graph has at least one connection. It runs after:
36
+
37
+ - Adding a wire (clicking a channel node while a pin is selected)
38
+ - Auto-Match
39
+ - Clear All
40
+
41
+ Because auto-save only writes when at least one connection exists,
42
+ **Clear All does not rewrite the file to the empty state** — the saved
43
+ fixture keeps its last non-empty connections until you add the next
44
+ wire. Drawer-initiated actions (Delete Connection, Delete Pin, Delete
45
+ Instrument, editing a pin field) don't save on their own either; add a
46
+ wire to write them out.
47
+
48
+ There is no Save button anywhere on the page.
49
+
50
+ ## Status bar
51
+
52
+ A row of counters and toggles, just above the design surface:
53
+
54
+ | Indicator | Meaning |
55
+ |---|---|
56
+ | `N / M pins wired` | How many of the part's pins are connected, and the total. |
57
+ | `N available` | How many pins are still unconnected. |
58
+ | `N instruments` | Instruments currently in the station. |
59
+ | Wiring: \<pin\> | When a pin is selected and waiting for a channel click, the status bar shows it in a blue chip. |
60
+ | Hide Unused checkbox | Filters the graph to only nodes with at least one connection. |
61
+ | Auto-Match button | Walks every unconnected pin that has a characteristic defined on it, asks the matching engine for a compatible channel from the current station, and creates the connection. Pins without a characteristic are skipped silently. |
62
+ | Clear All button | Wipes every connection on the current fixture in memory. The saved file is not rewritten to the empty state (auto-save only writes when at least one connection exists) — the cleared state lives in the page until you add the next wire. |
63
+
64
+ ## Design Surface
65
+
66
+ An [ECharts](https://echarts.apache.org/) graph showing UUT pins on
67
+ the left and instrument channels on the right, with wires drawn
68
+ between connected nodes. Three interactions:
69
+
70
+ - **Click a pin** — selects it. Status bar shows "Wiring: \<pin\>".
71
+ - **Click a channel** while a pin is selected — creates the
72
+ connection and clears the selection.
73
+ - **Click a wire** — opens the connection in the right-side
74
+ properties drawer. The drawer shows the connection's fields
75
+ (Point Name, UUT Pin, Net, Instrument, Channel, optional
76
+ Terminal) as read-only inputs with a Delete Connection button —
77
+ it's a remove-or-leave-alone affordance, not an edit form.
78
+
79
+ When no part is selected and no instruments are loaded, the
80
+ graph is replaced with a hint: "Select a part and load a station
81
+ to begin."
82
+
83
+ ## Bottom tabs
84
+
85
+ Three tabs share the panel below the graph; they always reflect the
86
+ current graph state.
87
+
88
+ ### Connections tab
89
+
90
+ A table of every current wire on the fixture.
91
+
92
+ | Column | What it shows |
93
+ |---|---|
94
+ | Point | The connection point name — auto-generated from pin + role at wire time and not user-editable |
95
+ | UUT Pin | The pin on the part side |
96
+ | Net | Net / signal name (optional, free-text) |
97
+ | Instrument | The station instrument the wire terminates on |
98
+ | Channel | The channel / terminal on that instrument |
99
+
100
+ Click a row to open the same read-only-with-Delete drawer that the
101
+ graph wires open.
102
+
103
+ When the fixture has no connections, the tab shows: "No connections
104
+ yet. Wire pins to instrument channels above."
105
+
106
+ ### Station Type tab
107
+
108
+ A live YAML preview of a station-type document derived from the
109
+ current station's instruments. The structure mirrors what
110
+ `/stations` consumes — useful for copying out to a
111
+ `stations/<id>.yaml` file by hand. The designer does not save this
112
+ on its own; you write it to disk yourself.
113
+
114
+ When no instruments are loaded, the tab shows: "No instruments
115
+ added yet."
116
+
117
+ ### YAML Preview tab
118
+
119
+ A live YAML preview of the **fixture** document — the file that
120
+ gets auto-saved to `fixtures/<fixture_id>.yaml`. Cross-check this
121
+ against the [Fixture YAML schema](../configuration.md#fixture-yaml)
122
+ to confirm the shape before you depend on the fixture in a run.
123
+
124
+ When the fixture has no connections, the tab shows: "No connections
125
+ to preview."
126
+
127
+ ## Pre-fill via URL
128
+
129
+ The designer accepts three URL query parameters; the URL is also
130
+ kept in sync (via `history.replaceState`) as you make selections so
131
+ the current state is bookmarkable.
132
+
133
+ | Parameter | Pre-fills |
134
+ |---|---|
135
+ | `part` | The Part dropdown — `?part=<id>` |
136
+ | `station` | The Station dropdown — `?station=<id>` |
137
+ | `fixture` | Loads an existing fixture by ID — `?fixture=<id>` |
138
+
139
+ ## Underlying data
140
+
141
+ - Parts come from `parts/`.
142
+ - Stations come from `stations/`.
143
+ - Fixtures (loaded and saved) live in `fixtures/`.
144
+ - Auto-Match uses the same
145
+ [capability matching](../../concepts/configuration/capabilities.md)
146
+ used elsewhere to find a station-channel that satisfies a part
147
+ pin's required signal direction.
148
+
149
+ ## Common tasks
150
+
151
+ - **Wire a fresh fixture from scratch** — pick Part + Station,
152
+ set Fixture ID, click pins → click channels. Save happens
153
+ automatically.
154
+ - **Iterate on an existing fixture** — open the designer with
155
+ `?fixture=<id>` (or pick it from Load Fixture), make changes,
156
+ watch the YAML Preview tab confirm the shape.
157
+ - **Generate a draft fixture quickly** — load Part + Station,
158
+ click Auto-Match, then refine the suggestions by clicking
159
+ individual wires.
160
+
161
+ ## See also
162
+
163
+ - [Fixtures](fixtures.md) — the entity reference for what gets saved
164
+ - [Configuration reference → Fixture YAML](../configuration.md#fixture-yaml) — the schema the designer writes
165
+ - [Concepts → Capabilities](../../concepts/configuration/capabilities.md) — how Auto-Match decides what fits
166
+ - [Stations](stations.md) — the station whose instruments populate the channel side
167
+ - [Parts](parts.md) — the part whose pins populate the UUT side
@@ -0,0 +1,89 @@
1
+ # Events
2
+
3
+ **URL:** `/events`
4
+
5
+ Browse the event log — the append-only stream of everything TesterKit
6
+ records: session lifecycle, run lifecycle, test step starts and ends,
7
+ measurements, channel starts, instrument writes, operator dialogs, and
8
+ diagnostics. The Results pages roll events up into runs; this page
9
+ shows them raw.
10
+
11
+ Use it to debug timing ("why did this run pause for 4 seconds?"),
12
+ trace instrument activity ("what did the DMM actually do during this
13
+ test?"), or audit dialog responses ("did the operator confirm
14
+ calibration before that batch?").
15
+
16
+ ## Filters
17
+
18
+ ![Events — filters](../../_assets/operator-ui/events/filters.png)
19
+
20
+ | Filter | What it does | Notes |
21
+ |---|---|---|
22
+ | Session ID | Restrict to events for one session | Free-text. Full or short (first 8 chars) UUID works. |
23
+ | Event type | Pick one of 15 curated event types, or `(any)` for all | The event log can hold any event type; this dropdown lists the categories worth a one-click filter — it is **not exhaustive**. Other event types (e.g. `fixture.uut_scanned`, `route.*`, `site.*`, `channel.*`) only appear under `(any)`. See the [Event types reference](../data/event-types.md) for the full list. |
24
+ | Role | Filter by instrument role (e.g. `dmm`, `psu`) | Free-text. |
25
+ | Since (ISO) | Earliest event timestamp | ISO-8601 string. |
26
+ | Limit | Maximum events fetched | Default 100, range 1–10,000. |
27
+ | Refresh | Force a re-fetch | Filter changes already auto-refresh. |
28
+
29
+ ## Table
30
+
31
+ ![Events — table](../../_assets/operator-ui/events/table.png)
32
+
33
+ One row per event, newest first. Above the table a count tells you
34
+ how many events matched.
35
+
36
+ | Column | What it shows |
37
+ |---|---|
38
+ | Timestamp | When the event was recorded, in browser-local time |
39
+ | Type | Event type (e.g. `channel.started`, `test.measurement`) |
40
+ | Role | Instrument or fixture role for events that carry one; otherwise blank |
41
+ | Summary | A type-specific one-liner — channel name for channel starts, measurement name + value + outcome for measurements, station id for session events, UUT serial for run events, step name for step events |
42
+
43
+ Click a row to open a detail dialog showing the full event JSON
44
+ (every field on the event record).
45
+
46
+ When no events match, the table area shows "No events match the
47
+ current filters." instead.
48
+
49
+ ## Bookmarkable URL state
50
+
51
+ All filters serialize to query parameters so a URL captures the view:
52
+
53
+ | Parameter | Meaning |
54
+ |---|---|
55
+ | `session_id` | Session UUID filter |
56
+ | `event_type` | One of the dropdown values (or omitted for `(any)`) |
57
+ | `role` | Instrument role filter |
58
+ | `since` | ISO-8601 lower bound |
59
+ | `limit` | Result cap (omitted at default 100) |
60
+
61
+ ## Underlying data
62
+
63
+ The page reads from the event log — the same append-only stream every
64
+ other view reads from. There is no first-class CLI equivalent today;
65
+ events are observable in aggregate via the Runs / Metrics CLIs, and
66
+ raw events can be read programmatically — see
67
+ [Querying events](../../how-to/data/querying-events.md).
68
+
69
+ For the schema of each event type, see
70
+ [Event types reference](../data/event-types.md).
71
+
72
+ For how the event log works, see
73
+ [Concepts → Event log](../../concepts/data/event-log.md).
74
+
75
+ ## Common tasks
76
+
77
+ - **Why did this run pause?** — Filter by Session ID, sort by
78
+ timestamp, look for gaps between consecutive `test.step_*` events.
79
+ - **Did the operator confirm before the batch?** — Filter event type
80
+ to `dialog.opened` then `dialog.responded`, narrow by Session ID.
81
+ - **Which channels did this test actually touch?** — Filter event
82
+ type to `channel.started`, scoped by Session ID.
83
+
84
+ ## See also
85
+
86
+ - [Results detail](results/detail.md) — the same events grouped into
87
+ a single run's tabs
88
+ - [Event types reference](../data/event-types.md)
89
+ - [Concepts → Event log](../../concepts/data/event-log.md)
@@ -0,0 +1,74 @@
1
+ # Files
2
+
3
+ `/files` lists the artifacts in the FileStore — images, waveforms, byte
4
+ streams, and any other file a test recorded via `observe(name, value)` or
5
+ `files.write(...)`. Each row links to a per-artifact detail page with an
6
+ inline viewer and a download button.
7
+
8
+ Reach it from the **Files** entry under DATA STORES in the sidebar.
9
+
10
+ ## Filters
11
+
12
+ Filter widgets render above the table:
13
+
14
+ - **Type** — dropdown of the MIME types (or file extensions) actually present,
15
+ `(any)` by default.
16
+ - **Filename contains** — case-insensitive substring match on the filename.
17
+ - **Since / Until** — created-at date window.
18
+ - **Session** — set only by deep-links from a run (`/results/{run_id}` →
19
+ Files), shown as a banner with a Clear affordance. There is no session
20
+ picker; operators scope by date / name / MIME, not by session UUID.
21
+
22
+ ## Table
23
+
24
+ ![Files — artifact list](../../_assets/operator-ui/files/table.png)
25
+
26
+ One row per artifact:
27
+
28
+ | Column | Meaning |
29
+ |--------|---------|
30
+ | Live | `● live` while the artifact is still being written (a stream), `○ done` once finalized. |
31
+ | Filename | The artifact's name (the `name` passed to `observe` / `files.write`, plus the format's extension). |
32
+ | Type | The recorded MIME type, or the file extension when the sidecar MIME is absent. |
33
+ | Size | Human-readable file size. |
34
+ | Created | When the artifact was written. |
35
+ | Download | A link that saves the artifact. |
36
+
37
+ Clicking a row opens `/files/{date}/{session_id}/{filename}`.
38
+
39
+ ## Detail page — viewer + download
40
+
41
+ The detail page shows a metadata card (MIME, extension, size, modified,
42
+ and the session it belongs to) and an **inline viewer chosen by file
43
+ type**. Supported viewers:
44
+
45
+ - **Image** (`.png`, `.jpg`, …) — rendered inline.
46
+ - **Video** (`.mp4`, `.webm`) — played inline.
47
+ - **JSON** — pretty-printed.
48
+ - **JSONL** (`.jsonl`, `.ndjson`) — one row per line in a table.
49
+ - **CSV** — parsed into a table.
50
+ - **Text** (`.txt`, `.log`, `.md`) — shown as plain text.
51
+ - **NPZ** — a `Waveform` chart.
52
+ - **NPY** — array stats.
53
+ - Anything else, or files over the viewer size cap — a **hex / download**
54
+ fallback.
55
+
56
+ The **Download** button saves the artifact rather than rendering it
57
+ inline; it works on every deployment.
58
+
59
+ ## Bookmarkable URL state
60
+
61
+ The list mirrors its filters into the URL (`?mime=`, `?name=`, `?since=`,
62
+ `?until=`, `?session_id=`), so a filtered view is shareable. The detail page's
63
+ URL is the artifact's full key — `/files/{date}/{session_id}/{filename}`.
64
+
65
+ ## Underlying data
66
+
67
+ Rows come from the **FileStore catalog** (the `testerkit_files` MCP tool and
68
+ `GET /api/files/catalog` expose the same list), never from a directory scan.
69
+
70
+ ## See also
71
+
72
+ - [How-to: capture an artifact](../../how-to/data/capture-an-artifact.md) — `observe` / `files.write` / `files.stream`
73
+ - [Concepts: the three verbs](../../concepts/data/three-verbs.md) — how `observe` routes a file to the FileStore
74
+ - [Channels](channels/list.md) — the time-series sibling store
@@ -0,0 +1,100 @@
1
+ # Fixtures
2
+
3
+ **URLs:** `/fixtures` (list), `/fixtures/new`, `/fixtures/{id}`, `/fixtures/{id}/edit`
4
+
5
+ A fixture is the wiring between a UUT's pins and a station's
6
+ instrument channels — which probe goes on which pin, which DMM
7
+ channel reads which voltage. A fixture is bound to a part (so it
8
+ gets used in the right runs) and is used at run time by stations
9
+ whose instruments cover the fixture's connections. The fixture's
10
+ connection rows themselves carry free-text UUT-pin and channel
11
+ fields — they're not validated against the part's pin map at
12
+ edit time.
13
+
14
+ ## List — `/fixtures`
15
+
16
+ A table with one row per fixture that is either configured in the project
17
+ (a YAML file exists) or has been observed in run history (no YAML file,
18
+ only referenced by past runs). Columns:
19
+
20
+ | Column | What it shows |
21
+ |---|---|
22
+ | Status | **Configured** chip (grey) — a YAML file exists. **Observed** chip (amber) — appears in run history but has no YAML file. |
23
+ | ID | Fixture identifier |
24
+ | Name | Human-readable name |
25
+ | Part | Part name (falls back to the bound part ID when the part name isn't resolvable) |
26
+ | Rev | Revision string (when set) |
27
+ | Connections | Count of pin → channel connections defined; `—` for Observed rows |
28
+ | Runs | Total runs that have used this fixture |
29
+ | Passed | Run count with outcome `passed` |
30
+ | Failed | Run count with outcome `failed` |
31
+ | Last Run | Most recent run start timestamp, browser-local time |
32
+
33
+ Above the table, a filter card with **All / Configured / Observed** buttons
34
+ narrows the view. The active filter is mirrored into the URL so the view is
35
+ bookmarkable.
36
+
37
+ A **New Fixture** button at the top right jumps to `/fixtures/new`.
38
+ Clicking a Configured row jumps to the detail view at `/fixtures/{id}`.
39
+ Observed rows are not clickable — no YAML exists to display.
40
+
41
+ When no fixtures are configured or observed, the table is replaced with an
42
+ empty-state card explaining the entity and offering a Create Fixture button.
43
+
44
+ ## Detail — `/fixtures/{id}`
45
+
46
+ A header bar (Back + Edit buttons), one Fixture Information card
47
+ (Fixture ID, Part Family, Connections count, Description, and a link
48
+ to the Part), then a tab strip with three tabs:
49
+
50
+ | Tab | Content |
51
+ |---|---|
52
+ | Pin Mappings | The connections table — one row per (UUT pin → instrument channel) mapping. Columns: Connection (the mapping's name), UUT Pin, Net, Instrument, Channel, Description. |
53
+ | Compatible Stations | Stations whose instruments cover this fixture's required instruments (matched by instrument role). |
54
+ | Diagram | A Mermaid-rendered diagram of the pin-to-instrument wiring. |
55
+
56
+ ## Edit — `/fixtures/{id}/edit`
57
+
58
+ The Edit page carries the fixture's info fields (Fixture ID, Name,
59
+ Part, Part Revision, Description) plus a **Pin Mappings** card where
60
+ you manage connections. The Part is a dropdown. The UUT Pin and
61
+ Instrument Channel fields on each connection row are **free-text
62
+ inputs**, not dropdowns sourced from the part pin map. The Instrument
63
+ dropdown on each connection row pulls its options from the union of
64
+ all stations' instruments in the project, so any instrument role
65
+ declared anywhere is selectable. Connections are managed as rows —
66
+ Add / Edit / Delete one at a time via per-row buttons and an Add
67
+ Connection dialog.
68
+
69
+ Not every YAML field is editable here — `instrument_terminal`,
70
+ `function`, `route`, `station_types`, `uut_resource`, and `sites` are
71
+ YAML-only.
72
+
73
+ ## New — `/fixtures/new`
74
+
75
+ A short form for just the fixture info (ID, Name, Part, Part Revision,
76
+ Description) — no connection rows. On create it redirects to the Edit
77
+ page, where you add the pin mappings.
78
+
79
+ ## Underlying data
80
+
81
+ Fixtures are stored as YAML in `fixtures/*.yaml` under the project
82
+ root.
83
+
84
+ For the YAML schema, see
85
+ [Configuration reference → Fixtures](../configuration.md#fixture-yaml).
86
+ For the concept, see [Concepts → Fixtures](../../concepts/configuration/fixtures.md).
87
+
88
+ ## Common tasks
89
+
90
+ - **Wire a new probe to a pin** — open `/fixtures/{id}/edit`, add a
91
+ connection row mapping pin → instrument-role + channel.
92
+ - **See where a fixture has been used** — the List view's Runs +
93
+ Passed + Failed columns + Last Run; the [Results list](results/list.md)
94
+ doesn't filter by fixture today, so use the Runs column here as
95
+ the quick scoreboard.
96
+
97
+ ## See also
98
+
99
+ - [Configuration reference → Fixtures](../configuration.md#fixture-yaml)
100
+ - [Concepts → Fixtures](../../concepts/configuration/fixtures.md)