Two blind spots made the detector miss real breakages.
1. Comparing « mode » is not the right test. What decides the shape an arch
must have is whether the target declares an inherit_id: with one, the arch
must be inheritance specs (<data>, <xpath>, position=); without one, it must
be a standalone template. A view moving from a root template to
« inherit_id + primary="True" » keeps mode='primary' on BOTH sides, so the
old test reported nothing while the copy still broke. The comparison is now
(target declares inherit) vs (stored arch is spec-shaped), and each finding
carries the reason. A mode change with a matching shape is still reported,
as a lesser warning.
arch_db is read as text up to 15.0 and as jsonb from 16.0; both are handled.
2. A module renamed upstream was reported as « module absent », hiding every
view it owns. renamed_modules is now read from the target OpenUpgrade
apriori.py (21 entries for 13.0, 56 for 14.0, 39 for 16.0, 20 for 18.0) and
used before concluding the module is gone.
Also correct the advice printed for a copy at risk: deactivating it is not
enough, an inactive copy keeping the same key still shadows the module view.
Renaming the key is what actually unpairs it.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>