mirror of
https://github.com/OrcaSlicer/OrcaSlicer.git
synced 2026-08-24 10:27:35 +00:00
plan v3: OFL as the catalog, content-addressed product ids
Revises the v1 mint rule after the maintainer catch that its key scoped families to the profile bundle (printer brand), fragmenting one commercial product into N ids (PolyLite PLA: five bundles, all filament_vendor "Polymaker", up to five ids). Architecture: BBL and QD_* stay frozen islands; OrcaFilamentLibrary becomes the single declaration point for every other material family; vendor bundles carry only same-alias specializations (no filament_id key) that shadow the OFL preset per printer and resolve its id through the loader walk. New mint key: uuid5 over "filament_product/<filament_vendor>/<filament_type>/<family_name>" from the root's flattened config — bundle-independent (hoisting families into OFL is id-stable), and the type component keeps the four known same-name- different-type groups apart until their data bugs are fixed. Content-addressing replaces "ids immutable once shipped": identity edits re-id the family, made safe by turning retired_filament_ids.json into a shipped succession ledger (old id -> successor, chains allowed, cross-island hints permitted) consulted on resolution miss in the AMS sync and lookup paths. The MoonrakerPrinterAgent hardcoded generic-id map is replaced by a runtime preset lookup, removing the code/profile lockstep. Migration: v3.0 tooling + W1 client hardening + W3 type fixes; v3.1 OFL re-mint with succession entries; v3.2 vendor bundles (391 unshipped OF ids re-derive without retirement; generic tunings re-point to OFL; ~800 shipped legacy ids re-mint with succession, incl. the 57 multi-vendor GF residue and the 10 P-hex system ids, which also exits them from the destructive check_ams_filament_valid P-gate); v3.3 optional id-stable consolidation into OFL. Gate battery unchanged plus succession-resolution tests. filament_id_plan_v2.md gets a status note: its P+md5 verdict stands; its work items are absorbed or superseded by v3.
This commit is contained in:
@@ -1,5 +1,9 @@
|
||||
# filament_id plan v2: the `get_filament_id` (P+md5) proposal, validated
|
||||
|
||||
> **Status note:** the verdict in §0-§4 and §7-§8 stands. The work items in §5 are
|
||||
> superseded by `filament_id_plan_v3.md` (OFL-as-catalog, content-addressed triple key,
|
||||
> succession ledger): W1/W3 are carried into v3.0, W2/W5 carry unchanged, W4 is dropped.
|
||||
|
||||
Follow-up to `filament_id_plan.md` (v1, implemented on `feature/filament_id`: deterministic
|
||||
`OF*` mint + snapshot ledger + 30-vendor migration, tree-wide validator `-f` = 0).
|
||||
|
||||
|
||||
203
filament_id_plan_v3.md
Normal file
203
filament_id_plan_v3.md
Normal file
@@ -0,0 +1,203 @@
|
||||
# filament_id plan v3: OFL as the catalog, content-addressed product ids
|
||||
|
||||
Supersedes §5 of `filament_id_plan_v2.md` (whose P+md5 verdict stands unchanged) and
|
||||
revises the mint rule of `filament_id_plan.md` (v1, implemented on `feature/filament_id`).
|
||||
Decision driver: v1's mint key scoped families to the *profile bundle* (printer brand), so
|
||||
one commercial product tuned in N bundles carries N ids — e.g. PolyLite PLA ships in five
|
||||
bundles (`BBL`, `OrcaFilamentLibrary`, `OrcaArena`, `Qidi`, `Snapmaker`), all with
|
||||
`filament_vendor: "Polymaker"`, under up to five different ids (`GFL00`, `OFceJcLf`, …).
|
||||
That contradicts what `filament_id` means: one id per commercial product line.
|
||||
|
||||
## 0. The architecture
|
||||
|
||||
Three tiers, two frozen islands:
|
||||
|
||||
1. **BBL island — untouched.** Bambu profiles keep their `GF*` catalog ids byte-for-byte
|
||||
(device/RFID/cloud contract). No convergence between GF and OFL ids is attempted: the
|
||||
same product may permanently carry `GFL00` on the BBL side and an `OF*` id everywhere
|
||||
else. This is a deliberate trade for simplicity; v2's curated-GF-adoption (old W4) is
|
||||
dropped.
|
||||
2. **`QD_*` island — untouched.** Qidi's box builds `QD_<series>_<vendor>_<type>` from
|
||||
device enums and requires exactly-matching presets (`QidiPrinterAgent.cpp:146-152`).
|
||||
Qidi presets carrying `QD_*` are exempt from re-minting, forever.
|
||||
3. **Everything else converges on OrcaFilamentLibrary.** OFL is the product catalog: a
|
||||
material family's id is declared once, on its OFL family root. Vendor bundles carry
|
||||
only per-printer *specializations* of OFL families — same base name, non-empty
|
||||
`compatible_printers`, **no `filament_id` key** — which (a) alias-shadow the OFL preset
|
||||
on the printers they claim (`Preset.cpp:3684-3714`: "Generic PLA @Qidi Q2 0.4mm nozzle"
|
||||
hides "Generic PLA @System" on that machine) and (b) resolve the OFL family's id
|
||||
through the loader's inherits/base-bundle walk (`PresetBundle.cpp:4842-5080`). Products
|
||||
OFL does not (yet) carry mint their id in the vendor bundle **with the same rule**;
|
||||
because the key is bundle-independent (§1), later hoisting the family into OFL never
|
||||
changes its id.
|
||||
|
||||
Convergence therefore happens by *single declaration point*, not by copying ids across
|
||||
bundles — no adoption registry, no cross-bundle id claims to curate.
|
||||
|
||||
## 1. The mint rule
|
||||
|
||||
```
|
||||
triple = (filament_vendor, filament_type, family_name) # from the family ROOT's flattened config
|
||||
key = "filament_product/<filament_vendor>/<filament_type>/<family_name>"
|
||||
id = "OF" + base62_6( uuid5( FILAMENT_ID_NAMESPACE, key ) ) # namespace unchanged:
|
||||
# c4d3ff49-4c32-5534-a3e3-00894157ab97
|
||||
```
|
||||
|
||||
- **Triple resolution.** All three values come from the family root preset's *flattened
|
||||
effective config* (`filament_vendor` and `filament_type` are inheritable list options —
|
||||
take the first element; family_name = the root's base name, `\s?@.*` stripped once).
|
||||
For own-key-layout families (no root), each declaring preset's flattened config is used
|
||||
and CI requires all declarers of one family to agree on the triple. A root that resolves
|
||||
an empty `filament_vendor` or `filament_type` is a CI error (generics use `"Generic"`).
|
||||
Values enter the key verbatim (UTF-8, no case folding).
|
||||
- **Bundle-independent by design.** The key contains no bundle name, so the same product
|
||||
yields the same id whether minted in OFL or in a vendor bundle; migrating a family into
|
||||
OFL (§0.3) is id-stable. Two bundles independently adding the same triple converge
|
||||
automatically — and that is correct, because equal (vendor, type, name) *is* the
|
||||
definition of "same product" here. The known look-alike hazards stay separated by the
|
||||
type component: the 4 same-name-different-type groups (Flashforge `Generic PLA Silk` as
|
||||
SILK, OFL `Generic PETG-CF` as PETG, `Generic PA6-CF`, `Generic PE-CF`) hash apart until
|
||||
their type bugs are fixed (§5, W3) and converge automatically after — self-healing that
|
||||
pure name-keying (rejected in v2) could not provide.
|
||||
- **Format and salt unchanged from v1**: 8 chars, `OF` + 6 base62; deterministic `/1`,
|
||||
`/2`… salt past any taken or retired id (the O+7 widening was evaluated and rejected:
|
||||
62⁶ expects 1.9×10⁻⁵ collisions at today's 1,455 families, and `^O.{7}$` would sweep 35
|
||||
legacy ids into the conformance gate vs. one today).
|
||||
- **Content-addressed, deliberately.** If any triple component changes — a family rename,
|
||||
a `filament_vendor` correction, a `filament_type` fix — the id changes with it. This
|
||||
*replaces* v1's "ids are immutable once shipped" with "ids are derivable from the
|
||||
product identity, and identity changes are migrations" — made safe by the succession
|
||||
ledger (§2). `renamed_from` still gates preset-name compatibility as before.
|
||||
- CLI: `--mint "Polymaker/PLA/PolyLite PLA"` prints without touching the tree; running
|
||||
the script plain inserts missing ids; CI errors print the expected id.
|
||||
|
||||
## 2. The succession ledger (the amendment that makes this safe)
|
||||
|
||||
Shipped ids are referenced outside the tree: AFC/Klipper lane data, Bambu AMS trays
|
||||
holding OFL-only materials, on-device PA-calibration records, user-root preset copies,
|
||||
3mf `slice_info`. Retiring an id without a forwarding pointer downgrades all of those to
|
||||
`Generic <type>` fallbacks. Therefore:
|
||||
|
||||
- **Schema.** `scripts/retired_filament_ids.json` entries become objects:
|
||||
`{"retired": {"OGFL99": {"claims": [...], "successor": "OFxxxxxx"}}}`. Append-only as
|
||||
before; a successor may itself be retired later (chains allowed, cycle-checked, and
|
||||
followed to the live end). A retired id may never be minted again (check 4 unchanged).
|
||||
Cross-island *hint* entries are permitted for ids Orca cannot retire because another
|
||||
island owns them (e.g. `GFL99 → <OFL Generic PLA id>`): consulted only when no live
|
||||
preset matches, so BBL installs still resolve `GFL99` natively first.
|
||||
- **Shipped and consulted at runtime.** The ledger ships in `resources/`; a small helper
|
||||
(`resolve_filament_id_succession(id)`) follows the chain and is consulted **only on
|
||||
resolution miss**, before the `Generic <type>` name fallback, in:
|
||||
`PresetBundle::get_filament_by_filament_id` (covers `DevFilaBlackList`, `SelectMachine`
|
||||
warnings, `Plater` tray configs in one place), the AMS sync match predicates
|
||||
(`PresetBundle.cpp:3151`, `:3252-3254` miss paths at `:3157-3169`/`:3260-3305`),
|
||||
`PresetComboBoxes::add_ams_filaments`, `MachineObject::setting_id_to_type`
|
||||
(`DeviceManager.cpp:2545` miss branch), calibration-history name lookup
|
||||
(`CaliHistoryDialog.cpp:62`), and the #14423 Moonraker lane matching when it lands.
|
||||
With this in place the OFL re-mint is near-residue-free and every future
|
||||
content-addressed rename stays safe.
|
||||
- **Kill the hardcoded generic map.** `MoonrakerPrinterAgent::map_filament_type_to_generic_id`
|
||||
(`MoonrakerPrinterAgent.cpp:608-658`) hardcodes 23 OFL ids (`OGFL99`… `OFLSBS99`).
|
||||
Replace it with a runtime lookup of the OFL generic preset by name ("Generic PLA
|
||||
@System" → its current id), removing the code↔profile lockstep permanently. (This also
|
||||
releases `OFLSBS99`, v2's one frozen OF-shaped legacy id, for normal re-minting.)
|
||||
|
||||
## 3. Validation rule changes
|
||||
|
||||
- **Check 3 (mint conformance)** becomes a pure function of the root's triple: a non-BBL,
|
||||
non-`QD_*` id must equal `mint(triple)` ± salt, or be snapshot-grandfathered (the
|
||||
grandfather set shrinks to ≈ nothing for non-BBL once migration completes).
|
||||
- **Check 5 (alias hygiene) generalizes and becomes load-bearing.** For *every*
|
||||
OFL-carried family (not just `Generic * @System`): a vendor specialization must keep the
|
||||
OFL base name (else the OFL preset un-shadows and creates a live per-printer duplicate —
|
||||
v1's P7 pattern) and non-empty `compatible_printers`, and must not declare an id. The
|
||||
C++ validator's OFL-aware `-f` (`PresetBundle.cpp:5674-5753`) already enforces the
|
||||
runtime consequence; the script check names the rename as the cause.
|
||||
- **New check 8 (triple integrity):** every id-declaring family resolves a complete,
|
||||
family-consistent triple; roots missing `filament_vendor`/`filament_type` error.
|
||||
- **New check 9 (succession integrity):** every retired entry's successor chain ends at a
|
||||
live tree id (or a documented cross-island hint target); no cycles; retired ids absent
|
||||
from the tree.
|
||||
- Snapshot mechanism, reserved spaces (`GF*`→BBL, `QD_*`→Qidi, `P`-hex/`null`→user-custom;
|
||||
v2's do-not-reserve-`OF*` note stands), and check 1/2/4/7 are unchanged.
|
||||
|
||||
## 4. Migration phases
|
||||
|
||||
**v3.0 — tooling + prerequisites (no profile changes).** New mint + triple resolver
|
||||
(reuse the flatten machinery), succession schema migration + C++ lookup helper wired into
|
||||
the §2 miss paths, Moonraker map → runtime lookup, checks 3/5/8/9, tests. Carry v2's W1
|
||||
client hardening (skip tray-wipe/temp-rewrite when a system preset holds the id; relax
|
||||
the `DeviceManager.cpp:5252` assert; guard the `PresetBundle.cpp:3717` deref) — it ships
|
||||
first regardless. **W3 type fixes land here**, *before* any re-mint: type is now a key
|
||||
component, so minting before fixing OFL `Generic PETG-CF`/`Generic PE-CF` would re-id
|
||||
those families twice.
|
||||
|
||||
**v3.1 — OFL re-mint.** Every OFL-declared id re-derives from its triple (mirrors like
|
||||
`OGFA00`, generics like `OGFL99`, blocks like `OEPLAB00` — all of it); each old shipped id
|
||||
gains a succession entry pointing at its replacement; the 26 BBL×OFL byte-shared ids
|
||||
dissolve (BBL keeps its id; the OFL family gets its own — two-island purity). Snapshot
|
||||
regenerated; full gate battery + fixture overlays (this phase touches preset-visibility
|
||||
machinery only via ids, but the fixtures are cheap insurance).
|
||||
|
||||
**v3.2 — vendor bundles, worksheet-per-vendor (v1 machinery).** Three sub-cases:
|
||||
(a) the **391 unshipped v1 `OF*` mints** re-derive under the triple key — no succession
|
||||
entries (they never shipped; a documented one-time `--forget-never-shipped <list>` drops
|
||||
them from the ledger lineage instead of retiring them, since the ledger's rationale —
|
||||
ids live on in user presets and 3mfs — cannot apply to unreleased ids);
|
||||
(b) **true generic tunings** riding copied legacy ids (`GFL99`-class) drop their own id
|
||||
and re-point to the OFL generic family (the v1 Sovol pattern) — their old ids get
|
||||
cross-island hints where BBL owns them, succession entries otherwise;
|
||||
(c) remaining **shipped legacy ids** (numeric, name-shaped, pseudo-GF, the 57
|
||||
multi-vendor GF residue, the 10 P-hex — everything non-BBL/non-`QD_*`, ~800 ids)
|
||||
re-mint with succession entries. Retiring the 10 P-hex system ids also removes the last
|
||||
system ids from `check_ams_filament_valid`'s destructive P-gate.
|
||||
|
||||
**v3.3 — ongoing consolidation (optional, per-vendor, id-stable).** Hoist vendor-unique
|
||||
products into OFL where a family is genuinely multi-vendor material; thanks to the
|
||||
bundle-independent key this never changes ids, so it can proceed opportunistically.
|
||||
|
||||
## 5. Gates (every phase)
|
||||
|
||||
`python scripts/orca_extra_profile_check.py` exit 0; `assign_filament_ids.py --check`
|
||||
exit 0; unit tests green (existing 46 + new triple/succession/adoption tests); validator
|
||||
`-l 2` exit 0, `-f` tree-wide exit 0, `-r` BBL+Qidi exit 0; custom-preset fixture
|
||||
archives; config-equivalence — flattened effective configs differ only in `filament_id`
|
||||
(re-mints), `inherits`/`compatible_printers` (re-points, as prescribed per worksheet), and
|
||||
the W3 `filament_type` corrections. New for v3: a C++ test that a retired id resolves
|
||||
through the succession chain in the sync miss path, and a Moonraker test that the generic
|
||||
map lookup matches the shipped OFL presets. Manual AMS smoke test (tray set → old-id
|
||||
resolve → clear) stays a release-checklist item.
|
||||
|
||||
## 6. Accepted costs (explicit)
|
||||
|
||||
- **GF ↔ OFL divergence is permanent** for products in both catalogs (PolyLite PLA ≠
|
||||
`GFL00` outside BBL). The forward-looking fix is PR #12724-style filament-database
|
||||
upload, where Orca ids become first-class device artifacts.
|
||||
- **Renames/type-fixes re-id families** (by design); the succession ledger absorbs the
|
||||
device/user residue, but each one is still a ledger entry and a snapshot diff to review.
|
||||
- **User roots** keep whatever id they copied at creation; with succession lookup in
|
||||
`get_filament_by_filament_id` they now *resolve* instead of dangling — strictly better
|
||||
than v1's accepted residue.
|
||||
- **One-time field transition**: devices holding pre-v3 ids (AFC lanes, AMS trays, cali
|
||||
records) resolve via succession on updated clients; *older* Orca versions and
|
||||
BambuStudio never resolved OFL-only ids anyway (`?`/generic fallback — unchanged for
|
||||
them).
|
||||
|
||||
## 7. Open decisions
|
||||
|
||||
1. Whether v3.2(b)'s cross-island hints (`GFL99` → OFL generic) are wanted at launch or
|
||||
deferred (pure-miss-path feature; zero risk to BBL installs, small review surface).
|
||||
2. v3.3 pacing: per-vendor PRs opportunistically vs. a dedicated consolidation train.
|
||||
3. Whether to fold v2's W5 (P+md5 ids for inherited *user* presets, PR #13315) into v3.0's
|
||||
C++ work or keep it a separate PR (recommended: separate; W1 is its only prerequisite).
|
||||
|
||||
## 8. Evidence
|
||||
|
||||
Carried from v2 §8 (all re-verified this session), plus: `filament_vendor` audit — 49
|
||||
distinct strings tree-wide, `"Polymaker"` byte-consistent across all five PolyLite-PLA
|
||||
bundles; multi-vendor different-family GF residue = 57 ids; `MoonrakerPrinterAgent.cpp:
|
||||
608-658` = 23 hardcoded OFL ids; mint examples verified live (`Qidi/PolyLite PLA` →
|
||||
`OFceJcLf` under the v1 key — the fragmentation this plan removes; salt determinism
|
||||
`OF8afiMO`). Alias shadowing and the OFL id fallback verified at `Preset.cpp:3684-3714`
|
||||
and `PresetBundle.cpp:4842-5080` during the v1 audit; per-printer `-f` semantics at
|
||||
`PresetBundle.cpp:5674-5753`.
|
||||
Reference in New Issue
Block a user