@aura3d/cli 1.4.5 → 1.5.0
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.
- package/dist/asset-intent.d.ts +148 -0
- package/dist/asset-intent.d.ts.map +1 -0
- package/dist/asset-intent.js +145 -0
- package/dist/asset-intent.js.map +1 -0
- package/dist/asset-role-admission.d.ts +174 -0
- package/dist/asset-role-admission.d.ts.map +1 -0
- package/dist/asset-role-admission.js +381 -0
- package/dist/asset-role-admission.js.map +1 -0
- package/dist/asset-screening-effects.d.ts +95 -0
- package/dist/asset-screening-effects.d.ts.map +1 -0
- package/dist/asset-screening-effects.js +321 -0
- package/dist/asset-screening-effects.js.map +1 -0
- package/dist/asset-screening-pipeline.d.ts +132 -0
- package/dist/asset-screening-pipeline.d.ts.map +1 -0
- package/dist/asset-screening-pipeline.js +277 -0
- package/dist/asset-screening-pipeline.js.map +1 -0
- package/dist/cartoon-asset-profiles.d.ts +15 -0
- package/dist/cartoon-asset-profiles.d.ts.map +1 -0
- package/dist/cartoon-asset-profiles.js +46 -0
- package/dist/cartoon-asset-profiles.js.map +1 -0
- package/dist/cli-help.js +1 -1
- package/dist/cli.js +16 -2
- package/dist/cli.js.map +1 -1
- package/dist/index.d.ts +8 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +390 -17
- package/dist/index.js.map +1 -1
- package/dist/pull-bridge/search.d.ts +4 -0
- package/dist/pull-bridge/search.d.ts.map +1 -1
- package/dist/pull-bridge/search.js +22 -0
- package/dist/pull-bridge/search.js.map +1 -1
- package/dist/pull-bridge.d.ts +20 -5
- package/dist/pull-bridge.d.ts.map +1 -1
- package/dist/pull-bridge.js +38 -1
- package/dist/pull-bridge.js.map +1 -1
- package/package.json +3 -3
|
@@ -0,0 +1,321 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Real bindings for the screening pipeline's injected effects.
|
|
3
|
+
*
|
|
4
|
+
* ## Why this file exists separately from the pipeline
|
|
5
|
+
*
|
|
6
|
+
* `asset-screening-pipeline.ts` owns *ordering and record-keeping* and takes every external effect as an
|
|
7
|
+
* injected function. That separation is what makes the part that historically failed -- running the steps
|
|
8
|
+
* in order and keeping every rejection reason -- testable offline. But an orchestrator with no real
|
|
9
|
+
* bindings is a library nobody can run: the previous state of this work had 38 passing tests against
|
|
10
|
+
* injected fakes and no way to actually screen a candidate.
|
|
11
|
+
*
|
|
12
|
+
* This module supplies the production wiring: catalog search, download, and structural geometry
|
|
13
|
+
* inspection read from the pulled file. It deliberately does **not** supply a render probe by default.
|
|
14
|
+
*
|
|
15
|
+
* ## Why no default render probe
|
|
16
|
+
*
|
|
17
|
+
* Rendering requires a browser (Playwright) and a dev server. Importing that here would make the CLI
|
|
18
|
+
* package depend on the test harness, and worse, it would tempt a caller into fabricating a "rendered"
|
|
19
|
+
* verdict from geometry when no browser is present. Omitting `renderProbe` means admission reports
|
|
20
|
+
* rendered visibility as `unproven` rather than passing -- the honest outcome, and the one the whole
|
|
21
|
+
* investigation was about. A caller with a working harness injects it explicitly.
|
|
22
|
+
*/
|
|
23
|
+
import { createHash } from "node:crypto";
|
|
24
|
+
import { existsSync, mkdirSync, mkdtempSync, readFileSync, statSync } from "node:fs";
|
|
25
|
+
import { tmpdir } from "node:os";
|
|
26
|
+
import { join, resolve } from "node:path";
|
|
27
|
+
import { defaultDownloadFile, runSearch } from "./pull-bridge.js";
|
|
28
|
+
/**
|
|
29
|
+
* Build production screening effects.
|
|
30
|
+
*
|
|
31
|
+
* Search failures propagate as thrown errors so the pipeline records them per query rather than treating
|
|
32
|
+
* an outage as "no candidates exist" -- a distinction that cost a whole pass when I concluded the catalog
|
|
33
|
+
* was empty without having searched it.
|
|
34
|
+
*/
|
|
35
|
+
export function createScreeningEffects(options = {}) {
|
|
36
|
+
const staging = options.stagingDir
|
|
37
|
+
? (mkdirSync(options.stagingDir, { recursive: true }), options.stagingDir)
|
|
38
|
+
: mkdtempSync(join(tmpdir(), "aura3d-screening-"));
|
|
39
|
+
return {
|
|
40
|
+
async search(query) {
|
|
41
|
+
const report = await runSearch({
|
|
42
|
+
query,
|
|
43
|
+
...(options.env ? { env: options.env } : {}),
|
|
44
|
+
limit: options.searchLimit ?? 10
|
|
45
|
+
});
|
|
46
|
+
// Rejected candidates are deliberately included: the pipeline's own licence/pullability gates decide
|
|
47
|
+
// and record why each one fails. Filtering them here would discard exactly the reasons that make a
|
|
48
|
+
// screening report reviewable.
|
|
49
|
+
return [...report.candidates, ...report.rejectedCandidates].map(toScreeningCandidate);
|
|
50
|
+
},
|
|
51
|
+
async pull(candidate) {
|
|
52
|
+
const url = candidate.downloadUrl;
|
|
53
|
+
if (!url)
|
|
54
|
+
throw new Error("candidate has no download URL");
|
|
55
|
+
// Content-addressed by id so a re-pull of the same candidate is idempotent within a run.
|
|
56
|
+
const safeName = candidate.id.replace(/[^a-zA-Z0-9_-]+/g, "_");
|
|
57
|
+
const destination = join(staging, `${safeName}.glb`);
|
|
58
|
+
if (existsSync(destination)) {
|
|
59
|
+
return { localPath: destination, sizeBytes: statSync(destination).size };
|
|
60
|
+
}
|
|
61
|
+
const result = await defaultDownloadFile(url, destination);
|
|
62
|
+
const localPath = result?.path ?? destination;
|
|
63
|
+
if (!existsSync(localPath))
|
|
64
|
+
throw new Error(`download produced no file at ${localPath}`);
|
|
65
|
+
return { localPath, sizeBytes: statSync(localPath).size };
|
|
66
|
+
},
|
|
67
|
+
async inspectGeometry(_candidate, pull) {
|
|
68
|
+
return inspectGlbGeometry(pull.localPath);
|
|
69
|
+
},
|
|
70
|
+
...(options.renderProbe ? { renderProbe: options.renderProbe } : {}),
|
|
71
|
+
...(options.register ? { register: options.register } : {})
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Structural geometry facts read directly from a GLB.
|
|
76
|
+
*
|
|
77
|
+
* This is the same measurement the standalone auditor performs, expressed in the admission vocabulary. It
|
|
78
|
+
* reads accessor min/max composed through the node hierarchy rather than trusting any manifest metadata,
|
|
79
|
+
* because the whole point of screening is to judge a file that is not registered yet.
|
|
80
|
+
*/
|
|
81
|
+
export function inspectGlbGeometry(file) {
|
|
82
|
+
const json = readGlbJson(file);
|
|
83
|
+
const parts = collectNodeWorldBounds(json);
|
|
84
|
+
const sizeBytes = statSync(file).size;
|
|
85
|
+
if (parts.length === 0) {
|
|
86
|
+
return { partCount: 0, triangles: 0, bounds: [0, 0, 0], materialCount: 0, textureCount: 0, drawCallsPerInstance: 0, sizeBytes };
|
|
87
|
+
}
|
|
88
|
+
const lo = [0, 1, 2].map((axis) => Math.min(...parts.map((part) => part.lo[axis])));
|
|
89
|
+
const hi = [0, 1, 2].map((axis) => Math.max(...parts.map((part) => part.hi[axis])));
|
|
90
|
+
const size = [hi[0] - lo[0], hi[1] - lo[1], hi[2] - lo[2]];
|
|
91
|
+
const triangles = parts.reduce((sum, part) => sum + part.triangles, 0);
|
|
92
|
+
const lengthAxis = size[0] >= size[2] ? 0 : 2;
|
|
93
|
+
const widthAxis = lengthAxis === 0 ? 2 : 0;
|
|
94
|
+
// Wheel-like parts: roughly circular in side profile, low-mounted, plausibly sized. Mirrors the
|
|
95
|
+
// standalone auditor's heuristic, because a second heuristic would let the two disagree.
|
|
96
|
+
const wheelParts = parts.filter((part) => {
|
|
97
|
+
const extent = [part.hi[0] - part.lo[0], part.hi[1] - part.lo[1], part.hi[2] - part.lo[2]];
|
|
98
|
+
if (Math.min(...extent) <= 0)
|
|
99
|
+
return false;
|
|
100
|
+
const topFraction = (part.hi[1] - lo[1]) / Math.max(size[1], 1e-9);
|
|
101
|
+
if (topFraction > 0.55)
|
|
102
|
+
return false;
|
|
103
|
+
const height = extent[1];
|
|
104
|
+
const length = extent[lengthAxis];
|
|
105
|
+
const width = extent[widthAxis];
|
|
106
|
+
if (Math.min(height, length) / Math.max(height, length) < 0.55)
|
|
107
|
+
return false;
|
|
108
|
+
if (width > Math.max(height, length) * 1.25)
|
|
109
|
+
return false;
|
|
110
|
+
const relative = Math.max(height, length) / Math.max(size[1], 1e-9);
|
|
111
|
+
return relative > 0.12 && relative < 0.75;
|
|
112
|
+
});
|
|
113
|
+
const midLength = (lo[lengthAxis] + hi[lengthAxis]) / 2;
|
|
114
|
+
const midWidth = (lo[widthAxis] + hi[widthAxis]) / 2;
|
|
115
|
+
const corners = new Set(wheelParts.map((part) => {
|
|
116
|
+
const alongLength = (part.lo[lengthAxis] + part.hi[lengthAxis]) / 2 > midLength ? "f" : "r";
|
|
117
|
+
const alongWidth = (part.lo[widthAxis] + part.hi[widthAxis]) / 2 > midWidth ? "l" : "r";
|
|
118
|
+
return `${alongLength}${alongWidth}`;
|
|
119
|
+
}));
|
|
120
|
+
const bodyHalfWidth = Math.max(Math.abs(lo[widthAxis]), Math.abs(hi[widthAxis]));
|
|
121
|
+
const wheelHalfWidth = wheelParts.reduce((widest, part) => Math.max(widest, Math.abs(part.lo[widthAxis]), Math.abs(part.hi[widthAxis])), 0);
|
|
122
|
+
const wheelsVisibleInSilhouette = wheelParts.length > 0 &&
|
|
123
|
+
wheelHalfWidth >= bodyHalfWidth - Math.max(size[widthAxis] * 0.02, 1e-6);
|
|
124
|
+
/*
|
|
125
|
+
* Per-instance draw cost, approximated as primitives x materials-in-use.
|
|
126
|
+
*
|
|
127
|
+
* This axis exists because a triangle budget missed a real regression: a 4.6MB pine cluster rendered
|
|
128
|
+
* correctly in isolation but carried 42 nodes and 5 materials per instance, driving a route to 840 draw
|
|
129
|
+
* calls and a blank capture.
|
|
130
|
+
*/
|
|
131
|
+
const primitiveCount = parts.reduce((sum, part) => sum + part.primitiveCount, 0);
|
|
132
|
+
const materialCount = (json.materials ?? []).length;
|
|
133
|
+
const textureCount = (json.textures ?? []).length;
|
|
134
|
+
return {
|
|
135
|
+
partCount: parts.length,
|
|
136
|
+
triangles,
|
|
137
|
+
bounds: size,
|
|
138
|
+
materialCount,
|
|
139
|
+
textureCount,
|
|
140
|
+
wheelCandidates: wheelParts.length,
|
|
141
|
+
distinctWheelCorners: corners.size,
|
|
142
|
+
wheelsVisibleInSilhouette,
|
|
143
|
+
wheelHalfWidth,
|
|
144
|
+
bodyHalfWidth,
|
|
145
|
+
minY: lo[1],
|
|
146
|
+
drawCallsPerInstance: primitiveCount,
|
|
147
|
+
sizeBytes
|
|
148
|
+
};
|
|
149
|
+
}
|
|
150
|
+
/** Map a catalog search line into the pipeline's candidate shape. */
|
|
151
|
+
function toScreeningCandidate(line) {
|
|
152
|
+
return {
|
|
153
|
+
id: line.id,
|
|
154
|
+
title: line.title,
|
|
155
|
+
provider: line.source,
|
|
156
|
+
licenseSpdx: line.license,
|
|
157
|
+
autoPullable: line.autoPullable,
|
|
158
|
+
...(line.sourcePage ? { sourcePage: line.sourcePage } : {}),
|
|
159
|
+
...(line.downloadUrl ? { downloadUrl: line.downloadUrl } : {}),
|
|
160
|
+
...(line.author ? { author: line.author } : {})
|
|
161
|
+
};
|
|
162
|
+
}
|
|
163
|
+
function readGlbJson(file) {
|
|
164
|
+
const bytes = readFileSync(file);
|
|
165
|
+
if (bytes.length < 20 || bytes.readUInt32LE(0) !== 0x46546c67) {
|
|
166
|
+
throw new Error(`${file} is not a binary GLB`);
|
|
167
|
+
}
|
|
168
|
+
const jsonLength = bytes.readUInt32LE(12);
|
|
169
|
+
return JSON.parse(bytes.subarray(20, 20 + jsonLength).toString("utf8"));
|
|
170
|
+
}
|
|
171
|
+
/** World-space AABB per mesh node, from accessor min/max composed through the node hierarchy. */
|
|
172
|
+
function collectNodeWorldBounds(json) {
|
|
173
|
+
const nodes = json.nodes ?? [];
|
|
174
|
+
const parent = new Map();
|
|
175
|
+
nodes.forEach((node, index) => (node.children ?? []).forEach((child) => parent.set(child, index)));
|
|
176
|
+
const localMatrix = (node) => {
|
|
177
|
+
if (Array.isArray(node.matrix))
|
|
178
|
+
return node.matrix;
|
|
179
|
+
const [tx = 0, ty = 0, tz = 0] = node.translation ?? [];
|
|
180
|
+
const [x = 0, y = 0, z = 0, w = 1] = node.rotation ?? [];
|
|
181
|
+
const [sx = 1, sy = 1, sz = 1] = node.scale ?? [];
|
|
182
|
+
const r = [
|
|
183
|
+
1 - 2 * (y * y + z * z), 2 * (x * y + z * w), 2 * (x * z - y * w),
|
|
184
|
+
2 * (x * y - z * w), 1 - 2 * (x * x + z * z), 2 * (y * z + x * w),
|
|
185
|
+
2 * (x * z + y * w), 2 * (y * z - x * w), 1 - 2 * (x * x + y * y)
|
|
186
|
+
];
|
|
187
|
+
return [
|
|
188
|
+
r[0] * sx, r[1] * sx, r[2] * sx, 0,
|
|
189
|
+
r[3] * sy, r[4] * sy, r[5] * sy, 0,
|
|
190
|
+
r[6] * sz, r[7] * sz, r[8] * sz, 0,
|
|
191
|
+
tx, ty, tz, 1
|
|
192
|
+
];
|
|
193
|
+
};
|
|
194
|
+
const multiply = (a, b) => {
|
|
195
|
+
const out = new Array(16).fill(0);
|
|
196
|
+
for (let column = 0; column < 4; column += 1) {
|
|
197
|
+
for (let row = 0; row < 4; row += 1) {
|
|
198
|
+
let sum = 0;
|
|
199
|
+
for (let k = 0; k < 4; k += 1)
|
|
200
|
+
sum += a[k * 4 + row] * b[column * 4 + k];
|
|
201
|
+
out[column * 4 + row] = sum;
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
return out;
|
|
205
|
+
};
|
|
206
|
+
const worldMatrix = (index) => {
|
|
207
|
+
let matrix = localMatrix(nodes[index]);
|
|
208
|
+
let next = parent.get(index);
|
|
209
|
+
while (next !== undefined) {
|
|
210
|
+
matrix = multiply(localMatrix(nodes[next]), matrix);
|
|
211
|
+
next = parent.get(next);
|
|
212
|
+
}
|
|
213
|
+
return matrix;
|
|
214
|
+
};
|
|
215
|
+
const apply = (m, point) => [
|
|
216
|
+
m[0] * point[0] + m[4] * point[1] + m[8] * point[2] + m[12],
|
|
217
|
+
m[1] * point[0] + m[5] * point[1] + m[9] * point[2] + m[13],
|
|
218
|
+
m[2] * point[0] + m[6] * point[1] + m[10] * point[2] + m[14]
|
|
219
|
+
];
|
|
220
|
+
const out = [];
|
|
221
|
+
nodes.forEach((node, index) => {
|
|
222
|
+
if (node.mesh === undefined)
|
|
223
|
+
return;
|
|
224
|
+
const mesh = json.meshes?.[node.mesh];
|
|
225
|
+
if (!mesh)
|
|
226
|
+
return;
|
|
227
|
+
let lo = [Infinity, Infinity, Infinity];
|
|
228
|
+
let hi = [-Infinity, -Infinity, -Infinity];
|
|
229
|
+
let triangles = 0;
|
|
230
|
+
let primitiveCount = 0;
|
|
231
|
+
for (const primitive of mesh.primitives ?? []) {
|
|
232
|
+
const positionIndex = primitive.attributes?.POSITION;
|
|
233
|
+
if (positionIndex === undefined)
|
|
234
|
+
continue;
|
|
235
|
+
const accessor = json.accessors?.[positionIndex];
|
|
236
|
+
if (!accessor?.min || !accessor?.max)
|
|
237
|
+
continue;
|
|
238
|
+
primitiveCount += 1;
|
|
239
|
+
lo = lo.map((value, axis) => Math.min(value, accessor.min[axis]));
|
|
240
|
+
hi = hi.map((value, axis) => Math.max(value, accessor.max[axis]));
|
|
241
|
+
if (primitive.indices !== undefined) {
|
|
242
|
+
triangles += Math.floor((json.accessors?.[primitive.indices]?.count ?? 0) / 3);
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
if (!lo.every(Number.isFinite))
|
|
246
|
+
return;
|
|
247
|
+
const matrix = worldMatrix(index);
|
|
248
|
+
const corners = [
|
|
249
|
+
...[lo[0], hi[0]].flatMap((x) => [lo[1], hi[1]].flatMap((y) => [lo[2], hi[2]].map((z) => apply(matrix, [x, y, z]))))
|
|
250
|
+
];
|
|
251
|
+
out.push({
|
|
252
|
+
lo: [0, 1, 2].map((axis) => Math.min(...corners.map((corner) => corner[axis]))),
|
|
253
|
+
hi: [0, 1, 2].map((axis) => Math.max(...corners.map((corner) => corner[axis]))),
|
|
254
|
+
triangles,
|
|
255
|
+
primitiveCount
|
|
256
|
+
});
|
|
257
|
+
});
|
|
258
|
+
return out;
|
|
259
|
+
}
|
|
260
|
+
/** sha256 of a staged file, for provenance binding in a screening report. */
|
|
261
|
+
export function hashStagedFile(file) {
|
|
262
|
+
return `sha256-${createHash("sha256").update(readFileSync(file)).digest("hex")}`;
|
|
263
|
+
}
|
|
264
|
+
/** Resolve a project-relative path, for callers staging into the repository. */
|
|
265
|
+
export function resolveProjectPath(projectDir, relativePath) {
|
|
266
|
+
return resolve(projectDir ?? process.cwd(), relativePath);
|
|
267
|
+
}
|
|
268
|
+
/**
|
|
269
|
+
* Build a render probe that reads a *retained* multi-angle visibility report.
|
|
270
|
+
*
|
|
271
|
+
* ## Why reading retained evidence is the right binding
|
|
272
|
+
*
|
|
273
|
+
* The alternative — launching a browser from inside the CLI — would make this package depend on the test
|
|
274
|
+
* harness and would put a 30-second render inside a search loop. Worse, a caller without a browser would be
|
|
275
|
+
* tempted to synthesise a verdict from geometry, which is the conflation that produced a false renderer
|
|
276
|
+
* diagnosis in the first place.
|
|
277
|
+
*
|
|
278
|
+
* Retained reports are produced by `tests/browser/vehicle-wheel-visibility.spec.ts`, which renders an asset
|
|
279
|
+
* across several azimuths and measures the lower-silhouette wheel band per angle. Reading them means the
|
|
280
|
+
* pipeline consumes *real rendered proof* while the rendering stays owned by the browser suite.
|
|
281
|
+
*
|
|
282
|
+
* A missing report is not treated as a failure: `renderedWheelVisibility` is left undefined so admission
|
|
283
|
+
* reports `unproven`. That distinction matters — "no evidence" and "evidence of absence" are different, and
|
|
284
|
+
* conflating them is what made a correctly-drawing asset look broken.
|
|
285
|
+
*/
|
|
286
|
+
export function createRetainedRenderProbe(options = {}) {
|
|
287
|
+
const reportDir = options.reportDir ?? "tests/reports/vehicle-wheel-visibility";
|
|
288
|
+
const minBandPixels = options.minBandPixels ?? 2_000;
|
|
289
|
+
return async (candidate) => {
|
|
290
|
+
// Reports are keyed by registered asset id, not by provider candidate id.
|
|
291
|
+
const assetId = candidate.id.includes(":") ? candidate.id.split(":").pop() : candidate.id;
|
|
292
|
+
const path = resolveProjectPath(options.projectDir, join(reportDir, `${assetId}.json`));
|
|
293
|
+
if (!existsSync(path))
|
|
294
|
+
return {};
|
|
295
|
+
const report = JSON.parse(readFileSync(path, "utf8"));
|
|
296
|
+
const angles = report.angles ?? [];
|
|
297
|
+
/*
|
|
298
|
+
* An angle counts as readable when the wheel band carries real mass in *both* outer thirds.
|
|
299
|
+
*
|
|
300
|
+
* Centre-only mass is bodywork seen head-on — precisely the geometry of the misleading dead-astern
|
|
301
|
+
* probe. Requiring both outer thirds is what distinguishes "wheels read here" from "the car's rear is
|
|
302
|
+
* filling the frame".
|
|
303
|
+
*/
|
|
304
|
+
const readable = angles.filter((angle) => {
|
|
305
|
+
const band = angle.wheelBand;
|
|
306
|
+
if (!band || (band.pixels ?? 0) < minBandPixels)
|
|
307
|
+
return false;
|
|
308
|
+
const outer = Math.min(band.leftThird ?? 0, band.rightThird ?? 0);
|
|
309
|
+
return outer >= (band.pixels ?? 0) * 0.18;
|
|
310
|
+
});
|
|
311
|
+
return {
|
|
312
|
+
screenshotPath: join(reportDir, `${assetId}-angle-0.png`),
|
|
313
|
+
renderedWheelVisibility: readable.length > 0,
|
|
314
|
+
renderedAzimuths: readable
|
|
315
|
+
.map((angle) => angle.azimuth ?? 0)
|
|
316
|
+
// A dead-on view is excluded from the evidence set: it is the one angle where bodywork hides wheels.
|
|
317
|
+
.filter((azimuth) => Math.abs(azimuth) > 0.2)
|
|
318
|
+
};
|
|
319
|
+
};
|
|
320
|
+
}
|
|
321
|
+
//# sourceMappingURL=asset-screening-effects.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"asset-screening-effects.js","sourceRoot":"","sources":["../../../../packages/aura3d-cli/src/asset-screening-effects.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Orchestrated candidate screening pipeline.
|
|
3
|
+
*
|
|
4
|
+
* ## Why an orchestrator rather than a documented procedure
|
|
5
|
+
*
|
|
6
|
+
* The individual capabilities exist: search, `--index`/`--candidate-id` selection, geometry auditing,
|
|
7
|
+
* isolated render probes, role-aware admission, registration and typegen. What did not exist was
|
|
8
|
+
* anything that *runs them in order and keeps the record*. In practice that meant a human ran a few
|
|
9
|
+
* steps by hand, formed an impression, and moved on -- which is exactly how three unusable hero vehicles
|
|
10
|
+
* shipped in a row, and how I once concluded "the catalog has no suitable props" without having searched
|
|
11
|
+
* it.
|
|
12
|
+
*
|
|
13
|
+
* The pipeline's real product is therefore not the accepted asset. It is the **retained record of every
|
|
14
|
+
* candidate and why it was rejected**. An accepted asset with no record of its rivals cannot be
|
|
15
|
+
* reviewed, and a rejection with no reason cannot be learned from.
|
|
16
|
+
*
|
|
17
|
+
* ## Stages
|
|
18
|
+
*
|
|
19
|
+
* search -> enumerate -> select -> pull -> inspect geometry -> render probe -> score role fitness ->
|
|
20
|
+
* reject with machine-readable reasons -> rank accepted -> register durably -> typegen -> certify.
|
|
21
|
+
*
|
|
22
|
+
* ## Deliberate injection seams
|
|
23
|
+
*
|
|
24
|
+
* Every external effect (search, pull, geometry inspection, render probe, register) is injected. That is
|
|
25
|
+
* not test convenience: a render probe needs a browser and a pull needs the network, so a pipeline that
|
|
26
|
+
* hardcoded them could only ever be tested by running the whole thing. Injection lets the *ordering and
|
|
27
|
+
* record-keeping logic* -- the part that failed before -- be tested deterministically and offline.
|
|
28
|
+
*/
|
|
29
|
+
import { type AssetAdmissionReport, type AssetGeometryFacts, type AssetRenderedFacts } from "./asset-role-admission.js";
|
|
30
|
+
import { type AssetIntent } from "./asset-intent.js";
|
|
31
|
+
/** A candidate as returned by search, before anything has been downloaded. */
|
|
32
|
+
export interface ScreeningCandidate {
|
|
33
|
+
/** Provider-qualified id, e.g. `objaverse:ffca09fb...`. */
|
|
34
|
+
readonly id: string;
|
|
35
|
+
readonly title?: string | undefined;
|
|
36
|
+
readonly provider?: string | undefined;
|
|
37
|
+
readonly licenseSpdx?: string | undefined;
|
|
38
|
+
readonly author?: string | undefined;
|
|
39
|
+
readonly sourcePage?: string | undefined;
|
|
40
|
+
readonly downloadUrl?: string | undefined;
|
|
41
|
+
/** Provider-reported rank score; used only for tie-breaks, never as fitness. */
|
|
42
|
+
readonly searchScore?: number | undefined;
|
|
43
|
+
/** True when the candidate can be fetched without interactive auth. */
|
|
44
|
+
readonly autoPullable?: boolean | undefined;
|
|
45
|
+
readonly sizeBytes?: number | undefined;
|
|
46
|
+
}
|
|
47
|
+
/** Result of pulling a candidate to a local path. */
|
|
48
|
+
export interface ScreeningPullResult {
|
|
49
|
+
readonly localPath: string;
|
|
50
|
+
readonly sizeBytes?: number | undefined;
|
|
51
|
+
}
|
|
52
|
+
/** Per-instance render cost, which a triangle budget does not capture. */
|
|
53
|
+
export interface ScreeningRenderCost {
|
|
54
|
+
readonly drawCallsPerInstance?: number | undefined;
|
|
55
|
+
}
|
|
56
|
+
/** Injected effects. Each may throw; a throw rejects that candidate and the pipeline continues. */
|
|
57
|
+
export interface ScreeningEffects {
|
|
58
|
+
/** Enumerate candidates for a query. */
|
|
59
|
+
search(query: string): Promise<readonly ScreeningCandidate[]>;
|
|
60
|
+
/** Download a candidate. */
|
|
61
|
+
pull(candidate: ScreeningCandidate): Promise<ScreeningPullResult>;
|
|
62
|
+
/** Structural geometry facts from the pulled file. */
|
|
63
|
+
inspectGeometry(candidate: ScreeningCandidate, pull: ScreeningPullResult): Promise<AssetGeometryFacts & ScreeningRenderCost>;
|
|
64
|
+
/**
|
|
65
|
+
* Render the candidate in isolation and report whether required features read.
|
|
66
|
+
*
|
|
67
|
+
* Optional: when absent, admission reports rendered visibility as `unproven` rather than passing,
|
|
68
|
+
* which is the honest outcome. It must never be synthesised from geometry.
|
|
69
|
+
*/
|
|
70
|
+
renderProbe?: ((candidate: ScreeningCandidate, pull: ScreeningPullResult) => Promise<AssetRenderedFacts>) | undefined;
|
|
71
|
+
/** Register the accepted asset durably and generate typed bindings. */
|
|
72
|
+
register?: ((candidate: ScreeningCandidate, pull: ScreeningPullResult) => Promise<{
|
|
73
|
+
readonly assetId: string;
|
|
74
|
+
readonly typedRef: string;
|
|
75
|
+
}>) | undefined;
|
|
76
|
+
}
|
|
77
|
+
export type ScreeningStage = "search" | "license-policy" | "auto-pullable" | "pull" | "inspect-geometry" | "budget" | "render-probe" | "admission" | "register";
|
|
78
|
+
/** One candidate's outcome, retained whether accepted or not. */
|
|
79
|
+
export interface ScreeningCandidateOutcome {
|
|
80
|
+
readonly candidate: ScreeningCandidate;
|
|
81
|
+
/** Zero-based position in the deduplicated enumerated list. */
|
|
82
|
+
readonly index: number;
|
|
83
|
+
readonly accepted: boolean;
|
|
84
|
+
/** Stage at which the candidate was rejected. `undefined` when accepted. */
|
|
85
|
+
readonly rejectedAtStage?: ScreeningStage | undefined;
|
|
86
|
+
/** Machine-readable rejection reasons. Never empty for a rejected candidate. */
|
|
87
|
+
readonly reasons: readonly string[];
|
|
88
|
+
readonly geometry?: (AssetGeometryFacts & ScreeningRenderCost) | undefined;
|
|
89
|
+
readonly rendered?: AssetRenderedFacts | undefined;
|
|
90
|
+
readonly admission?: AssetAdmissionReport | undefined;
|
|
91
|
+
}
|
|
92
|
+
export interface ScreeningReport {
|
|
93
|
+
readonly schema: "aura3d-asset-screening/1.0";
|
|
94
|
+
readonly intentId: string;
|
|
95
|
+
readonly role: string;
|
|
96
|
+
readonly queries: readonly string[];
|
|
97
|
+
/** Every candidate seen, in enumeration order, with its outcome. */
|
|
98
|
+
readonly candidates: readonly ScreeningCandidateOutcome[];
|
|
99
|
+
/** Accepted candidates, best first. */
|
|
100
|
+
readonly ranked: readonly ScreeningCandidateOutcome[];
|
|
101
|
+
/** The selected candidate, when one was accepted or a fallback allowed one. */
|
|
102
|
+
readonly selected?: ScreeningCandidateOutcome | undefined;
|
|
103
|
+
/** Set when the selection only satisfied a fallback policy; names what is still unproven. */
|
|
104
|
+
readonly fallbackApplied?: {
|
|
105
|
+
readonly policy: string;
|
|
106
|
+
readonly gaps: readonly string[];
|
|
107
|
+
} | undefined;
|
|
108
|
+
readonly registered?: {
|
|
109
|
+
readonly assetId: string;
|
|
110
|
+
readonly typedRef: string;
|
|
111
|
+
} | undefined;
|
|
112
|
+
/** Counts per stage, so "where do candidates die?" is answerable without reading every entry. */
|
|
113
|
+
readonly rejectionsByStage: Readonly<Record<string, number>>;
|
|
114
|
+
}
|
|
115
|
+
export interface ScreeningOptions {
|
|
116
|
+
readonly intent: AssetIntent;
|
|
117
|
+
readonly effects: ScreeningEffects;
|
|
118
|
+
/** Maximum candidates to pull. Pulling is the expensive stage, so it is bounded. */
|
|
119
|
+
readonly maxCandidatesToPull?: number | undefined;
|
|
120
|
+
/** Stop after the first accepted candidate. Default true; set false to rank the whole set. */
|
|
121
|
+
readonly stopAtFirstAccepted?: boolean | undefined;
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* Run the screening pipeline for an intent.
|
|
125
|
+
*
|
|
126
|
+
* Throws only for an incoherent intent -- a request that cannot be satisfied as written is a caller
|
|
127
|
+
* defect, not a screening outcome. Everything else is reported.
|
|
128
|
+
*/
|
|
129
|
+
export declare function screenAssetCandidates(options: ScreeningOptions): Promise<ScreeningReport>;
|
|
130
|
+
/** Render a screening report as human-readable lines. Every rejection keeps its reason. */
|
|
131
|
+
export declare function formatScreeningReport(report: ScreeningReport): readonly string[];
|
|
132
|
+
//# sourceMappingURL=asset-screening-pipeline.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"asset-screening-pipeline.d.ts","sourceRoot":"","sources":["../../../../packages/aura3d-cli/src/asset-screening-pipeline.ts"],"names":[],"mappings":"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"}
|