-
2026-08-24 —
PackageManager.install_targeted: resolver-aware install into a directory an embedded host imports from (core_utils/package_manager.py). For interpreters embedded in a DCC (Blender's bundled python, mayapy) whose safe landing zone is a plain directory on the host'ssys.pathrather than site-packages. A naivepip install --targetis the trap it replaces:--targetplans a COMPLETE standalone closure, ignoring what the interpreter ships, so it happily installs a newer numpy over the host's bundled one (measured: it planned numpy 2.5.2 over Blender 5.1's bundled 2.3.4). Instead pip's own resolver produces the plan (--dry-run --report— interpreter-aware, sees the bundled site-packages) and only the reported set is applied with--no-deps --upgrade --target. Planning runs under-sso a user-site dist the HOST never reads cannot count as satisfied, and the target dir rides PYTHONPATH so prior targeted installs make re-runs no-ops. Returns thename==versionpins actually applied. The report file goes throughTempArtifacts. Backs blendertk'sensure_packages, tentacle's Blender Qt bootstrap, and the sharedpackage-manager.bat's targeted mode.test_package_manager+4. -
2026-08-23 —
OutputTemplates.profile_outline/.profile_outlines: a workflow profile can now describe what it WRITES, not just which engine it is for (core_utils/engines/textures/output_template.py).profile_choiceshands every preset combo in the ecosystem one paragraph of prose, which answers "which profile is right for me" and nothing about the thing a user is actually choosing — the files they will get.profile_outline(name)returns a document outline (title/body/sections/notes) whose Writes section names each output and what it carries: every packed map the profile declares with its channel layout read verbatim fromMapType.channels(<name>_ORM.tga — R: Ambient Occlusion · G: Roughness · B: Metallic, MSAO's filler Detail channel marked optional), the maps it deliberately keeps loose, and the normal-map handedness — the one thing a user has to match and the one thing a bare "DirectX" never said. Which maps a profile declares is derived the same wayget_workflow_presetsderives its flags (the map naming the workflow), so the tooltip and the resolved config cannot disagree.delivery=True(default) also resolves each filename's real container through the profile's template and adds a Delivery section (containers, the 16-bit height-like override, the advisory size ceiling, POT);delivery=Falseis for a panel that does NOT pass the profile asoutput_profile— naming TGA under Unreal there would be a promise the run does not keep. Rendering stays with the caller because the palette belongs upstream: the returned keys are exactly what uitk'sTooltipFormat.fmttakes as**kwargs. Registry prose and the caller'sbase_nameare HTML-escaped; only<b>/<i>are added. A listed packed map is presented as a REQUEST, not a guarantee, because that is what it is:BaseColorHandlerpacks Albedo_Transparency only when the set carries real transparency ("we keep it as Base_Color to avoid misleading filenames") andMetallicSmoothnessHandlersaves a loose Metallic when no smoothness resolves, so a flat listing would promise the common opaque set a file the run never writes; the transparency caveat is derived from the pack's channels carrying Opacity rather than matched on a name, so Spec/Gloss is not told about transparency it never handles. The Missing Maps rule is deliberately NOT cited — only the ORM / MRAO / MSAO handlers consultallow_incomplete_pack, and that control documents itself in the panel. An unknown profile yields an EMPTY outline rather than one built from the default template: there is nothing truthful to say about what a profile that does not exist writes.profile_choicesis unchanged — existing callers keep the plain-text description.test_output_template+20 (incl. markup-balance, normal-handedness coverage and the two conditional-pack guards, each checked against its own defect).