Skip to content

Fix compound metadata removal without restart - #7583

Open
laritakr wants to merge 5 commits into
mainfrom
fix-compound-removal-without-restart
Open

Fix compound metadata removal without restart#7583
laritakr wants to merge 5 commits into
mainfrom
fix-compound-removal-without-restart

Conversation

@laritakr

@laritakr laritakr commented Aug 13, 2026

Copy link
Copy Markdown
Contributor

Summary

Fix compound metadata removal without restart. If an app is booted with flexible metadata and includes compound metadata, removing the compound metadata from the m3 profile didn't take effect until restarting the app.

Details

The first commit adds a failing spec that reproduces a compound metadata field continuing to render on work forms after it is removed from the m3 profile, until the app is restarted.

The second commit fixes the bug: flexible resources now read compound declarations from the loader's attribute map at the current profile version, rather than from the resource's Dry schemas. A compound removed from the m3 profile disappears from work forms immediately, with no restart.

The Dry schemas cannot represent a removal. Hyrax::Flexibility.attributes only merges attributes in, and builds the singleton schema from the class schema, so a compound present when the class loaded survives in both the class and singleton schemas — folded subproperties: and all — for the life of the process. Ordinary single-value properties were unaffected because ResourceForm#initialize already prunes definitions absent from the current profile; compounds bypass that prune, rendering via #compound_terms instead.

Testing

  • Boot the app with an m3 profile that declares a compound (a type: hash parent property with at least one member declaring available_on: { properties: [<parent>] }). Confirm the compound renders on a work's edit form.
  • Without restarting, upload a profile with the compound parent and its subproperties removed.
  • Reload the work's edit form. The compound field should be gone.
  • Add the compound back via another profile upload, still without restarting, and confirm it reappears on the form.

Reproduces a compound metadata field continuing to render on work
forms after it is removed from the m3 profile, until the app is
restarted.

The failure needs the compound present in the profile at class load,
which is what seeds the stale schema entry. A scalar removed the same
way already disappears correctly; that case is included as a control
so the compound-specific nature of the bug stays pinned.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@laritakr
laritakr marked this pull request as draft August 13, 2026 00:29
@laritakr laritakr added the notes-bugfix Release Notes: Fixed a bug label Aug 13, 2026
A compound removed from the m3 profile now disappears from work forms
immediately, matching how an ordinary single-value property already
behaves.

Flexible resources resolve compounds from the loader's attribute map at
the current profile version instead of their Dry schemas. Those schemas
cannot represent a removal: Hyrax::Flexibility.attributes only merges
attributes in, and builds the singleton schema from the class schema, so
a compound present when the class loaded survives in both for the life
of the process.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@github-actions

github-actions Bot commented Aug 13, 2026

Copy link
Copy Markdown

Test Results

    17 files  ± 0      17 suites  ±0   3h 39m 11s ⏱️ + 18m 49s
 8 021 tests + 6   7 714 ✅ + 6  307 💤 ±0  0 ❌ ±0 
27 451 runs  +25  26 852 ✅ +25  599 💤 ±0  0 ❌ ±0 

Results for commit 86ebbab. ± Comparison against base commit e66834c.

This pull request removes 442 and adds 448 tests. Note that renamed tests count towards both.
spec.abilities.ability_spec ‑ Hyrax::Ability AdminSets and PermissionTemplates a user without edit access is expected not to be able to create #<Hyrax::PermissionTemplate:0x00007f4b06a5f3e0>
spec.abilities.ability_spec ‑ Hyrax::Ability AdminSets and PermissionTemplates a user without edit access is expected not to be able to create #<Hyrax::PermissionTemplate:0x00007f5436381a58>
spec.abilities.ability_spec ‑ Hyrax::Ability AdminSets and PermissionTemplates a user without edit access is expected not to be able to create #<Hyrax::PermissionTemplate:0x00007f9c48f21908>
spec.abilities.ability_spec ‑ Hyrax::Ability AdminSets and PermissionTemplates a user without edit access is expected not to be able to create #<Hyrax::PermissionTemplate:0x00007faa2aa7bf58>
spec.abilities.ability_spec ‑ Hyrax::Ability AdminSets and PermissionTemplates a user without edit access is expected not to be able to create #<Hyrax::PermissionTemplateAccess:0x00007f4b093bec40>
spec.abilities.ability_spec ‑ Hyrax::Ability AdminSets and PermissionTemplates a user without edit access is expected not to be able to create #<Hyrax::PermissionTemplateAccess:0x00007f54363a4da0>
spec.abilities.ability_spec ‑ Hyrax::Ability AdminSets and PermissionTemplates a user without edit access is expected not to be able to create #<Hyrax::PermissionTemplateAccess:0x00007f9c4915af08>
spec.abilities.ability_spec ‑ Hyrax::Ability AdminSets and PermissionTemplates a user without edit access is expected not to be able to create #<Hyrax::PermissionTemplateAccess:0x00007faa2aa717d8>
spec.abilities.ability_spec ‑ Hyrax::Ability AdminSets and PermissionTemplates a user without edit access is expected not to be able to destroy AdminSet: 6b8c7912-6a94-4475-8a12-ec9ab72cf27f
spec.abilities.ability_spec ‑ Hyrax::Ability AdminSets and PermissionTemplates a user without edit access is expected not to be able to destroy Hyrax::AdministrativeSet: 83194b7c-2bf2-426f-bf4d-02091fef045b
…
spec.abilities.ability_spec ‑ Hyrax::Ability AdminSets and PermissionTemplates a user without edit access is expected not to be able to create #<Hyrax::PermissionTemplate:0x00007f2c93a27800>
spec.abilities.ability_spec ‑ Hyrax::Ability AdminSets and PermissionTemplates a user without edit access is expected not to be able to create #<Hyrax::PermissionTemplate:0x00007f57cd3b9260>
spec.abilities.ability_spec ‑ Hyrax::Ability AdminSets and PermissionTemplates a user without edit access is expected not to be able to create #<Hyrax::PermissionTemplate:0x00007fb560930f18>
spec.abilities.ability_spec ‑ Hyrax::Ability AdminSets and PermissionTemplates a user without edit access is expected not to be able to create #<Hyrax::PermissionTemplate:0x00007fc602f13c20>
spec.abilities.ability_spec ‑ Hyrax::Ability AdminSets and PermissionTemplates a user without edit access is expected not to be able to create #<Hyrax::PermissionTemplateAccess:0x00007f2c9afb4258>
spec.abilities.ability_spec ‑ Hyrax::Ability AdminSets and PermissionTemplates a user without edit access is expected not to be able to create #<Hyrax::PermissionTemplateAccess:0x00007f57e6efb060>
spec.abilities.ability_spec ‑ Hyrax::Ability AdminSets and PermissionTemplates a user without edit access is expected not to be able to create #<Hyrax::PermissionTemplateAccess:0x00007fb5a42cb698>
spec.abilities.ability_spec ‑ Hyrax::Ability AdminSets and PermissionTemplates a user without edit access is expected not to be able to create #<Hyrax::PermissionTemplateAccess:0x00007fc5f42a7580>
spec.abilities.ability_spec ‑ Hyrax::Ability AdminSets and PermissionTemplates a user without edit access is expected not to be able to destroy AdminSet: 4e5992af-8224-4012-97c5-695b83ef55d8
spec.abilities.ability_spec ‑ Hyrax::Ability AdminSets and PermissionTemplates a user without edit access is expected not to be able to destroy Hyrax::AdministrativeSet: a53a4373-d980-42f8-a2dd-59984deee16c
…

♻️ This comment has been updated with latest results.

laritakr and others added 2 commits August 12, 2026 21:20
A compound declared as a plain class attribute, on a class the m3
profile does not govern, resolves from the class schema again.

The profile is authoritative only for classes it declares. Gating on
flexible? alone sent every flexible resource to the loader, which
answers for an unknown class with a fallback schema rather than
nothing — silently dropping a compound that only the class body
declares, such as the FileSet provenance case.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@laritakr
laritakr marked this pull request as ready for review August 13, 2026 20:08
@laritakr
laritakr requested a lite review from Copilot August 13, 2026 20:09

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR fixes a flexible-metadata edge case where removing a compound field from the active M3 profile didn’t stop it from rendering on work edit forms until the app was restarted. It does this by changing how Hyrax::CompoundSchema resolves compound declarations in flexible mode and adds a regression spec that reproduces the stale-compound behavior.

Changes:

  • Add a failing regression spec demonstrating compound removal not taking effect without a restart.
  • Update Hyrax::CompoundSchema to prefer current profile-derived attribute maps for profile-governed flexible resources instead of relying on stale Dry schemas.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.

File Description
spec/services/hyrax/compound_schema_profile_removal_spec.rb Adds a regression spec covering removal of a compound field without restarting the app.
app/services/hyrax/compound_schema.rb Adjusts compound resolution to use loader-provided attribute maps for the current profile when the profile governs the resource.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread app/services/hyrax/compound_schema.rb
@laritakr
laritakr marked this pull request as draft August 13, 2026 20:16
A governed class whose current contexts filter out every field no
longer falls back to its stale schemas, which would have resurrected
the compounds the profile dropped.

The loader already distinguishes the two cases: nil means it could not
answer, an empty map means it answered with nothing. Testing for
present? conflated them.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@laritakr
laritakr marked this pull request as ready for review August 13, 2026 22:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

notes-bugfix Release Notes: Fixed a bug

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants