From cb98d82023d4b3c248874d6404875cdf4e3ce71d Mon Sep 17 00:00:00 2001 From: SoftFever Date: Sun, 20 Sep 2026 22:36:45 +0800 Subject: [PATCH] Document filament compatibility specificity and preset naming conventions --- .claude/skills/orca-profiles/SKILL.md | 6 +- .../references/filament-profiles.md | 51 ++++++++++++++++ .../skills/orca-profiles/references/naming.md | 60 +++++++++++++++++++ .../references/review-checklist.md | 15 ++++- .../orca-profiles/references/validation.md | 2 +- 5 files changed, 130 insertions(+), 4 deletions(-) create mode 100644 .claude/skills/orca-profiles/references/naming.md diff --git a/.claude/skills/orca-profiles/SKILL.md b/.claude/skills/orca-profiles/SKILL.md index 692e529074..bb755d12fa 100644 --- a/.claude/skills/orca-profiles/SKILL.md +++ b/.claude/skills/orca-profiles/SKILL.md @@ -21,6 +21,7 @@ Paths below are relative to this skill. Commands run from the repository root. | Add a printer or nozzle; change models, variants, assets or extruder vectors | [machine-profiles.md](references/machine-profiles.md) | | Add a quality tier or tune a process | [process-profiles.md](references/process-profiles.md) | | Create a vendor bundle; diagnose loading or inheritance; migrate preset names | [vendor-bundle.md](references/vendor-bundle.md) | +| Name a preset; check what a name must equal | [naming.md](references/naming.md) | | Change ids; diagnose AMS identity | [ids.md](references/ids.md), then `docs/HLSD/filament_id.md` for identity changes | | Review a profile diff | [review-checklist.md](references/review-checklist.md) | | Run checks, interpret failures, test another tree or verify in the app | [validation.md](references/validation.md) | @@ -44,7 +45,10 @@ Paths below are relative to this skill. Commands run from the repository root. update in-tree references too. See [migration rules](references/vendor-bundle.md#renamed_from). 6. **Compatibility uses exact printer variant names.** Every instantiated non-library filament needs a non-empty `compatible_printers` in its own file. Library fallbacks may omit it; - library printer-specific tunes use a non-empty list. Keep same-product tunes disjoint. + library printer-specific tunes use a non-empty list. One variant may be claimed by only one + profile per filament product (`filament_id`); an overlap is resolved by moving the variant to the + most specific preset, which is preferred over deleting a profile. See + [one variant, one profile](references/filament-profiles.md#overlapping-coverage-one-variant-one-profile-per-product). 7. **Preset values are strings or arrays of strings.** Use `"instantiation": "false"`, not `false`. Model `nozzle_diameter` is a `;`-separated string; machine `nozzle_diameter` is an array. Wrong types can abort loading; see [failure scopes](references/vendor-bundle.md#failure-modes-ranked-by-blast-radius). diff --git a/.claude/skills/orca-profiles/references/filament-profiles.md b/.claude/skills/orca-profiles/references/filament-profiles.md index b3f6acd4c4..d6679d9122 100644 --- a/.claude/skills/orca-profiles/references/filament-profiles.md +++ b/.claude/skills/orca-profiles/references/filament-profiles.md @@ -103,6 +103,57 @@ name. - Copying a base's full printer list onto a nozzle-specific variant produces duplicate combobox entries — a real shipped bug twice over. +## Overlapping coverage: one variant, one profile per product + +`filament_id` is the **product** key, not the preset key — every variant of one product shares it +(`//`). So if one printer variant appears in the +`compatible_printers` of two presets of that product, the slicer cannot tell them apart at AMS match time. +The C++ validator reports `Ambiguous AMS filament match: N presets share filament_id "X" … printer "Y"`. +`orca_profile_tool.py check` does **not** see it and passes. Resolve the overlap by **specificity**: keep +the variant on the most specific profile and remove it from every more general one. Deleting a profile is +the least preferred fix — moving coverage keeps the tune that users rely on. + +Judge specificity from the profile's `compatible_printers` — how many variants it actually covers — and +use the name only as a secondary, easily-vague hint; decide by the lists, with a best judgement call on +the name. Naming conventions differ by vendor: BBL's is the reference (`@ ` for a whole +model, `@ nozzle` for one variant, `@` for a vendor-wide generic), but +others vary (`@`, a printer serial, or Creality's `@-all`). A name never overrides +the list — see [preset naming](naming.md) for the shapes. + +Specificity, most to least: + +1. **Variant-specialized** — lists a single printer variant (BBL-style + `... @ nozzle`). +2. **Model-specialized** — lists the variants of one printer model (BBL-style `... @ `). + It should cover every variant of its model, not only the nozzle it was authored for. +3. **Family / series** — lists variants spanning a printer family or series. +4. **Generic / catch-all** — vendor-wide, covering many unrelated models (often the bare + `Generic @`). + +Rules: + +- A model-specialized profile is extended to **all** variants of its model, and each variant it thereby + starts covering is removed from the family and generic profiles that also listed it — including variants + that had no overlap before. Apply it per nozzle, not just 0.4. +- Apply it **per product**: trim only the material that has a specialized profile from the generic; a + material whose product has no specialized profile keeps the variant in the generic. +- Never strip coverage a variant has nowhere else to get. If a variant has no variant-level specialized + profile, the next level down keeps it; when the model has specialized profiles, the model-level one wins + over the family/generic. +- Moving coverage is preferred over deleting. If a profile must be deleted, remove the more general + one, not the specialized profile that carries the tune. +- After moving coverage, repoint the affected `default_filament_profile` (machine) and clean the model's + `default_materials`: they should name the most specific profile that covers the variant, and should not + keep generic entries that no longer cover the model. This rule applies equally when adding or fixing + defaults. + +Multiple profiles of one product with **disjoint** `compatible_printers` is the intended end state. +Adding coverage to the specialized profile and removing it from the generic is the preferred direction. + +**Detection caveat:** `orca_profile_tool.py check` is blind to this; only the C++ validator behind the full +`./scripts/check_profile.sh` reports it (`validate_system`). Always confirm with that, not the vendor-scoped +loop. + ## Alias shadowing A printer-specific filament in either the library or a vendor bundle supersedes the library fallback diff --git a/.claude/skills/orca-profiles/references/naming.md b/.claude/skills/orca-profiles/references/naming.md new file mode 100644 index 0000000000..502863f0c4 --- /dev/null +++ b/.claude/skills/orca-profiles/references/naming.md @@ -0,0 +1,60 @@ +# Preset naming + +A preset's `name` is the loader's key, not decoration. The index registers it; `inherits`, +`compatible_printers` and the `default_*` keys reference it by the exact string; `renamed_from` depends +on it; and `setting_id` / `filament_id` hash it (see [ids.md](ids.md)). Two presets of one type in a +bundle may not share a name (`check_preset_name_uniqueness`). Treat a name change as an identity change, +not a relabel. + +Naming is convention only where the loader does not parse it. What the loader actually acts on: + +| Type | Shape | Acted on | +| --- | --- | --- | +| `machine_model` | `` | the exact string, named by a variant's `printer_model` | +| `machine` | ` nozzle` | the exact string, named by `compatible_printers`; `printer_variant` must equal a nozzle diameter | +| `process` | `mm @` | the exact string when referenced or selected; the `@` half is a label | +| `filament` | ` @` | text before the first `@` is the **alias**, used for shadowing; the rest is a label | + +## `machine_model` + +`` — the vendor-prefixed model name (`Bambu Lab X1 Carbon`, `Creality K1`, `Prusa CORE One`). A +variant names it verbatim in `printer_model`; a mismatch makes the variant invalid. `check_name_consistency` +forces the index entry to equal the file's `name`, and the variant's `printer_model` targets this string +([A `machine_model` is not a config preset](machine-profiles.md#a-machine_model-is-not-a-config-preset)). +It is also the `_cover.png` and bed-asset stem. + +## `machine` (variant) + +` nozzle` is near-universal (`Bambu Lab X1 Carbon 0.4 nozzle`). `printer_variant` holds +the bare nozzle (`0.4`) and must be an exact member of the model's `nozzle_diameter` list — the hard +rules are in [The `machine` variant](machine-profiles.md#the-machine-variant). Casing varies +(`nozzle` / `Nozzle`): match the bundle, not this page. A variant that is not nozzle-specific (a special +toolhead, a multi-material build) may drop the suffix — still an exact reference. Bases are named +`fdm_machine_common` / `fdm__common`. + +## `process` + +`mm @` — [process-profiles.md](process-profiles.md#naming) has the +quality ladder and the `fdm_process_*` base names. The `@` is a human label, not a reference: it +usually does not equal a real variant, and compatibility comes from the resolved `compatible_printers` +list or condition. + +## `filament` + +` @`. The product half is what `filament_id` hashes and what survives as the **alias** up +to the first `@`; the target half is a label except for reserved forms: + +- `@base` — a non-instantiated product root. `@base` is convention; a base is really identified by + `instantiation: "false"` and no `setting_id` ([the three-part shape](filament-profiles.md#the-three-part-shape)). +- `@System` — the OrcaFilamentLibrary selectable shim. The literal `Generic @System` is + load-bearing for 3MF/project recovery, beyond the alias rule ([alias shadowing](filament-profiles.md#alias-shadowing)). +- `@`, `@ `, `@ nozzle` — printer tunes, BBL's shape. + Other vendors differ (a bare model, a printer serial, Creality's `@-all`). Specificity is judged + from `compatible_printers`, not the name + ([one variant, one profile](filament-profiles.md#overlapping-coverage-one-variant-one-profile-per-product)). + +## Not the same as the filename + +The loader keys off `name`, and a filename that disagrees usually still loads. Index `name` must equal the +file's `name`, and the filename should match `sub_path`; a mismatch that differs only in case breaks +another platform ([cross-platform paths](validation.md#cross-platform-paths)). diff --git a/.claude/skills/orca-profiles/references/review-checklist.md b/.claude/skills/orca-profiles/references/review-checklist.md index 0c4fa7e95a..43dc5091f8 100644 --- a/.claude/skills/orca-profiles/references/review-checklist.md +++ b/.claude/skills/orca-profiles/references/review-checklist.md @@ -79,8 +79,15 @@ and written in the preset's own file — golden rule 6, with the flattened-vs-ow inherited or copied the base's full printer list, and for two presets of one product with overlapping lists — duplicate combobox entries and an ambiguous AMS match. +Two presets of one product (`filament_id`) must not share a variant. Resolve it by specificity: move the +variant to the most specific preset and remove it from the more general ones — preferred over deleting a +profile. Then repoint the machine's `default_filament_profile` and the model's `default_materials` at the +profile that now covers it. See +[one variant, one profile](filament-profiles.md#overlapping-coverage-one-variant-one-profile-per-product). + *Why:* real shipped bugs twice (`b7b3418baf` "showing up everywhere", `ff83aa41ef` duplicate Flashforge -entries). +entries). The Python `check` passes on an overlap; only the full `check_profile.sh` (`validate_system`) +reports `Ambiguous AMS filament match`. ## 6. Model ↔ variant ↔ process consistency @@ -128,7 +135,11 @@ numbers nobody measured. ## 11. `default_materials` (checked by CI) `check` fails on a `default_materials` / `default_filament_profile` name that resolves to no system -filament, so a dangling entry no longer reaches review. Scope the run while working on one vendor: +filament, so a dangling entry no longer reaches review. When compatibility moves between profiles of a +product, the machine's `default_filament_profile` and the model's `default_materials` must be repointed at +the most specific profile that still covers the variant, dropping generic entries that no longer apply — +the same [specificity rule](filament-profiles.md#overlapping-coverage-one-variant-one-profile-per-product) +applies when adding or fixing defaults. Scope the run while working on one vendor: ```bash python3 scripts/orca_profile_tool.py check --vendor "" # py -3 on Windows diff --git a/.claude/skills/orca-profiles/references/validation.md b/.claude/skills/orca-profiles/references/validation.md index 497e1d4e18..aa2a7d348d 100644 --- a/.claude/skills/orca-profiles/references/validation.md +++ b/.claude/skills/orca-profiles/references/validation.md @@ -223,7 +223,7 @@ Keep stems tidy too, but a space immediately before `.json` is not a trailing pa | `references unknown compatible_printers "

"` | the printer was renamed or deleted; fix the reference | | `references renamed compatible_printers "" (now "")` | in-tree references must name the current preset; `renamed_from` does not excuse them | | `Filament preset "" is missing compatible_printers setting` | non-library filaments need a non-empty list in their **own** file — the flattened-vs-own-key trap is in [filament-profiles.md](filament-profiles.md#compatible_printers) | -| `Ambiguous AMS filament match: N presets share filament_id "X" … printer "Y"` | make the lists disjoint, or fix an `inherits` pointing at another material's `@base` | +| `Ambiguous AMS filament match: N presets share filament_id "X" … printer "Y"` | make the lists disjoint by [specificity](filament-profiles.md#overlapping-coverage-one-variant-one-profile-per-product) — the specialized profile keeps the variant, the general ones drop it; prefer this over deleting a profile — or fix an `inherits` pointing at another material's `@base`. `orca_profile_tool.py check` does not catch this; only `validate_system` here does | | `Layer height cannot exceed nozzle diameter.` / `Line width too small` | `Print::validate()` flow rules | | `[ERROR] … no .json list references it, so it never loads` | `update-index`, or delete the file | | `[ERROR] … references it and it declares no profile type` | set the correct `type` explicitly, then `normalize` and `update-index` |