Skip to content

fix: netbox-branching 1.1.1 compat + endpoint identity clamping (2.4.5)#46

Merged
captainpacket merged 2 commits into
mainfrom
fix/branching-111-compat-endpoint-identity
Jul 9, 2026
Merged

fix: netbox-branching 1.1.1 compat + endpoint identity clamping (2.4.5)#46
captainpacket merged 2 commits into
mainfrom
fix/branching-111-compat-endpoint-identity

Conversation

@captainpacket

Copy link
Copy Markdown
Collaborator

Problem (field report, design partner on 2.4.4)

  1. Sync failed: type object 'SquashMergeStrategy' has no attribute '_split_bidirectional_cycles' — netbox-branching 1.1.1 (released; our dependency was unbounded >=1.1.0) removed that internal helper (and _has_fk_to); our bulk merge called it unconditionally.
  2. 18 ingestion issues: endpoint rows carry raw SNMP sysDescr as device_type — up to 251 chars vs NetBox's 100-char DeviceType model/slug limits, plus one symbol-only sysDescr slugifying to "" (At least one coalesce lookup must be provided).

Changes

  • Vendored _split_bidirectional_create_cycles + _create_has_fk_to (faithful 1.1.0 mirror incl. GenericForeignKey cycle detection); prefer the framework helper when present (1.1.0 bit-identical); guard _log_cycle_details; tests tolerate either branching version (create=True patches, skip-if-absent).
  • Bound the dependency: netboxlabs-netbox-branching >=1.1.0,<1.2.0 — internals are borrowed by design, so future churn should fail at install, not mid-merge.
  • Clamp device-row identity: _sanitize_device_rows clamps device_type/manufacturer/platform/role/site + slugs to 100 chars, recomputes the slug from the clamped value (deterministic — no DeviceType churn), falls back to unknown for degenerate slugs; applied in _apply_device_tag_scope and on every _fetch_spec_rows exit so fetch-artifact cache hits (resumed runs) are clean too. Device names never modified.

Verification

  • Adversarial (codex) review ran twice; all four findings fixed (cache-hit bypass, 1.1.1-incompatible tests, missing GFK handling, slug divergence).
  • Compat test deletes the framework attribute to simulate 1.1.1 and proves ordering still breaks a real Device↔VirtualChassis bidirectional CREATE pair.
  • Full suite 1001 OK + lint + harness green.

netbox-branching 1.1.1 removed SquashMergeStrategy._split_bidirectional_cycles
(and _has_fk_to); the bulk merge called it unconditionally, so a fresh install
resolving the unbounded >=1.1.0 dependency to 1.1.1 died mid-sync with an
AttributeError. The bidirectional-cycle splitter is now vendored (faithful
mirror of the 1.1.0 idiom including GenericForeignKey cycle detection); the
framework helper is preferred when present so 1.1.0 behavior is unchanged, and
the dependency is bounded to >=1.1.0,<1.2.0 so future internal churn fails at
install time rather than mid-merge. _log_cycle_details is guarded the same way
and tests tolerate either branching version.

Endpoint rows carry raw SNMP sysDescr as device_type, which exceeds NetBox's
100-char DeviceType model/slug limits (observed 251 chars -> 18 per-row
"Ensure this value has at most 100 characters" rejects) and can slugify to ""
("At least one coalesce lookup must be provided"). Device-row taxonomy fields
are now clamped to 100 chars with deterministic slug recomputation and
fallbacks, applied on every fetch exit including fetch-artifact cache hits so
resumed runs replay clean rows. Device names are never modified.

Full suite (1001) + lint + harness green.
Maintainer decision: NQE is the source of truth — the plugin must not
normalize or mutate query rows. Replace the Python _sanitize_device_rows
mutation with query-side clamping in both endpoint branches: device_type =
substring(sysDescr, 0, 100), slug clamped after slugifyNetboxModel (which can
EXPAND the string past 100 — live-verified 124 -> 100), and explicit fallbacks
for empty slugs/manufacturers. Because the queries changed, operators publish
bundled queries after upgrading; the release notes and version tables say so.

Live-validated on ADP: both device queries emit max(model)=100 max(slug)=100
with zero empty slugs across 5645 rows / 685 endpoints. Full suite (997) +
lint + harness + NQE lint green.
@captainpacket captainpacket merged commit d384c4d into main Jul 9, 2026
2 checks passed
@captainpacket captainpacket deleted the fix/branching-111-compat-endpoint-identity branch July 9, 2026 18:05
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant