@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.
Files changed (36) hide show
  1. package/dist/asset-intent.d.ts +148 -0
  2. package/dist/asset-intent.d.ts.map +1 -0
  3. package/dist/asset-intent.js +145 -0
  4. package/dist/asset-intent.js.map +1 -0
  5. package/dist/asset-role-admission.d.ts +174 -0
  6. package/dist/asset-role-admission.d.ts.map +1 -0
  7. package/dist/asset-role-admission.js +381 -0
  8. package/dist/asset-role-admission.js.map +1 -0
  9. package/dist/asset-screening-effects.d.ts +95 -0
  10. package/dist/asset-screening-effects.d.ts.map +1 -0
  11. package/dist/asset-screening-effects.js +321 -0
  12. package/dist/asset-screening-effects.js.map +1 -0
  13. package/dist/asset-screening-pipeline.d.ts +132 -0
  14. package/dist/asset-screening-pipeline.d.ts.map +1 -0
  15. package/dist/asset-screening-pipeline.js +277 -0
  16. package/dist/asset-screening-pipeline.js.map +1 -0
  17. package/dist/cartoon-asset-profiles.d.ts +15 -0
  18. package/dist/cartoon-asset-profiles.d.ts.map +1 -0
  19. package/dist/cartoon-asset-profiles.js +46 -0
  20. package/dist/cartoon-asset-profiles.js.map +1 -0
  21. package/dist/cli-help.js +1 -1
  22. package/dist/cli.js +16 -2
  23. package/dist/cli.js.map +1 -1
  24. package/dist/index.d.ts +8 -0
  25. package/dist/index.d.ts.map +1 -1
  26. package/dist/index.js +390 -17
  27. package/dist/index.js.map +1 -1
  28. package/dist/pull-bridge/search.d.ts +4 -0
  29. package/dist/pull-bridge/search.d.ts.map +1 -1
  30. package/dist/pull-bridge/search.js +22 -0
  31. package/dist/pull-bridge/search.js.map +1 -1
  32. package/dist/pull-bridge.d.ts +20 -5
  33. package/dist/pull-bridge.d.ts.map +1 -1
  34. package/dist/pull-bridge.js +38 -1
  35. package/dist/pull-bridge.js.map +1 -1
  36. package/package.json +3 -3
@@ -0,0 +1,148 @@
1
+ /**
2
+ * Typed asset-intent contract.
3
+ *
4
+ * ## Why a declarative contract
5
+ *
6
+ * Three unusable hero vehicles shipped into Turbo Drift Circuit in succession. Each replacement was
7
+ * chosen by re-wording a search query and hoping the resolver returned something better, because there
8
+ * was nowhere to *state what the route actually needed*. The requirement lived in a human's head:
9
+ * "a modern road car with visible tyres, textured, commercially usable". Nothing machine-readable
10
+ * expressed it, so nothing could check a candidate against it.
11
+ *
12
+ * An asset intent makes that requirement a value. It is consumed by the screening pipeline
13
+ * (`screenAssetCandidates`) to decide which candidates to reject and why, and by
14
+ * `admitAssetForRole` to decide whether a registered asset is fit for the role it is used in.
15
+ *
16
+ * ## Deliberate separation from admission
17
+ *
18
+ * `AssetRoleRequirement` in `asset-role-admission.ts` is the *checkable* subset: thresholds derived from
19
+ * an intent. `AssetIntent` is the *authored* form, and carries fields admission cannot check on its own
20
+ * (style words, expected camera angles, fallback policy) which the pipeline uses for search, ranking and
21
+ * probe configuration. Keeping them separate stops the admission checker from growing fields it cannot
22
+ * actually verify, which is how "asset loads, therefore asset is fine" gets reintroduced.
23
+ */
24
+ import type { AssetAdmissionRole, AssetRoleRequirement } from "./asset-role-admission.js";
25
+ /**
26
+ * A visual feature a role may require to be *readable*, not merely present.
27
+ *
28
+ * The distinction is the entire point. `turboHeroCar` had 16 wheel parts at four corners and still read
29
+ * as a wheelless shell, because a closed-wheel Le Mans body encloses them. "Has wheels" and "wheels are
30
+ * visible" are different claims and the contract must be able to demand the second one.
31
+ */
32
+ export type RequiredVisibleFeature = "wheels" | "feet" | "hands" | "face" | "windows" | "doors" | "weapon-muzzle" | "interactive-surface";
33
+ /** How permissive the caller is about licensing. */
34
+ export type LicensePolicy =
35
+ /** Public-domain or CC0 only: no attribution obligation. */
36
+ "public-domain-only"
37
+ /** Attribution-required licences allowed; the pipeline records the attribution. */
38
+ | "commercial-attribution-allowed"
39
+ /** Any redistributable licence, including share-alike. */
40
+ | "any-redistributable";
41
+ /** What the caller will do about scale and pivot. */
42
+ export type NormalizationPolicy =
43
+ /** Let the renderer fit and ground the asset from its manifest bounds. */
44
+ "fit-and-ground"
45
+ /** Use the asset's own world units untouched; the caller has verified they are correct. */
46
+ | "preserve-source-units"
47
+ /** Require the asset to already be authored at real-world scale with a grounded pivot. */
48
+ | "require-authored-scale";
49
+ /** What to do when no candidate satisfies the intent. */
50
+ export type FallbackPolicy =
51
+ /** Fail loudly. Correct for a hero: a wrong hero is worse than a missing one. */
52
+ "reject-and-fail"
53
+ /** Accept the best-ranked candidate that fails only `unproven` checks, and record the gap. */
54
+ | "accept-best-with-recorded-gaps"
55
+ /** Fall back to a lesser role (e.g. background instead of hero) and record the downgrade. */
56
+ | "downgrade-role";
57
+ /** Geometry budget for the role. */
58
+ export interface AssetGeometryBudget {
59
+ readonly maxTriangles?: number | undefined;
60
+ readonly minTriangles?: number | undefined;
61
+ readonly maxFileBytes?: number | undefined;
62
+ /**
63
+ * Maximum draw calls this asset may contribute *per instance*.
64
+ *
65
+ * Added after a real regression: a 4.6MB pine cluster rendered correctly in isolation but carried 42
66
+ * nodes and 5 materials per instance, and at composition density drove a route to 840 draw calls and a
67
+ * blank capture. A triangle budget would not have caught it; instance draw cost is a separate axis.
68
+ */
69
+ readonly maxDrawCallsPerInstance?: number | undefined;
70
+ }
71
+ /** Camera angles the asset must read correctly from, in radians of azimuth. */
72
+ export interface AssetCameraExpectation {
73
+ /**
74
+ * Azimuths the asset is presented at. A hero requiring readable wheels must list at least two, because
75
+ * a single dead-on angle is exactly where a car's bodywork hides its own wheels -- the mistake that
76
+ * produced a false "the renderer drops wheel primitives" diagnosis.
77
+ */
78
+ readonly heroAzimuths: readonly number[];
79
+ readonly elevation?: number | undefined;
80
+ }
81
+ /** Orientation evidence the caller needs before it will trust a forward direction. */
82
+ export type OrientationRequirement =
83
+ /** Manifest must declare `forwardAxis`; reject otherwise. */
84
+ "require-manifest-evidence"
85
+ /** Accept an inferred forward axis, recording that it is inferred. */
86
+ | "allow-inferred"
87
+ /** Orientation is irrelevant (radially symmetric props, terrain). */
88
+ | "not-required";
89
+ /**
90
+ * A route's declarative statement of what it needs from an asset.
91
+ *
92
+ * Every field is either used to *search*, to *reject*, or to *configure a probe*. Nothing here is
93
+ * decorative; a field that could not change an outcome would be a comment.
94
+ */
95
+ export interface AssetIntent {
96
+ /** Stable id for the intent, used in reports so a rejection is traceable to a requirement. */
97
+ readonly id: string;
98
+ /** The role the asset will be used in. Drives which admission checks apply. */
99
+ readonly role: AssetAdmissionRole;
100
+ /** Free-text style intent, used to build search queries. */
101
+ readonly style: string;
102
+ /** Features that must be *visually readable*, not merely modelled. */
103
+ readonly requiredVisibleFeatures?: readonly RequiredVisibleFeature[] | undefined;
104
+ /** Require textured materials rather than flat colour. */
105
+ readonly materialRequirement?: "textured" | "any" | undefined;
106
+ readonly licensePolicy: LicensePolicy;
107
+ readonly geometryBudget?: AssetGeometryBudget | undefined;
108
+ readonly heroCameraAngles?: AssetCameraExpectation | undefined;
109
+ readonly orientationRequirement?: OrientationRequirement | undefined;
110
+ readonly normalizationPolicy?: NormalizationPolicy | undefined;
111
+ readonly fallbackPolicy?: FallbackPolicy | undefined;
112
+ }
113
+ /** True when `spdx` satisfies `policy`. Unknown or missing identifiers never satisfy any policy. */
114
+ export declare function licenseSatisfiesPolicy(spdx: string | undefined, policy: LicensePolicy): boolean;
115
+ /** SPDX identifiers a policy admits, for search-time filtering and error messages. */
116
+ export declare function licensesForPolicy(policy: LicensePolicy): readonly string[];
117
+ /**
118
+ * Minimum distinct hero azimuths required when a role demands a readable feature.
119
+ *
120
+ * Mirrors `HERO_MIN_RENDERED_AZIMUTHS` in the admission module. Duplicated as a *validation* rule here
121
+ * so an intent that could never be satisfied is rejected when authored, rather than after a pipeline run.
122
+ */
123
+ export declare const MIN_INTENT_HERO_AZIMUTHS = 2;
124
+ /**
125
+ * Reject an intent that cannot be satisfied as written.
126
+ *
127
+ * Authoring-time validation matters because the alternative is a screening run that rejects every
128
+ * candidate for a reason that is actually a defect in the request. Returns human-readable problems;
129
+ * empty means the intent is coherent.
130
+ */
131
+ export declare function validateAssetIntent(intent: AssetIntent): readonly string[];
132
+ /**
133
+ * Derive the checkable admission requirement from an authored intent.
134
+ *
135
+ * This is the seam between "what a route asked for" and "what a checker can verify". Anything the
136
+ * checker cannot verify is deliberately *not* forwarded, so admission never reports a pass on a
137
+ * dimension it did not measure.
138
+ */
139
+ export declare function admissionRequirementForIntent(intent: AssetIntent): AssetRoleRequirement;
140
+ /**
141
+ * Build search queries for an intent, most specific first.
142
+ *
143
+ * Multiple phrasings rather than one, because a single query returning poor candidates was previously
144
+ * indistinguishable from "the catalog has nothing" -- a conclusion I reached wrongly once and which cost
145
+ * a whole pass. Enumerating phrasings makes the search itself auditable.
146
+ */
147
+ export declare function searchQueriesForIntent(intent: AssetIntent): readonly string[];
148
+ //# sourceMappingURL=asset-intent.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"asset-intent.d.ts","sourceRoot":"","sources":["../../../../packages/aura3d-cli/src/asset-intent.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,145 @@
1
+ /**
2
+ * Typed asset-intent contract.
3
+ *
4
+ * ## Why a declarative contract
5
+ *
6
+ * Three unusable hero vehicles shipped into Turbo Drift Circuit in succession. Each replacement was
7
+ * chosen by re-wording a search query and hoping the resolver returned something better, because there
8
+ * was nowhere to *state what the route actually needed*. The requirement lived in a human's head:
9
+ * "a modern road car with visible tyres, textured, commercially usable". Nothing machine-readable
10
+ * expressed it, so nothing could check a candidate against it.
11
+ *
12
+ * An asset intent makes that requirement a value. It is consumed by the screening pipeline
13
+ * (`screenAssetCandidates`) to decide which candidates to reject and why, and by
14
+ * `admitAssetForRole` to decide whether a registered asset is fit for the role it is used in.
15
+ *
16
+ * ## Deliberate separation from admission
17
+ *
18
+ * `AssetRoleRequirement` in `asset-role-admission.ts` is the *checkable* subset: thresholds derived from
19
+ * an intent. `AssetIntent` is the *authored* form, and carries fields admission cannot check on its own
20
+ * (style words, expected camera angles, fallback policy) which the pipeline uses for search, ranking and
21
+ * probe configuration. Keeping them separate stops the admission checker from growing fields it cannot
22
+ * actually verify, which is how "asset loads, therefore asset is fine" gets reintroduced.
23
+ */
24
+ /** SPDX identifiers each policy admits. */
25
+ const LICENSE_POLICY_ALLOWLIST = {
26
+ "public-domain-only": ["CC0-1.0", "Unlicense", "PDDL-1.0"],
27
+ "commercial-attribution-allowed": ["CC0-1.0", "Unlicense", "PDDL-1.0", "CC-BY-4.0", "CC-BY-3.0", "MIT", "Apache-2.0"],
28
+ "any-redistributable": [
29
+ "CC0-1.0", "Unlicense", "PDDL-1.0", "CC-BY-4.0", "CC-BY-3.0", "MIT", "Apache-2.0",
30
+ "CC-BY-SA-4.0", "CC-BY-SA-3.0"
31
+ ]
32
+ };
33
+ /** True when `spdx` satisfies `policy`. Unknown or missing identifiers never satisfy any policy. */
34
+ export function licenseSatisfiesPolicy(spdx, policy) {
35
+ if (!spdx)
36
+ return false;
37
+ return LICENSE_POLICY_ALLOWLIST[policy].includes(spdx);
38
+ }
39
+ /** SPDX identifiers a policy admits, for search-time filtering and error messages. */
40
+ export function licensesForPolicy(policy) {
41
+ return LICENSE_POLICY_ALLOWLIST[policy];
42
+ }
43
+ /**
44
+ * Minimum distinct hero azimuths required when a role demands a readable feature.
45
+ *
46
+ * Mirrors `HERO_MIN_RENDERED_AZIMUTHS` in the admission module. Duplicated as a *validation* rule here
47
+ * so an intent that could never be satisfied is rejected when authored, rather than after a pipeline run.
48
+ */
49
+ export const MIN_INTENT_HERO_AZIMUTHS = 2;
50
+ /**
51
+ * Reject an intent that cannot be satisfied as written.
52
+ *
53
+ * Authoring-time validation matters because the alternative is a screening run that rejects every
54
+ * candidate for a reason that is actually a defect in the request. Returns human-readable problems;
55
+ * empty means the intent is coherent.
56
+ */
57
+ export function validateAssetIntent(intent) {
58
+ const problems = [];
59
+ if (!intent.id.trim())
60
+ problems.push("intent id must not be empty");
61
+ if (!intent.style.trim())
62
+ problems.push("intent style must not be empty; it is used to build search queries");
63
+ const budget = intent.geometryBudget;
64
+ if (budget?.maxTriangles !== undefined && budget?.minTriangles !== undefined &&
65
+ budget.minTriangles > budget.maxTriangles) {
66
+ problems.push(`geometry budget is empty: minTriangles ${budget.minTriangles} exceeds maxTriangles ${budget.maxTriangles}`);
67
+ }
68
+ for (const [field, value] of [
69
+ ["maxTriangles", budget?.maxTriangles],
70
+ ["minTriangles", budget?.minTriangles],
71
+ ["maxFileBytes", budget?.maxFileBytes],
72
+ ["maxDrawCallsPerInstance", budget?.maxDrawCallsPerInstance]
73
+ ]) {
74
+ if (value !== undefined && (!Number.isFinite(value) || value < 0)) {
75
+ problems.push(`geometry budget ${field} must be a non-negative finite number (got ${String(value)})`);
76
+ }
77
+ }
78
+ const features = intent.requiredVisibleFeatures ?? [];
79
+ if (features.length > 0) {
80
+ const azimuths = intent.heroCameraAngles?.heroAzimuths ?? [];
81
+ const distinct = new Set(azimuths.map((azimuth) => Number(azimuth.toFixed(4))));
82
+ if (distinct.size < MIN_INTENT_HERO_AZIMUTHS) {
83
+ problems.push(`intent requires visible features (${features.join(", ")}) but declares only ${distinct.size} distinct hero azimuth(s); ` +
84
+ `${MIN_INTENT_HERO_AZIMUTHS}+ are required because a single head-on angle is where a subject's own body hides its lower features`);
85
+ }
86
+ }
87
+ if (features.includes("wheels") && intent.role !== "hero-vehicle" && intent.role !== "background-vehicle") {
88
+ problems.push(`role "${intent.role}" cannot require visible wheels`);
89
+ }
90
+ if (features.includes("feet") && intent.role !== "playable-character") {
91
+ problems.push(`role "${intent.role}" cannot require visible feet`);
92
+ }
93
+ return problems;
94
+ }
95
+ /**
96
+ * Derive the checkable admission requirement from an authored intent.
97
+ *
98
+ * This is the seam between "what a route asked for" and "what a checker can verify". Anything the
99
+ * checker cannot verify is deliberately *not* forwarded, so admission never reports a pass on a
100
+ * dimension it did not measure.
101
+ */
102
+ export function admissionRequirementForIntent(intent) {
103
+ const features = intent.requiredVisibleFeatures ?? [];
104
+ const budget = intent.geometryBudget;
105
+ return {
106
+ role: intent.role,
107
+ ...(features.includes("wheels") ? { requireReadableWheels: true } : {}),
108
+ ...(intent.materialRequirement === "textured" ? { requireTextured: true } : {}),
109
+ ...(budget?.maxTriangles !== undefined ? { maxTriangles: budget.maxTriangles } : {}),
110
+ ...(budget?.minTriangles !== undefined ? { minTriangles: budget.minTriangles } : {}),
111
+ // Attribution-bearing policies need author + licence recorded, so provenance completeness is checked.
112
+ ...(intent.licensePolicy !== "public-domain-only" ? { requireProvenance: true } : {})
113
+ };
114
+ }
115
+ /**
116
+ * Build search queries for an intent, most specific first.
117
+ *
118
+ * Multiple phrasings rather than one, because a single query returning poor candidates was previously
119
+ * indistinguishable from "the catalog has nothing" -- a conclusion I reached wrongly once and which cost
120
+ * a whole pass. Enumerating phrasings makes the search itself auditable.
121
+ */
122
+ export function searchQueriesForIntent(intent) {
123
+ const style = intent.style.trim();
124
+ const roleWords = {
125
+ "hero-vehicle": ["car", "vehicle"],
126
+ "background-vehicle": ["car", "traffic vehicle"],
127
+ "playable-character": ["character", "character model"],
128
+ environment: ["environment", "scene"],
129
+ track: ["race track", "circuit"],
130
+ platform: ["platform", "level block"],
131
+ building: ["building", "house"],
132
+ prop: ["prop"],
133
+ collectible: ["collectible", "pickup"],
134
+ weapon: ["weapon"],
135
+ "ui-hero-object": ["product model"]
136
+ };
137
+ const words = roleWords[intent.role] ?? [];
138
+ const queries = [style, ...words.map((word) => `${style} ${word}`)];
139
+ if ((intent.requiredVisibleFeatures ?? []).includes("wheels")) {
140
+ queries.push(`${style} car with visible wheels`);
141
+ }
142
+ // Dedupe while preserving specificity order.
143
+ return [...new Set(queries.map((query) => query.trim()).filter(Boolean))];
144
+ }
145
+ //# sourceMappingURL=asset-intent.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"asset-intent.js","sourceRoot":"","sources":["../../../../packages/aura3d-cli/src/asset-intent.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,174 @@
1
+ /**
2
+ * Role-aware asset fitness admission.
3
+ *
4
+ * ## Why this exists, and why one boolean is not enough
5
+ *
6
+ * Three hero-vehicle assets shipped into Turbo Drift Circuit and every one of them was visually wrong
7
+ * in a *different* way that every existing gate accepted:
8
+ *
9
+ * | Asset | Parts | Triangles | Actual failure |
10
+ * | --- | --- | --- | --- |
11
+ * | `showcaseTexturedSportsCar` | 7 | 33,700 | tyres attached through detached stalk-like geometry |
12
+ * | `showcaseCityVehicle` | 1 | 792 | a distant low-poly body shell with no wheels modelled at all |
13
+ * | `turboHeroCar` | 483 | 71,426 | closed-wheel Le Mans body encloses the wheels; not readable |
14
+ *
15
+ * Nothing caught them because every upstream check measured the *frame*, not the *model*: probe
16
+ * thresholds measure subject pixel size, readability rules measure foreground bounds, composition
17
+ * checks measure coverage ratios. A wheelless car is a large, well-lit, correctly-framed subject and
18
+ * passes all of them.
19
+ *
20
+ * The second lesson is that fitness is **not global**. `showcaseCityVehicle` is a perfectly good
21
+ * background traffic prop and a bad hero. `turboHeroCar` is a structurally valid vehicle and a bad
22
+ * choice when the requested style needs exposed tyres. Collapsing that into one pass/fail either
23
+ * rejects usable assets or admits unusable ones. So admission is evaluated **against a requested role
24
+ * and its visual requirements**, and every check is reported individually with its own verdict so a
25
+ * rejection is machine-readable and explains itself.
26
+ *
27
+ * ## Deliberate boundary
28
+ *
29
+ * This module is structural only. It consumes geometry and provenance facts and never claims rendered
30
+ * visibility: `wheelsVisibleInSilhouette` is a *geometric prediction* that wheels reach the body
31
+ * silhouette, not proof a viewer saw them. Rendered proof is a separate input
32
+ * (`renderedWheelVisibility`) supplied by a browser probe, because the repository rule is that no
33
+ * visual claim may rest on mesh statistics. When rendered evidence is absent for a role that requires
34
+ * it, admission reports `unproven` rather than `pass`.
35
+ */
36
+ /** Roles admission can be requested for. Vehicle is fully specified; the rest are extensible. */
37
+ export type AssetAdmissionRole = "hero-vehicle" | "background-vehicle" | "playable-character" | "environment" | "track" | "platform" | "building" | "prop" | "collectible" | "weapon" | "ui-hero-object";
38
+ export type AssetAdmissionVerdict = "pass" | "fail" | "unproven" | "not-applicable";
39
+ /** One named check, reported individually so a rejection explains itself. */
40
+ export interface AssetAdmissionCheck {
41
+ readonly id: string;
42
+ readonly verdict: AssetAdmissionVerdict;
43
+ /** Human-readable reason. Always populated for `fail` and `unproven`. */
44
+ readonly detail: string;
45
+ /** Measured value the verdict was derived from, when there is one. */
46
+ readonly measured?: number | string | boolean | undefined;
47
+ }
48
+ /** Geometry facts, as produced by the vehicle geometry auditor. */
49
+ export interface AssetGeometryFacts {
50
+ readonly partCount: number;
51
+ readonly triangles: number;
52
+ /** Axis-aligned world size, `[x, y, z]`. */
53
+ readonly bounds: readonly [number, number, number];
54
+ readonly materialCount?: number | undefined;
55
+ readonly textureCount?: number | undefined;
56
+ /** Roughly-circular, low-mounted parts found. */
57
+ readonly wheelCandidates?: number | undefined;
58
+ /** Distinct outboard corners carrying such a part. */
59
+ readonly distinctWheelCorners?: number | undefined;
60
+ /** True when at least one wheel reaches the body silhouette in plan view. */
61
+ readonly wheelsVisibleInSilhouette?: boolean | undefined;
62
+ /** Largest |half-width| reached by a wheel candidate. */
63
+ readonly wheelHalfWidth?: number | undefined;
64
+ /** Largest |half-width| of the whole body. */
65
+ readonly bodyHalfWidth?: number | undefined;
66
+ /** Parts detached from the main body shell, which produced the "tyres on stalks" failure. */
67
+ readonly detachedPartCount?: number | undefined;
68
+ /** Lowest Y of the asset in its own units, used for grounding confidence. */
69
+ readonly minY?: number | undefined;
70
+ /**
71
+ * Declared forward axis from the asset's own manifest, if it states one.
72
+ *
73
+ * `undefined` means *not declared*, which admission reports as `unproven` rather than guessing. A vehicle
74
+ * placed backwards on a track is a visible defect that geometry cannot rule out: a symmetric body has no
75
+ * intrinsic front, so this has to come from manifest evidence or an explicit override.
76
+ */
77
+ readonly forwardAxis?: readonly [number, number, number] | undefined;
78
+ /**
79
+ * Whether the front and rear of the asset are distinguishable from geometry, e.g. a longer overhang or an
80
+ * asymmetric wheelbase. Separate from `forwardAxis`: this says the inference is *possible*, not which way.
81
+ */
82
+ readonly frontRearDistinguishable?: boolean | undefined;
83
+ /** Horizontal distance from the asset origin to its bounds centre, as a fraction of its longest axis. */
84
+ readonly pivotOffsetRatio?: number | undefined;
85
+ /** Mesh parts carrying no material assignment. A part with no material has no shader to draw with. */
86
+ readonly partsWithoutMaterial?: number | undefined;
87
+ }
88
+ /** Rendered evidence, supplied by a browser probe. Never inferred from geometry. */
89
+ export interface AssetRenderedFacts {
90
+ /** Path to the retained screenshot the verdict is bound to. */
91
+ readonly screenshotPath?: string | undefined;
92
+ /** Whether a retained render shows readable wheels. `undefined` means not measured. */
93
+ readonly renderedWheelVisibility?: boolean | undefined;
94
+ /** Camera azimuths the render covered, in radians. A single head-on angle proves little. */
95
+ readonly renderedAzimuths?: readonly number[] | undefined;
96
+ }
97
+ export interface AssetProvenanceFacts {
98
+ readonly license?: string | undefined;
99
+ readonly author?: string | undefined;
100
+ readonly sourcePage?: string | undefined;
101
+ readonly provider?: string | undefined;
102
+ }
103
+ /** What the caller needs from the asset, expressed as intent rather than thresholds. */
104
+ export interface AssetRoleRequirement {
105
+ readonly role: AssetAdmissionRole;
106
+ /** Require exposed, visually readable wheels. Meaningless for a closed-wheel prototype. */
107
+ readonly requireReadableWheels?: boolean | undefined;
108
+ /** Require textures rather than flat colour. */
109
+ readonly requireTextured?: boolean | undefined;
110
+ /** Maximum triangle budget for the role. */
111
+ readonly maxTriangles?: number | undefined;
112
+ /** Minimum triangle count, used to reject distant-prop shells from hero use. */
113
+ readonly minTriangles?: number | undefined;
114
+ /** Require complete license/author provenance. */
115
+ readonly requireProvenance?: boolean | undefined;
116
+ /**
117
+ * Require orientation evidence rather than accepting an unoriented asset.
118
+ *
119
+ * The brief is explicit that a route must be able to "reject if required orientation evidence is absent".
120
+ * Off by default because a rock or a tree has no meaningful forward axis; a vehicle or character does.
121
+ */
122
+ readonly requireOrientationEvidence?: boolean | undefined;
123
+ }
124
+ export interface AssetAdmissionInput {
125
+ readonly assetId: string;
126
+ readonly requirement: AssetRoleRequirement;
127
+ readonly geometry: AssetGeometryFacts;
128
+ readonly rendered?: AssetRenderedFacts | undefined;
129
+ readonly provenance?: AssetProvenanceFacts | undefined;
130
+ }
131
+ export interface AssetAdmissionReport {
132
+ readonly schema: "aura3d-asset-role-admission/1.0";
133
+ readonly assetId: string;
134
+ readonly role: AssetAdmissionRole;
135
+ readonly checks: readonly AssetAdmissionCheck[];
136
+ /** `true` only when no check failed **and** no required check is unproven. */
137
+ readonly admitted: boolean;
138
+ /** Machine-readable rejection reasons, `<check-id>:<detail>`. Empty when admitted. */
139
+ readonly blockers: readonly string[];
140
+ /** Checks that could not be decided. A non-empty list forbids `admitted: true`. */
141
+ readonly unproven: readonly string[];
142
+ /** Roles this asset would satisfy instead, so a rejection is actionable. */
143
+ readonly suitableAlternativeRoles: readonly AssetAdmissionRole[];
144
+ }
145
+ /** Minimum distinct outboard corners for a vehicle to count as wheeled. */
146
+ export declare const MIN_VEHICLE_WHEEL_CORNERS = 3;
147
+ /** Below this triangle count an asset is a distant prop, not a hero subject. */
148
+ export declare const HERO_MIN_TRIANGLES = 3000;
149
+ /**
150
+ * A hero render must cover at least this many distinct azimuths.
151
+ *
152
+ * One angle is not evidence: the `turboRaceCar` release probe rendered a dead-on front view (camera
153
+ * azimuth and node rotation cancelled exactly), which is the single angle where a car's own bodywork
154
+ * hides its wheels. That frame was read as "the renderer is dropping the wheel primitives" when in
155
+ * fact all five primitives were drawing. Requiring multiple angles makes that mistake impossible.
156
+ */
157
+ export declare const HERO_MIN_RENDERED_AZIMUTHS = 2;
158
+ /**
159
+ * Evaluate an asset against a requested role.
160
+ *
161
+ * Returns every check individually. Callers must not reduce this to a boolean without also surfacing
162
+ * `blockers` and `unproven`, or the "asset loads, therefore asset is fine" failure returns.
163
+ */
164
+ export declare function admitAssetForRole(input: AssetAdmissionInput): AssetAdmissionReport;
165
+ /**
166
+ * Rank candidates for a role, best first.
167
+ *
168
+ * Admitted candidates always outrank rejected ones; within each group, fewer blockers then fewer
169
+ * unproven checks then more triangles wins. Rejected candidates are **retained**, with their reasons,
170
+ * because a screening loop needs to report why every candidate failed rather than silently discarding
171
+ * them.
172
+ */
173
+ export declare function rankAssetCandidatesForRole(inputs: readonly AssetAdmissionInput[]): readonly AssetAdmissionReport[];
174
+ //# sourceMappingURL=asset-role-admission.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"asset-role-admission.d.ts","sourceRoot":"","sources":["../../../../packages/aura3d-cli/src/asset-role-admission.ts"],"names":[],"mappings":"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"}