filament_id: deterministic mint rule, sanctioned-state ledger, validator hardening

Phase 0 of the filament_id cleanup (filament_id_plan.md):

- scripts/assign_filament_ids.py: mint OF-prefixed 8-char ids as
  uuid5(FILAMENT_ID_NAMESPACE, filament_family/<vendor>/<family>) in the
  base62 derivation of the setting_id precedent; loader-faithful effective-id
  resolver (vendor inherits chain + OrcaFilamentLibrary fallback); CLI:
  default assign run (idempotent no-op on a fully-idded tree),
  --mint Vendor/Family, --update-snapshot, --check.
- scripts/filament_id_snapshot.json: the sanctioned-state ledger (1092 ids,
  1965 family claims over the current tree). The tree must equal it exactly,
  both directions, so every id/claim change lands as a reviewable diff; a PR
  snapshot diff is the maintainer gate. scripts/retired_filament_ids.json is
  the append-only retirement ledger; --update-snapshot refuses to resurrect
  retired ids and to sanction new reserved-namespace claims (GF*/QD_*/P-hex/
  null) for non-owner vendors without --allow-shared-catalog.
- orca_extra_profile_check.py: runs check_filament_ids() tree-wide (format,
  snapshot equality, mint conformance, retired reuse, alias hygiene for tuned
  OFL generics, reserved namespaces, structure ratchet). The pre-existing
  check_filament_id() 8-char rule stays BBL/OFL-scoped: grandfathered longer
  ids exist elsewhere (e.g. Prusa's 36-char name ids) and are frozen via the
  snapshot instead.
- PresetBundle::check_duplicate_filament_subtypes now includes
  OrcaFilamentLibrary presets in every vendor's per-printer duplicate check;
  alias-shadowed library presets are excluded via the existing
  m_excluded_from population (verified live in the validator load path), so
  only genuinely visible duplicates are flagged. AMS tray-id resolution logs
  a warning when a filament_id matches 2+ compatible presets (pick unchanged).
- doc/developer-reference/filament_id.md: the authoring rule; PR template
  gains a no-hand-written-ids checkbox.
- scripts/tests/test_filament_id.py: 46 stdlib-unittest tests (mint vectors,
  resolver semantics, every check firing/silent, ledger round-trips, byte
  preservation, real-tree smoke).

Verified: python -m unittest discover -s scripts/tests (46 OK);
python scripts/orca_extra_profile_check.py exit 0 on the unmigrated tree;
assign run is a no-op; rebuilt OrcaSlicer_profile_validator -l 2 exit 0;
extended -f is strictly additive vs baseline (every baseline group preserved,
all new groups involve library presets, alias exclusion proven by BBL-mirror
absence on BBL printers).
This commit is contained in:
SoftFever
2026-07-02 23:17:15 +08:00
parent 051cdd4560
commit 1482fb81fd
9 changed files with 9561 additions and 5 deletions

View File

@@ -4,6 +4,7 @@ import argparse
from pathlib import Path
from assign_vendor_setting_ids import generate_preset_setting_id
from assign_filament_ids import check_filament_ids
OBSOLETE_KEYS = {
"acceleration", "scale", "rotate", "duplicate", "duplicate_grid",
@@ -288,6 +289,12 @@ def check_name_consistency(profiles_dir, vendor_name):
def check_filament_id(vendor, vendor_folder):
"""
Make sure filament_id is not longer than 8 characters, otherwise AMS won't work properly
NOTE: superseded by check_filament_ids (assign_filament_ids.py) for non-BBL/OFL
vendors, which validates format/uniqueness/structure tree-wide against the
grandfather snapshot. This length check stays scoped to BBL/OFL because other
vendors ship grandfathered >8-char ids (e.g. Prusa's 36-char name-ids), so it
cannot simply go tree-wide.
"""
if vendor not in ('BBL', 'OrcaFilamentLibrary'):
return 0
@@ -606,6 +613,11 @@ def main():
# Runs once over the whole tree regardless of the --vendor filter.
errors_found += check_setting_id_uniqueness(profiles_dir)
# Global filament_id check (see scripts/assign_filament_ids.py): effective ids
# are resolved loader-faithfully and validated against the sanctioned snapshot
# (scripts/filament_id_snapshot.json). Runs once over the whole tree.
errors_found += check_filament_ids(profiles_dir)
# ✨ Output finale in stile "compilatore"
print("\n==================== SUMMARY ====================")
print_info(f"Checked vendors : {checked_vendor_count}")