@openmixer/plugin-qualify 0.17.5 → 0.18.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 (109) hide show
  1. package/README.md +127 -13
  2. package/bin/plugin-qualify-sync.mjs +3 -1
  3. package/dist/clap-qualify.d.ts +3 -1
  4. package/dist/clap-qualify.js +7 -1
  5. package/dist/clap-qualify.js.map +1 -1
  6. package/dist/direct-limit.d.ts +27 -0
  7. package/dist/direct-limit.js +52 -0
  8. package/dist/direct-limit.js.map +1 -0
  9. package/dist/distributed-records.d.ts +4 -2
  10. package/dist/distributed-records.js +1 -1
  11. package/dist/distributed-records.js.map +1 -1
  12. package/dist/host-admission.d.ts +12 -2
  13. package/dist/host-admission.js +24 -4
  14. package/dist/host-admission.js.map +1 -1
  15. package/dist/host-profiles.d.ts +8 -0
  16. package/dist/host-profiles.js +16 -1
  17. package/dist/host-profiles.js.map +1 -1
  18. package/dist/hosting-codes.generated.d.ts +10 -0
  19. package/dist/hosting-codes.generated.js +10 -0
  20. package/dist/hosting-codes.generated.js.map +1 -1
  21. package/dist/hosting-suitability.d.ts +34 -8
  22. package/dist/hosting-suitability.js +92 -7
  23. package/dist/hosting-suitability.js.map +1 -1
  24. package/dist/index.d.ts +3 -0
  25. package/dist/index.js +3 -0
  26. package/dist/index.js.map +1 -1
  27. package/dist/measurement/format.d.ts +54 -8
  28. package/dist/measurement/format.js +54 -3
  29. package/dist/measurement/format.js.map +1 -1
  30. package/dist/measurement/plan.d.ts +3 -3
  31. package/dist/measurement/plan.js +1 -1
  32. package/dist/measurement-grid.d.ts +8 -0
  33. package/dist/measurement-grid.js +4 -0
  34. package/dist/measurement-grid.js.map +1 -1
  35. package/dist/memory-bound.d.ts +6 -0
  36. package/dist/memory-bound.js +8 -0
  37. package/dist/memory-bound.js.map +1 -1
  38. package/dist/memory-budget.d.ts +39 -0
  39. package/dist/memory-budget.js +32 -0
  40. package/dist/memory-budget.js.map +1 -0
  41. package/dist/probe-judge.d.ts +11 -0
  42. package/dist/probe-judge.js +26 -10
  43. package/dist/probe-judge.js.map +1 -1
  44. package/dist/probe-merge.js +6 -5
  45. package/dist/probe-merge.js.map +1 -1
  46. package/dist/probe-output-fixtures.d.ts +6 -0
  47. package/dist/probe-output-fixtures.js +8 -0
  48. package/dist/probe-output-fixtures.js.map +1 -1
  49. package/dist/probe-output.d.ts +4 -2
  50. package/dist/probe-output.js +2 -1
  51. package/dist/probe-output.js.map +1 -1
  52. package/dist/probe-runner.js +7 -3
  53. package/dist/probe-runner.js.map +1 -1
  54. package/dist/qualification-record.d.ts +116 -10
  55. package/dist/qualification-record.js +34 -30
  56. package/dist/qualification-record.js.map +1 -1
  57. package/dist/qualify-adapter-pass.d.ts +67 -0
  58. package/dist/qualify-adapter-pass.js +255 -0
  59. package/dist/qualify-adapter-pass.js.map +1 -0
  60. package/dist/qualify-declarations.d.ts +53 -9
  61. package/dist/qualify-declarations.js +54 -2
  62. package/dist/qualify-declarations.js.map +1 -1
  63. package/dist/qualify-rejudge.d.ts +81 -0
  64. package/dist/qualify-rejudge.js +421 -0
  65. package/dist/qualify-rejudge.js.map +1 -0
  66. package/dist/qualify-sync.d.ts +72 -1
  67. package/dist/qualify-sync.js +194 -21
  68. package/dist/qualify-sync.js.map +1 -1
  69. package/fixtures/records-0.16.1/http___example.org_raffo@unversioned-2060c09ff626.default.probe.json +46 -0
  70. package/fixtures/records-0.16.1/http___example.org_raffo@unversioned-2060c09ff626.default.qualification.json +185 -0
  71. package/fixtures/records-0.16.1/http___lv2plug.in_plugins_eg-amp@unversioned-f046a60efd45.default.probe.json +51 -0
  72. package/fixtures/records-0.16.1/http___lv2plug.in_plugins_eg-amp@unversioned-f046a60efd45.default.qualification.json +232 -0
  73. package/fixtures/records-0.16.1/https___github.com_lucianodato_noise-repellent@unversioned-c3b5e21dd9a7.default.probe.json +51 -0
  74. package/fixtures/records-0.16.1/https___github.com_lucianodato_noise-repellent@unversioned-c3b5e21dd9a7.default.qualification.json +245 -0
  75. package/fixtures/records-0.16.1/in.lsp-plug.impulse_responses_mono@unversioned-d5235d2f5f53.custom.probe.json +52 -0
  76. package/fixtures/records-0.16.1/in.lsp-plug.impulse_responses_mono@unversioned-d5235d2f5f53.custom.qualification.json +145 -0
  77. package/fixtures/records-0.16.1/in.lsp-plug.trigger_midi_mono@unversioned-d5235d2f5f53.custom.probe.json +52 -0
  78. package/fixtures/records-0.16.1/in.lsp-plug.trigger_midi_mono@unversioned-d5235d2f5f53.custom.qualification.json +155 -0
  79. package/package.json +1 -1
  80. package/src/clap-qualify.ts +8 -1
  81. package/src/direct-limit.ts +68 -0
  82. package/src/distributed-records.ts +1 -1
  83. package/src/host-admission.ts +27 -4
  84. package/src/host-profiles.ts +17 -1
  85. package/src/hosting-codes.generated.ts +10 -0
  86. package/src/hosting-suitability.ts +105 -11
  87. package/src/index.ts +3 -0
  88. package/src/measurement/format.ts +97 -3
  89. package/src/measurement/plan.ts +3 -3
  90. package/src/measurement-grid.ts +5 -0
  91. package/src/memory-bound.ts +10 -0
  92. package/src/memory-budget.ts +55 -0
  93. package/src/probe-judge.ts +29 -9
  94. package/src/probe-merge.ts +6 -5
  95. package/src/probe-output-fixtures.ts +10 -1
  96. package/src/probe-output.ts +5 -2
  97. package/src/probe-runner.ts +5 -3
  98. package/src/qualification-record.ts +121 -18
  99. package/src/qualify-adapter-pass.ts +278 -0
  100. package/src/qualify-declarations.ts +67 -3
  101. package/src/qualify-rejudge.ts +452 -0
  102. package/src/qualify-sync.ts +210 -20
  103. package/tools/_declarations.py +1 -0
  104. package/tools/benchmark.py +25 -2
  105. package/tools/gen-python-declarations.mjs +1 -0
  106. package/tools/lv2-measure.mjs +7 -4
  107. package/tools/lv2_presets.py +1 -1
  108. package/tools/lv2_resolve.py +49 -0
  109. package/tools/mod-host-admit.mjs +23 -6
@@ -0,0 +1,421 @@
1
+ // SPDX-License-Identifier: GPL-3.0-or-later
2
+ // Copyright (C) 2026 Pau Aliagas <linuxnow@gmail.com>
3
+ /**
4
+ * Keeping a device's qualification records through an upgrade, instead of measuring every plugin again. An upgrade is a
5
+ * different host (`HOSTING_NOTE`): the figures are carried across and judged again, never trusted.
6
+ *
7
+ * `plugin-qualify-sync --rejudge` measures nothing. Each record's probe output goes through the one judge
8
+ * (`judgeProbeOutput`) under today's rules, with the host runs the record already holds, and the verdicts, the tiers and
9
+ * the plugin's pin word are replaced; the figures and their provenance are not touched, and the record says who took the
10
+ * figures and when. A verdict that needs a run the record lacks (an LV2 plugin's omx-clap-host verdict is decided by its
11
+ * adapter run) reads `unknown`, and the record owes that run: nothing is guessed, and a run that never happened gives a
12
+ * plugin no pin word. A record whose plugin's bytes changed, or whose probe output is not the one it names, is left as it
13
+ * is and owes a qualification. A second run changes nothing.
14
+ *
15
+ * `plugin-qualify-sync --memory-only` takes one figure: the footprint of each recorded plugin at the cells a Pi runs,
16
+ * through the probe runner, under the limits of an ordinary run, in a world of its bundle only. Only the `memory` of those
17
+ * cells changes in the record. It judges nothing: a `--rejudge` afterwards reads the footprints. Growth over time needs a
18
+ * soak, which this does not run: the record says so in `notMeasured`.
19
+ */
20
+ import { mkdtempSync, readFileSync, readdirSync, rmSync, symlinkSync } from "node:fs";
21
+ import { tmpdir } from "node:os";
22
+ import { basename, dirname, join } from "node:path";
23
+ import { outcomeOfVerdict } from "./distributed-records.js";
24
+ import { ADAPTER_RUN_HOSTS, ADMITTED_HOSTS } from "./host-admission.js";
25
+ import { OMX_CLAP_HOST_CONFIGURED_EXTENSIONS, shippedHostProfile } from "./host-profiles.js";
26
+ import { HOSTING_CODE } from "./hosting-codes.js";
27
+ import { readMemoryFootprint } from "./measurement/format.js";
28
+ import { cellKey } from "./measurement-grid.js";
29
+ import { pinVerdictOf } from "./pins-file.js";
30
+ import { failedOutcome, judgeProbeOutput } from "./probe-judge.js";
31
+ import { PROBE_OK, readProbeOutput, sha256Hex } from "./probe-output.js";
32
+ import { probeTarget, ProbeRunnerError } from "./probe-runner.js";
33
+ import { proberOffer } from "./clap-qualify.js";
34
+ import { IN_PROCESS_TIER_HOST, ISOLATED_TIER_HOST, QUALIFICATION_RECORD_SCHEMA, memoryOfCell, tiersOf, unmeasuredWordOf, verdictRows, } from "./qualification-record.js";
35
+ import { PI_CELLS, PROBE_MEMORY_ONLY_ENV, PROBE_NOTES_ENV } from "./qualify-declarations.js";
36
+ import { SYNC_STATE_SCHEMA, digestFiles, recordStem } from "./qualify-sync.js";
37
+ import { writeFileWhole } from "./whole-file.js";
38
+ /** The codes of a measurement a record owes. */
39
+ export const OWED_CODE = {
40
+ /** An LV2 verdict of a host that runs it through the adapter, and no measured adapter run. */
41
+ adapterRun: "qualify.sync.adapter-run-owed",
42
+ /** A verdict decided by a run under its host (mod-host, jalv), and no run in the record. */
43
+ hostRun: "qualify.sync.host-run-owed",
44
+ /** The plugin's files are not the bytes the record measured. */
45
+ bytesChanged: "qualify.sync.bytes-changed",
46
+ /** The probe output is missing, is not the copy the record names, or does not read. */
47
+ figuresUnreadable: "qualify.sync.figures-unreadable",
48
+ /** The plugin has a record that holds no figures at all. */
49
+ noFigures: "qualify.sync.no-figures",
50
+ };
51
+ /** The cells the memory-only pass measures: the ones a Pi runs, 48 kHz at 128 and 256 frames. */
52
+ export const MEMORY_PASS_CELLS = PI_CELLS;
53
+ /** What a memory-only pass cannot say, in every record it writes to: growth over time needs a soak. */
54
+ export const MEMORY_PASS_NOT_MEASURED = { dimension: "memoryGrowth", code: HOSTING_CODE.stabilityUnsoaked };
55
+ const RECORD_SUFFIX = ".qualification.json";
56
+ /** The tool as the record says it: this package's own version, read where it is installed. */
57
+ export function rejudgeToolName() {
58
+ try {
59
+ const pkg = JSON.parse(readFileSync(new URL("../package.json", import.meta.url), "utf8"));
60
+ return `plugin-qualify ${pkg.version ?? "unknown"}`;
61
+ }
62
+ catch {
63
+ return "plugin-qualify unknown";
64
+ }
65
+ }
66
+ /** A world holding one bundle, as plugin-hostd runs a pinned LV2 plugin, for as long as `body` runs. */
67
+ export function lv2World(bundle, body) {
68
+ const world = mkdtempSync(join(tmpdir(), "plugin-qualify-sync-world-"));
69
+ try {
70
+ symlinkSync(bundle, join(world, basename(bundle)));
71
+ return body(world);
72
+ }
73
+ finally {
74
+ rmSync(world, { recursive: true, force: true });
75
+ }
76
+ }
77
+ // --- the judgment of one record ---------------------------------------------------------------------------------------
78
+ /** The probe output with the footprints a memory-only pass merged into the record: the probe copy itself stays as it was taken. */
79
+ function withMemoryRun(output, record) {
80
+ const merged = record.memoryRun;
81
+ if (merged === undefined)
82
+ return output;
83
+ const grid = [...output.grid];
84
+ for (const c of merged.cells) {
85
+ const point = record.measurements.grid.find((p) => p.rate === c.rate && p.quantum === c.quantum);
86
+ const memory = readMemoryFootprint(point?.memory);
87
+ if (memory === undefined)
88
+ continue;
89
+ const at = grid.findIndex((p) => p.rate === c.rate && p.quantum === c.quantum);
90
+ if (at >= 0)
91
+ grid[at] = { ...grid[at], memory };
92
+ else
93
+ grid.push({ rate: c.rate, quantum: c.quantum, outcome: PROBE_OK, memory });
94
+ }
95
+ return { ...output, grid };
96
+ }
97
+ /** The offer a profile is judged under for a CLAP plugin; `undefined` for a host the prober cannot stand in for. */
98
+ const offerIdOf = (profile) => {
99
+ const offer = proberOffer(profile);
100
+ return offer === undefined ? undefined : offer.length > 0 ? "custom" : "default";
101
+ };
102
+ /**
103
+ * The profiles a record is judged under: the hosts it has verdicts for, the console's two tiers, the host of this run, and
104
+ * the Pi boards, whose budgets read the footprints. A host only joins a CLAP plugin's record of its own offer.
105
+ */
106
+ function rejudgeProfiles(record, output, host) {
107
+ const format = output.plugin.format;
108
+ const added = [IN_PROCESS_TIER_HOST, ISOLATED_TIER_HOST[format], host, ...ADAPTER_RUN_HOSTS].filter((id) => id !== undefined);
109
+ const profiles = new Map();
110
+ const kept = [];
111
+ for (const v of record.verdicts) {
112
+ const p = shippedHostProfile(v.host);
113
+ if (p === undefined)
114
+ kept.push(v);
115
+ else
116
+ profiles.set(p.id, p);
117
+ }
118
+ for (const id of added) {
119
+ const p = shippedHostProfile(id);
120
+ if (p === undefined || profiles.has(id))
121
+ continue;
122
+ if (format === "lv2" || offerIdOf(p) === output.offer.id)
123
+ profiles.set(id, p);
124
+ }
125
+ return { profiles: [...profiles.values()], kept };
126
+ }
127
+ /** The runs the record holds, as the judge takes them: its adapter run, and each `run` verdict of a host that is decided by one. */
128
+ function admissionsOf(record) {
129
+ const out = {};
130
+ for (const v of record.verdicts) {
131
+ const host = ADMITTED_HOSTS.find((h) => h === v.host);
132
+ if (host === undefined || v.arm !== "run")
133
+ continue;
134
+ const r = v.reasons.find((x) => x.dimension === "hostAdmission");
135
+ out[host] = r === undefined ? { host, measured: true, admitted: true, params: {} } : { host, measured: r.rating !== "unknown", admitted: false, code: r.code, params: r.params };
136
+ }
137
+ const a = record.adapter;
138
+ if (a?.measured === true) {
139
+ const run = { host: "omx-clap-host", measured: true, admitted: a.admitted, ...(a.code === undefined ? {} : { code: a.code }), params: a.params };
140
+ for (const id of ADAPTER_RUN_HOSTS)
141
+ out[id] = run;
142
+ }
143
+ return out;
144
+ }
145
+ const owedReason = (code, params) => ({ dimension: "hostAdmission", rating: "unknown", code, params });
146
+ /** The runs the verdicts of these profiles need and the record does not hold. A run that did not end well decides nothing, so it owes none. */
147
+ function runsOwed(record, output, profiles) {
148
+ const reasons = {};
149
+ const owes = [];
150
+ if (failedOutcome(output) !== undefined)
151
+ return { reasons, owes };
152
+ if (output.plugin.format === "lv2" && record.adapter?.measured !== true) {
153
+ const why = record.adapter?.code;
154
+ const params = why === undefined ? {} : { lastRun: why };
155
+ for (const p of profiles)
156
+ if (ADAPTER_RUN_HOSTS.includes(p.id))
157
+ reasons[p.id] = owedReason(OWED_CODE.adapterRun, params);
158
+ owes.push({ measurement: "adapter-run", host: "omx-clap-host", code: OWED_CODE.adapterRun, ...(why === undefined ? {} : { detail: why }) });
159
+ }
160
+ for (const v of record.verdicts) {
161
+ if (!ADMITTED_HOSTS.some((h) => h === v.host) || v.arm === "run")
162
+ continue;
163
+ reasons[v.host] = owedReason(OWED_CODE.hostRun, { host: v.host });
164
+ owes.push({ measurement: "host-run", host: v.host, code: OWED_CODE.hostRun });
165
+ }
166
+ return { reasons, owes };
167
+ }
168
+ export class RejudgeRefusal extends Error {
169
+ }
170
+ /**
171
+ * One record judged again from its probe output, with what it owes. The figures, who took them and when are as they were;
172
+ * only the verdicts, the tiers and the cost reasons beside them are new. `at` is the prior re-judge's when nothing else
173
+ * differs, so that a second run leaves the file alone.
174
+ */
175
+ export function rejudgeRecord(record, probeBytes, options) {
176
+ if (sha256Hex(probeBytes) !== record.probe.sha256)
177
+ throw new RejudgeRefusal(`${record.probe.file} is not the probe output the record names (its SHA-256 differs)`);
178
+ const read = readProbeOutput(Buffer.from(probeBytes).toString("utf8"));
179
+ if (!read.ok)
180
+ throw new RejudgeRefusal(`${record.probe.file}: ${read.code}: ${read.problem}`);
181
+ const output = withMemoryRun(read.output, record);
182
+ const { profiles, kept } = rejudgeProfiles(record, output, options.host);
183
+ const { reasons, owes } = runsOwed(record, output, profiles);
184
+ const judgment = judgeProbeOutput(output, profiles, { admissions: admissionsOf(record), owed: reasons });
185
+ const memory = record.memoryRun === undefined ? {} : { memory: { tool: record.memoryRun.tool, measuredAt: record.memoryRun.measuredAt } };
186
+ const a = record.adapter;
187
+ const adapterTaken = a?.versions === undefined || a.measuredAt === undefined ? {} : { adapter: { versions: a.versions, measuredAt: a.measuredAt } };
188
+ const { rejudged: prior, ...rest } = record;
189
+ const next = (at) => ({
190
+ ...rest,
191
+ verdicts: [...verdictRows(judgment), ...kept],
192
+ tiers: tiersOf(judgment),
193
+ cost: judgment.hosts.map((h) => ({ host: h.verdict.host, ...h.cost })),
194
+ rejudged: {
195
+ at,
196
+ by: options.by,
197
+ figures: { tool: record.tool, measuredAt: record.measuredAt, runId: read.output.run.id, ...memory, ...adapterTaken },
198
+ ...(owes.length === 0 ? {} : { owes }),
199
+ },
200
+ });
201
+ const same = prior !== undefined && JSON.stringify(next(prior.at)) === JSON.stringify(record);
202
+ return { record: same ? record : next(options.at), owes };
203
+ }
204
+ // --- a device's records -----------------------------------------------------------------------------------------------
205
+ /** The file that lists what a re-judge left owing, beside the state file. */
206
+ export const owedFile = (stateFile) => join(dirname(stateFile), "qualify-owed.json");
207
+ export const OWED_SCHEMA = "plugin-qualify.owed/1";
208
+ /** The entries whose files are not the bytes they were qualified from, and their records' stems. */
209
+ function changedStems(state) {
210
+ const stems = new Set();
211
+ const entries = new Set();
212
+ for (const [key, e] of Object.entries(state.entries)) {
213
+ const now = digestFiles(e.root, e.files.map((f) => f.path), e.files);
214
+ if (now !== undefined && now.every((f) => e.files.some((x) => x.path === f.path && x.sha256 === f.sha256)))
215
+ continue;
216
+ entries.add(key);
217
+ for (const p of e.plugins) {
218
+ const stem = p.record === undefined ? undefined : recordStem(p.record);
219
+ if (stem !== undefined)
220
+ stems.add(stem);
221
+ }
222
+ }
223
+ return { stems, entries };
224
+ }
225
+ const readRecord = (path) => {
226
+ try {
227
+ const r = JSON.parse(readFileSync(path, "utf8"));
228
+ return r.schema === QUALIFICATION_RECORD_SCHEMA ? r : undefined;
229
+ }
230
+ catch {
231
+ return undefined;
232
+ }
233
+ };
234
+ const nameOf = (record) => record.plugin.id;
235
+ /** A state plugin with the verdict its record now holds for the host: the pin's files stay as they are, only its word follows. */
236
+ function pluginWithVerdict(plugin, v) {
237
+ const { pin, code: _code, ...rest } = plugin;
238
+ const word = v.measured ? pinVerdictOf(v.rating) : undefined;
239
+ return {
240
+ ...rest,
241
+ outcome: outcomeOfVerdict(v),
242
+ ...(v.deciding === undefined ? {} : { code: v.deciding }),
243
+ ...(pin === undefined ? {} : { pin: { uri: pin.uri, integrity: pin.integrity, ...(word === undefined ? {} : { verdict: word }) } }),
244
+ };
245
+ }
246
+ /**
247
+ * Every record of the device's qualification directory judged again, the state's outcomes and pin words brought into line,
248
+ * and the list of what is owed written beside the state file. Each file is written whole, and only when it differs.
249
+ */
250
+ export function rejudgeState(ctx, state, now = () => new Date().toISOString()) {
251
+ const { qualificationDir: dir, hostProfile, stateFile } = ctx.settings;
252
+ const by = rejudgeToolName();
253
+ const at = now();
254
+ const changed = changedStems(state);
255
+ const judged = new Map();
256
+ const owing = [];
257
+ let changedCount = 0;
258
+ let unchanged = 0;
259
+ let names = [];
260
+ try {
261
+ names = readdirSync(dir).filter((f) => f.endsWith(RECORD_SUFFIX)).sort();
262
+ }
263
+ catch {
264
+ // no directory, no record
265
+ }
266
+ for (const name of names) {
267
+ const path = join(dir, name);
268
+ const record = readRecord(path);
269
+ if (record === undefined) {
270
+ ctx.log(`${name}: does not read as a record; left as it is`);
271
+ owing.push({ plugin: name, record: name, owes: [{ measurement: "qualification", code: OWED_CODE.figuresUnreadable }] });
272
+ continue;
273
+ }
274
+ if (changed.stems.has(recordStem(name) ?? "")) {
275
+ owing.push({ plugin: nameOf(record), record: name, owes: [{ measurement: "qualification", code: OWED_CODE.bytesChanged }] });
276
+ continue;
277
+ }
278
+ let result;
279
+ try {
280
+ result = rejudgeRecord(record, readFileSync(join(dir, record.probe.file)), { host: hostProfile.id, by, at });
281
+ }
282
+ catch (e) {
283
+ const detail = e instanceof RejudgeRefusal ? e.message : `${record.probe.file}: ${e.code ?? String(e)}`;
284
+ ctx.log(`${name}: ${detail}; left as it is`);
285
+ owing.push({ plugin: nameOf(record), record: name, owes: [{ measurement: "qualification", code: OWED_CODE.figuresUnreadable, detail }] });
286
+ continue;
287
+ }
288
+ if (result.record === record)
289
+ unchanged++;
290
+ else {
291
+ writeFileWhole(path, `${JSON.stringify(result.record, null, 2)}\n`);
292
+ changedCount++;
293
+ }
294
+ judged.set(name, result.record);
295
+ if (result.owes.length > 0)
296
+ owing.push({ plugin: nameOf(record), record: name, owes: result.owes });
297
+ }
298
+ const entries = {};
299
+ for (const [key, entry] of Object.entries(state.entries)) {
300
+ if (changed.entries.has(key)) {
301
+ entries[key] = entry;
302
+ continue;
303
+ }
304
+ const plugins = entry.plugins.map((plugin) => {
305
+ const record = plugin.record === undefined ? undefined : judged.get(basename(plugin.record));
306
+ const v = record?.verdicts.find((x) => x.host === hostProfile.id);
307
+ if (v !== undefined)
308
+ return pluginWithVerdict(plugin, v);
309
+ if (record === undefined && plugin.outcome === "unmeasured" && plugin.record?.endsWith(RECORD_SUFFIX) !== true) {
310
+ owing.push({ plugin: plugin.uri, ...(plugin.record === undefined ? {} : { record: basename(plugin.record) }), owes: [{ measurement: "qualification", code: OWED_CODE.noFigures }] });
311
+ }
312
+ return plugin;
313
+ });
314
+ entries[key] = { ...entry, plugins };
315
+ }
316
+ owing.sort((a, b) => (a.record ?? a.plugin).localeCompare(b.record ?? b.plugin));
317
+ for (const o of owing)
318
+ ctx.log(`owes: ${o.plugin}: ${o.owes.map((x) => `${x.measurement}${x.host === undefined ? "" : ` under ${x.host}`}`).join(", ")}`);
319
+ writeIfDifferent(owedFile(stateFile), `${JSON.stringify({ schema: OWED_SCHEMA, owing }, null, 1)}\n`);
320
+ return { state: { schema: SYNC_STATE_SCHEMA, entries }, changed: changedCount, unchanged, owing };
321
+ }
322
+ function writeIfDifferent(path, text) {
323
+ try {
324
+ if (readFileSync(path, "utf8") === text)
325
+ return;
326
+ }
327
+ catch {
328
+ // not there yet
329
+ }
330
+ writeFileWhole(path, text);
331
+ }
332
+ // --- the memory-only pass ---------------------------------------------------------------------------------------------
333
+ /**
334
+ * A memory-only run's footprints in a record: the `memory` of each cell and nothing else of it, a cell the record's grid
335
+ * does not hold joined with no other figure. A cell the run could not read says why instead of a figure, so that it is
336
+ * never read as fitting. Pure.
337
+ */
338
+ export function mergeMemoryRun(record, output, cells) {
339
+ const grid = [...record.measurements.grid];
340
+ const said = [];
341
+ for (const c of cells) {
342
+ const p = output.grid.find((g) => cellKey(g) === cellKey(c));
343
+ const outcome = p?.outcome ?? output.run.outcome;
344
+ const memory = p?.memory ?? { unmeasuredReason: unmeasuredWordOf(outcome), unmeasuredDetail: `the memory-only run ended ${outcome}` };
345
+ const figures = memoryOfCell({ rate: c.rate, quantum: c.quantum, outcome, memory });
346
+ const at = grid.findIndex((g) => cellKey(g) === cellKey(c));
347
+ if (at >= 0)
348
+ grid[at] = { ...grid[at], ...figures };
349
+ else
350
+ grid.push({ rate: c.rate, quantum: c.quantum, outcome: PROBE_OK, latency: { unmeasuredReason: "not-attempted", code: HOSTING_CODE.latencyUnmeasured }, ...figures });
351
+ said.push({ rate: c.rate, quantum: c.quantum, outcome, ...(p?.memoryLimit === undefined ? {} : { memoryLimit: p.memoryLimit }) });
352
+ }
353
+ const notMeasured = record.notMeasured ?? [];
354
+ return {
355
+ ...record,
356
+ measurements: { ...record.measurements, grid },
357
+ notMeasured: notMeasured.some((n) => n.dimension === MEMORY_PASS_NOT_MEASURED.dimension) ? notMeasured : [...notMeasured, MEMORY_PASS_NOT_MEASURED],
358
+ memoryRun: { tool: output.run.tools, measuredAt: output.run.startedAt, runId: output.run.id, cells: said },
359
+ };
360
+ }
361
+ /** Whether a record already holds this pass's footprints. */
362
+ const memoryTaken = (record, cells) => record.memoryRun !== undefined && cells.every((c) => record.memoryRun.cells.some((m) => cellKey(m) === cellKey(c)));
363
+ /** The extensions a record was measured with: its file says which offer it is. */
364
+ const offerOf = (recordName) => (recordName.endsWith(`.custom${RECORD_SUFFIX}`) ? OMX_CLAP_HOST_CONFIGURED_EXTENSIONS : []);
365
+ /**
366
+ * The footprint of each plugin of the state, at `MEMORY_PASS_CELLS`, merged into the record its verdict for this run's host
367
+ * came from. One plugin's failure is that plugin's; each record is written whole as its plugin ends, so a pass cut short
368
+ * keeps what it finished, and a pass run again skips those unless `force`.
369
+ */
370
+ export function memoryPass(ctx, state, options = {}) {
371
+ const { memory, budgetS, memoryNotes } = ctx.settings;
372
+ const count = { measured: 0, already: 0, failed: 0 };
373
+ const changed = changedStems(state);
374
+ for (const [key, entry] of Object.entries(state.entries)) {
375
+ if (changed.entries.has(key)) {
376
+ ctx.log(`${key}: its files changed since it was measured; the sync measures it whole`);
377
+ continue;
378
+ }
379
+ for (const plugin of entry.plugins) {
380
+ if (plugin.record === undefined || !plugin.record.endsWith(RECORD_SUFFIX))
381
+ continue;
382
+ const name = basename(plugin.record);
383
+ const path = join(ctx.settings.qualificationDir, name);
384
+ const record = readRecord(path);
385
+ if (record === undefined) {
386
+ ctx.log(`${plugin.uri}: its record ${name} does not read; no footprint taken`);
387
+ count.failed++;
388
+ continue;
389
+ }
390
+ if (options.force !== true && memoryTaken(record, MEMORY_PASS_CELLS)) {
391
+ count.already++;
392
+ continue;
393
+ }
394
+ const started = Date.now();
395
+ const env = { ...ctx.env, [PROBE_MEMORY_ONLY_ENV]: "1", [PROBE_NOTES_ENV]: String(memoryNotes) };
396
+ const limits = { rates: [...new Set(MEMORY_PASS_CELLS.map((c) => c.rate))], cells: MEMORY_PASS_CELLS, wallS: budgetS, ...(memory === undefined ? {} : { memory }), ...(options.run === undefined ? {} : { run: options.run }) };
397
+ try {
398
+ const probed = entry.format === "clap"
399
+ ? probeTarget(clapTarget(key, entry, record), { ...limits, offer: offerOf(name), env })
400
+ : lv2World(entry.root, (world) => probeTarget({ format: "lv2", uri: record.plugin.id, bundle: entry.root }, { ...limits, env: { ...env, LV2_PATH: world } }));
401
+ if (probed.output.binary.sha256 !== record.binary.sha256)
402
+ throw new ProbeRunnerError(`measured binary ${probed.output.binary.sha256.slice(0, 12)}, the record's is ${record.binary.sha256.slice(0, 12)}`);
403
+ writeFileWhole(path, `${JSON.stringify(mergeMemoryRun(record, probed.output, MEMORY_PASS_CELLS), null, 2)}\n`);
404
+ count.measured++;
405
+ ctx.log(`${plugin.uri}: footprint taken at ${MEMORY_PASS_CELLS.map(cellKey).join(", ")} in ${((Date.now() - started) / 1000).toFixed(1)} s`);
406
+ }
407
+ catch (e) {
408
+ if (!(e instanceof ProbeRunnerError))
409
+ throw e;
410
+ count.failed++;
411
+ ctx.log(`${plugin.uri}: no footprint: ${e.message}`);
412
+ }
413
+ }
414
+ }
415
+ return count;
416
+ }
417
+ function clapTarget(key, entry, record) {
418
+ const file = key.startsWith("clap:") ? key.slice("clap:".length) : join(entry.root, record.binary.files[0]?.path ?? "");
419
+ return { format: "clap", uri: `urn:clap:${record.plugin.id}`, bundle: entry.root, binary: basename(file), binaryPath: file };
420
+ }
421
+ //# sourceMappingURL=qualify-rejudge.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"qualify-rejudge.js","sourceRoot":"","sources":["../src/qualify-rejudge.ts"],"names":[],"mappings":"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"}
@@ -1,7 +1,9 @@
1
1
  import { type HostProfile } from "./host-profiles.js";
2
2
  import { type PinEntry } from "./pins-file.js";
3
3
  import { type PinFilesRun } from "./hostd-pin-files.js";
4
+ import { type ProbeRun } from "./probe-runner.js";
4
5
  import { type GridSpec } from "./measurement-grid.js";
6
+ import { type AdapterPassOptions } from "./qualify-adapter-pass.js";
5
7
  import { type MemoryBound } from "./memory-bound.js";
6
8
  import { type NotMeasured } from "./qualification-record.js";
7
9
  /** The settings file a system service reads, `key value` per line. */
@@ -32,6 +34,8 @@ export interface SyncSettings {
32
34
  readonly cellsPerPluginBudget: number;
33
35
  /** The memory bound of every run; `undefined` is `off`. */
34
36
  readonly memory?: MemoryBound;
37
+ /** The notes an instrument with no declared capacity holds in a memory-only run. */
38
+ readonly memoryNotes: number;
35
39
  readonly hostdPort: number;
36
40
  readonly hostdFeedbackPort: number;
37
41
  readonly settleS: number;
@@ -57,6 +61,12 @@ export interface SyncArgs {
57
61
  readonly noWait: boolean;
58
62
  /** `--refresh-pins`: refresh the pins' files from plugin-hostd and measure nothing (the package's upgrade runs it). */
59
63
  readonly refreshPins: boolean;
64
+ /** `--rejudge`: the verdicts, tiers and pins derived again from the records' figures, measuring nothing. */
65
+ readonly rejudge: boolean;
66
+ /** `--memory-only`: the footprint of each recorded plugin at the Pi's cells, merged into its record. */
67
+ readonly memoryOnly: boolean;
68
+ /** `--adapter-only`: the run of each LV2 plugin under the adapter at the Pi's cells, merged into its record. */
69
+ readonly adapterOnly: boolean;
60
70
  readonly help: boolean;
61
71
  /** The settings given as flags, by key. */
62
72
  readonly values: ReadonlyMap<string, string>;
@@ -89,15 +99,30 @@ export interface SyncItem {
89
99
  readonly files: readonly string[];
90
100
  /** The LV2 plugin's uri. */
91
101
  readonly uri?: string;
102
+ /** The LV2 plugin's binary as lilv loads it, an absolute path that may lie outside `root` (a complement's). */
103
+ readonly binary?: string;
92
104
  }
105
+ /** One LV2 plugin as lilv resolves it over the whole search path: the bundle its version rule takes, and its binary. */
106
+ export interface Lv2Resolved {
107
+ readonly uri: string;
108
+ readonly bundle: string;
109
+ readonly binary?: string | null;
110
+ }
111
+ /** The bundles lilv takes over `dirs`, or why it could not say. A stand-in in tests. */
112
+ export type Lv2Resolve = (dirs: readonly string[]) => readonly Lv2Resolved[] | {
113
+ readonly problem: string;
114
+ };
115
+ /** lilv itself, one world over the whole search path (tools/lv2_resolve.py), as every host built on it resolves (#199). */
116
+ export declare const LILV_RESOLVE: Lv2Resolve;
93
117
  /**
94
118
  * Every item on the search paths. A `.clap` is one item; an LV2 plugin is one item, found in the first bundle on the
95
119
  * LV2 directories that declares it, as plugin-hostd finds it. A directory that cannot be read is a problem named, and
96
120
  * the others are still walked.
97
121
  */
98
- export declare function discoverSyncItems(settings: Pick<SyncSettings, "lv2Dirs" | "clapDirs">): {
122
+ export declare function discoverSyncItems(settings: Pick<SyncSettings, "lv2Dirs" | "clapDirs">, lv2Resolve?: Lv2Resolve): {
99
123
  items: SyncItem[];
100
124
  problems: string[];
125
+ notes: string[];
101
126
  };
102
127
  /** One file of a set: its SHA-256, as plugin-hostd's `pin.h` digests it, and the stat it was taken at. */
103
128
  export interface FileDigest {
@@ -130,6 +155,13 @@ export declare const SYNC_CODE: {
130
155
  /** The probe runner wrote no document to judge. */
131
156
  readonly notMeasured: "qualify.sync.not-measured";
132
157
  };
158
+ /**
159
+ * Why a plugin is unmeasured because of the machine it ran on rather than what it is (#192): an EACCES, EPERM or
160
+ * ENOSPC the run hit, or a measurement that could not run or wrote no document. Such a plugin is measured again by
161
+ * the next run although its files are unchanged; a reason of the plugin's own (probe.limit.not-implemented, no such
162
+ * plugin, a crash) is not. `undefined` for every other outcome.
163
+ */
164
+ export declare function machineReason(p: Pick<SyncPlugin, "outcome" | "code" | "detail">): string | undefined;
133
165
  /** What the quick qualification never measures, stated in every record it writes. */
134
166
  export declare const QUICK_NOT_MEASURED: readonly NotMeasured[];
135
167
  export interface SyncPlugin {
@@ -168,6 +200,13 @@ export declare function recordedAsIs(item: SyncItem, entry: SyncEntry | undefine
168
200
  same: boolean;
169
201
  files?: FileDigest[];
170
202
  };
203
+ /**
204
+ * The entry of an LV2 plugin a host now loads from another bundle than it was qualified in, when its binary is the
205
+ * same bytes (#199): the entry with the new bundle and the new bundle's file digests, its verdicts and records kept.
206
+ * `undefined` when the item is not that case: not LV2, no entry, the same bundle, a binary that cannot be read, or one
207
+ * whose bytes differ from the recorded binary's (then it is measured again).
208
+ */
209
+ export declare function sameBinaryElsewhere(item: SyncItem, entry: SyncEntry | undefined): SyncEntry | undefined;
171
210
  export interface SyncContext {
172
211
  readonly settings: SyncSettings;
173
212
  readonly env: Readonly<Record<string, string | undefined>>;
@@ -241,6 +280,26 @@ export interface SyncSummary {
241
280
  readonly sent?: number;
242
281
  /** The pins whose files were refreshed from plugin-hostd without a measurement (plugin-qualify#239). */
243
282
  readonly refreshed?: number;
283
+ /** `--rejudge`: the records whose verdicts changed, the ones that stood, and the ones that owe a measurement. */
284
+ readonly rejudge?: {
285
+ readonly changed: number;
286
+ readonly unchanged: number;
287
+ readonly owing: number;
288
+ };
289
+ /** `--memory-only`: the plugins measured, those whose footprints were already merged, and those no run could read. */
290
+ readonly memoryOnly?: {
291
+ readonly measured: number;
292
+ readonly already: number;
293
+ readonly failed: number;
294
+ };
295
+ /** Every plugin the run measured was unmeasured for this one reason of the machine ({@link machineReason}): the run failed. */
296
+ readonly machineFailure?: string;
297
+ /** `--adapter-only`: the plugins run, those done already at these host versions, and those whose host could not be run. */
298
+ readonly adapterOnly?: {
299
+ readonly measured: number;
300
+ readonly already: number;
301
+ readonly failed: number;
302
+ };
244
303
  }
245
304
  /**
246
305
  * Why a reader that is not the sync's user (the console, #221) cannot read the descriptors: the directory or one of its
@@ -263,8 +322,20 @@ export interface SyncRunOptions {
263
322
  readonly force?: boolean;
264
323
  /** `--refresh-pins`: only refresh the pins' files from plugin-hostd and send the changed ones; measure nothing. */
265
324
  readonly refreshOnly?: boolean;
325
+ /** `--rejudge`: derive the verdicts again from the records' figures; measure nothing. */
326
+ readonly rejudge?: boolean;
327
+ /** `--memory-only`: take only the footprints; `force` takes those already merged again. */
328
+ readonly memoryOnly?: boolean;
329
+ /** `--adapter-only`: take only the adapter runs; `force` takes those already done again. */
330
+ readonly adapterOnly?: boolean;
331
+ /** Stand-ins for the pass's hosts, in tests. */
332
+ readonly adapterPass?: AdapterPassOptions;
266
333
  /** The run of `plugin-hostd --pin-files`, a stand-in in tests. */
267
334
  readonly pinFilesRun?: PinFilesRun;
335
+ /** The run of the probe runner in a memory-only pass, a stand-in in tests. */
336
+ readonly probeRun?: ProbeRun;
337
+ /** How LV2 plugins are resolved to the bundle a host loads: lilv itself unless a test stands in (#199). */
338
+ readonly lv2Resolve?: Lv2Resolve;
268
339
  /** False under `--no-wait`: a run in progress is not waited for; the holder runs once more at its end instead. */
269
340
  readonly wait?: boolean;
270
341
  readonly env?: Readonly<Record<string, string | undefined>>;