Content Libraries Sync Notes
@Kyle McCormick @Dave Ormsbee (Axim) @Braden MacDonald @Jenna Makowski @Marco Morales @Sam Daitzman @Maksim Sokolskiy @Scott Dunn
Evergreen topics:
Any new decisions made in the past week?
Any big decisions that need to be made?
https://openedx.atlassian.net/wiki/spaces/OEPM/pages/5025693717
Check figma files - new decisions
Add any ADRs - new decisions
Roadmap status updates: https://github.com/orgs/openedx/projects/66/views/6
May 8, 2026
Bugs outstanding: https://github.com/openedx/frontend-app-authoring/issues/3045
Braden is currently working on course import related performance issues.
Jenna is going to write up the import docs.
Apr 23, 2026 :
Discussed history log behavior and how we want to display intermediate container changes. (Added to the decision log.)
Prioritization of history log work for Verawood (now that the release has been delayed by a bit and we have some chance of getting this across the line):
First priority is to make the history log available, even if it has no intermediate containers in pending changes. That’s the current state of the code in-flight, and the feature is valuable enough in this state that it makes sense to include in Verawood, even if it’s a bit rough around the edges. Merging these existing PRs is our best shot at having something for this release cycle.
The next priority is to include intermediate containers in the pending changes display.
Next priority is to add the display of when the draft is reset (“discard changes”). This is currently filtered out.
Apr 10, 2026
https://github.com/openedx/openedx-core/issues/533
tldr
3 categories of things which are changed when “Publish” happens…
Directly published. the things that are published because we literally hit “Publish”
Example: A Unit. Its “Publish” button was pressed.
agree that “Direct” is a good term both for the UI and for the code.
Indirectly published (downwards cascade). dependencies (ie children & descendents) of the that was published
Example: Components within the Unit. They were implicitly published because their parent Unit was explicitly published.
Indirectly changed (upwards cascade). publish state changed, but nobody asked for that thing to be published
Example: the Unit’s parent Subsections, their parent Sections
(does this case actually happen)
It’s not actually published
But it’s changed by side effect
Publish All edge case
Bulk Publish vs Publish All. Are they different?
Braden: Get rid of Publish All. Just select all and hit Bulk Publish
jenna: Fine to not distinguish. Likes ^ idea
Kyle: are they direct publishes?
consensus - yes
When you bulk-publish containers X, Y, Z:
X Y Z are Direct published
descendents of X Y Z are indirectly published
ancestors of X Y Z are indirectly changed
what is shown in the publish log record is: X Y Z
do we have a UI for multiple things directly published?
bulk-publish of two things that share a common descendent?
scenario: two units, A and B ….
[ (A), B ] –> C*shared component, C
C has changed
*publish
(A)look in history log for B, what do I see there?
I should see that C was published because A was published?
Marco: the original expectation was that when you publish A, that B wouldn’t be affected-- B would need to be directly published too. But that’s not the publish model we went with.
Braden: UI is confusing because ..
Jenna; UI tweak to distinguish direct vs indirect publishing would resolve this?
e.g. “C was indirectly published because B was published” ?
Braden: would be great to be able to click on any of these entries and see the full log of what was published directly or indirectly
is on the future wishlist but not planned currently
we don’t expect this to be a very common case in the short term
Marco: should a unit/subsection publish be considered same as a bulk publish of the things below it?
There’s a whole workflow (punted from Verawood) to reword library-level publish
UI that explains what’ll be published is really nice
doesn’t say any specific terms for these things, just says what’ll be published
when someone explicity publishes a section, the UI clarifies that its descendents will be published
“through the act of publishing a unit, not only did it cascade down, but the things it used in changed”
DECISIONS
“Direct” is the tech term, possibly a UI term, for the things you explicitly publish by hitting “Publish” or include it in a bulk publish
Publish log will currently only just show directly published things
Will not currently--but might in the future--show indirectly published things in the publish log too.
@Dave Ormsbee (Axim) will ticket up that ^ followup
Feb 27, 2026
Jan 9, 2026
https://github.com/orgs/openedx/projects/66/views/6?sortedBy%5Bdirection%5D=&sortedBy%5BcolumnId%5D=
Lots of epics that have a ton of completed stories and 1-2 outstanding ones. Planning to move some to future epics like a new performance-oriented one (e.g. #1681
Closing out outstanding Ulmo epics today
DECISION: Will push Legacy libraries DEPR to Willow to ensure sites like MIT, edX have time to migrate. Aiming to get key stakeholders migrated by Verawood, with padding.
Dec 12, 2025
@Sam Daitzman Version history: design share out and discussion about lower-level publishes
https://openedx.atlassian.net/wiki/spaces/OEPM/pages/5386567689
Conclusion: group object-level publishes at bottom, with child-level publishes chronologically grouped above, with all non-published lower-level edits at top
All publishes are chronological (though not edits within them). All edits since last child publish are chronological.
Dec 5, 2025
@Sam Daitzman: following up, I think there was a small patch planned to add some limited links from course content to the library content it references-- is that still planned?
→ Not yet, Dave looked into it
@Kyle McCormick - Legacy migration, status & concerns
PR we need to land some version of before the release:https://github.com/openedx/edx-platform/pull/37711
user-facing issues it is fixing:
[not release blocking] editability of legacy libraries post-migration
[not release blocking] spurious sync after converting a reference
REST API facing issues it is fixing:
[not release blocking] inconsistent decision making around what entities and collections to update when the “update”/”skip” strategies are specified. This is not important for the UI because it always uses “fork”, but Scott’s use case sounded like he’d be using “update”/”skip”
General improvements to code consistency and comprehensibility. Which normally I’d try to land NOT in Ulmo, but we’re seeing other migration issues, and I’m wondwering if they’re related
Decision: these are not release blockers, they do not affect the vast-majority use cases. Will try to get some fixes into ulmo.1, but can become part of ulmo.2 otherwise
Nov 28, 2025
@Sam Daitzman / @Edward Byun: Settings for Ulmo release (incremental design / checking in on current status) https://github.com/openedx/frontend-app-authoring/issues/1976#issuecomment-3571612172
Nov 21, 2025
@Sam Daitzman: User-facing sync / publish behavior documentation
Requested at Educators WG
Requested here as well: https://github.com/openedx/docs.openedx.org/issues/1298
Sarina: want to move toward how-to articles in documentation, testing should just be “follow this how-to and report unexpected behavior”
Action item: ideally before the Ulmo release (Dec 9): send @Sarina Canelake high-level overview of publish / sync happy path
@Kyle McCormick legacy libraries migration release notes / docs
…
Meeting Visibility / Cross-Org Input and Recaps
@Marco Morales - flagging based on prior conversations about cross-org initiatives
@Edward Byun / @Sam Daitzman: https://github.com/openedx/frontend-app-authoring/issues/2626#issuecomment-3555417120
Steps:
1. Migrate legacy library
1.5. Publish all migrated
2. Update reference
3. Update content from updates pane
If step 1.5 exists: someone rewrites the content, then skipping step 3 or auto applying it will have unexpected results
@Kyle McCormick: may be possible to detect this case (step 3 being spurious). If the legacy course content was up-to-date, and there has been no non-migration-triggered version update in new libraries, may be able to ignore the update / not present it
Kyle figured this out and will make a PR for it.
Oct 31, 2025
@Sam Daitzman: checking in on settings status
there’s a ticket to add readonly settings https://github.com/openedx/frontend-app-authoring/issues/1976
there is a PR for the frontend, but nothing for the backend. have not heard from the 2U dev who volunteered on the ticket.
@Sam Daitzman: release testing / RBAC overlap
plan to delay testing until RBAC lands?
are we concerned about overlap?
Braden:
let’s consider that to be BTR’s testing plan
we can still test in a more fine-grained way on our own and just ignore RBAC
Have we tested on Indigo theme / depending on BTR group and Tutor outcome of BTR thread (if BTR decides to test with Indigo theme applied), we may want to check on libraries support
It looks like nobody is using python_lib.zip in practice.
Test process
Dave: Are we adding our cases to the giant spreadsheet?
Sam:
UX Discussion: When published components are added to a unit, or components are individually published within a unit, it’s not obvious that the unit itself is still in draft and the published version doesn’t yet show those new components.
Proposed short-term fixes:
add a “draft” / “unpublished changes” label to the unit header / unit info button
-> we decided this is the best short-term fix for Ulmoadd content type icon to sidebar to make it more obvious what thing you’re publishing
after publishing child object, switch to parent object info sidebar
Proposed long-term fixes
Add a “What the student will see.” / “Published” tab that shows the published view in the library
Hide component-level publish buttons entirely when you’re on a unit page
But then should they also be hidden when you access a component separately but it’s only used in one parent unit? → Gets to Scott’s question about intended level of re-use and how we don’t acknowledge that anywhere in the UI.
add persistent page-level draft status / publish action (basically requires layout restructure I would not recommend after feature cut)
Oct 24, 2025
Dave & Kyle: Proposal to backport a minimal
python_lib.zipsupport into libraries so that we can better support early adopters like MIT. Would involve a new entity type.Example of a python_lib.zip : https://mitodl.github.io/mitx-grading-library/
Conclusions:
@Dave Ormsbee (Axim) Reach out to MIT to see if they actually do this, and if it’s a blocker for v1 → v2 migration.
@Kyle McCormick will (re-)write the legacy libraries deprecation ticket
Documentation
Ulmo docs will include concept docs and reference docs
@Scott Dunn to provide some insight on confusing parts of the library workflows and where documentation currently is not clear
Import backend API epic: https://github.com/openedx/frontend-app-authoring/issues/1681
Oct 17, 2025
Sam: When we were testing the migration, there was one time when they encountered a failed migration state (@Edward Byun ran into this). It seemed like some libraries were migrated in, but none were assigned to collections. Question: Is the migration codebase set up so that operations are atomic (either all works or all fails).
Kyle: Intention is that it’s atomic. Way it’s implemented now is that adding to collection could fail even if import succeeds.
Braden: We’ll follow-up in the ticket: https://github.com/openedx/frontend-app-authoring/issues/2169#issuecomment-3412840187
Sam: If we’re migrating multiple libraries at the same time, it’s okay if some succeed and some fail. Will provide mockups for this error state.
Marco: We’re making progress on post-Ulmo stuff. If there’s anything that the team would benefit from sizing activities, etc. where we’re blocked on UX questions, please contact them. But currently closing out Ulmo is highest priority. Want to make sure there are no other blockers.
Sam: Is it possible to create some test libraries that will cause migration errors?
@Kyle McCormick will create these test libraries to cause errors for testing.Braden will take a look at https://github.com/openedx/frontend-app-authoring/pull/2532 , but in general it’s okay for Diana or others who are CCs with access to that repo merge. Braden is the default reviewer and gets notifications on everything.
Restore screen discussion
Sam provided updated adjustments to the Figma screen for the restore screen, to include where the archive came from.
We’ll continue to have extra metadata in the archive about things like “number of units”, “number of subsections”, etc. Even if we’re not doing it for now because it would crowd the UX, we may want to display them later.
We will not implement a “change the archive” flow. If you uploaded the wrong archive, you can go back and create new again.
Javier is out next week, but he will transition work to someone else on his team.
Opaque Keys discussion postponed to post-Ulmo-cut
Oct 10, 2025
Testing migration process:
Obtain some text export V1 libraries (from Colin?), import into sandbox, then test the migration process
How many? as many as possible
UX/UI presentation: Thinking about course outline sidebar and FE slot
@Jenna Makowski / @Sam Daitzman : sidebar pattern epic planning and spec
Likely ~3 epics across: sidebar plugin slots on course outline/unit view, outline/unit sidebars and selection pattern (could be split), library bulk actions
What questions should initial spec to unblock the plugin slot work answer?
What would be helpful to unlock the first round of development work on this?
Some thoughts in: https://github.com/openedx/frontend-app-authoring/issues/1958
Questions to answer
Are sidebars resizable? Responsive approach?
Sequencing: how do we avoid overwhelming authors? What is the first increment of change?
Are we eventually going to support bulk actions, either through multi-selection or another interface?
Would be helpful to plan for this even if not shipping it quickly
If you close a sidebar, can you reopen it or do you have to press the same button to open it again?
How do sidebar states interact with URLs, can you share a URL with a specific sidebar open in a specific state?
Plugin architecture: what slots do we want to support?
Extensibility: at a site level, course level, etc.?
Design / product principles for sidebars vs. modals vs. inline: how do we generally want to prioritize?
Frequency of use / frequency of repeat tasks
Benefit of in-context / multi-modal actions vs. irrelevant for some actions
Oct 3, 2025
Code cut pushed out 2 weeks
Check in re Course library related Advanced settings (educator visibility, use, etc)
https://github.com/openedx/edx-platform/pull/36831
We need to this again ^ but for the newly-added fields.
Testing plan for V1 ---> V2 migration workflows
Happy path tests - pretty simple, one or two tests cases should suffice
will talk through them with Jenna on tuesday
Failure case tests
One or two manual test cases should be sufficient, details can be handled in unit tests
@Kyle McCormick will make an invalid library .tar.gz for manual testing
will add to release testing sheet: https://docs.google.com/spreadsheets/d/1-gEXI4IiAn5mdROGDMxNcFHAaZCRu3mxVLNDmTdJFI8/edit?gid=1955774185#gid=1955774185
Seeking input on UI for “migrating” a randomized Legacy Library reference into a Problem Bank after its source library has already been migrated.
WIP UI:
Text under the migratable legacy reference:
e.g. “The source has been migrated to a new library. <Check for updates>”
or just use the standard update text
Sam approves
Eddie is going to think on it
should this apply the update from the v2 library, or just check for it?
dave approves of applying the update at the same time
and if sync from v2 fails, then leave it as a legacy reference
course-level admin action for updating all legacy references
or, even better, a button on the library updates page ( * )
dave: we could just do a modulestore query to get a list of library_content references which haven’t been migrated but have source librarides that are migrated
Also noted: exporting a course with migrated references into an older instance should still allow the v1 library sync flow (i.e. we keep the old field value there)
Decisions recorded here: https://github.com/openedx/frontend-app-authoring/issues/2386#issuecomment-3372472237
Sep 26, 2025
Any blockers, particularly on the migration epics?
Any concerns about Ulmo timeline?
Ticket for hiding hierarchy diagram parent labels / text for Ulmo based on publish behavior discussion: https://github.com/openedx/frontend-app-authoring/issues/2466
@Edward Byun https://github.com/openedx/edx-platform/issues/37327 Wanted to confirm: 50 legacy libraries per migration?
We suggest 50 libraries per page limit, pagination, and limiting migration to page-in-view
Updated designs / detailed spec coming soon on frontend migration ticket
Finding a time for Pearson API import workshop
Sep 19, 2025
@Sam Daitzman: demo of section-/subsection- level library authoring and course reuse experience
@Edward Byun Deletion for Ulmo. There are some conversations to have in the future, but want to keep this to Ulmo focused.
Child components: parent shows as requiring a sync after parent is published (treated as a content edit; publish cascade implementation for deletions/removals for Ulmo will differ slightly)
Deletion = publishable action with no viewable entity (publish all publishes the object, and publishing parent can cause sync because of null reference / updated list of references)
Stand-alone and deleted at level of reuse: broken link icon appears immediately in course instance of deleted library object
For containers, this means if there are published changes to descendants, course will not be able to see unless user sees broken link icon and unlinks the container.
Three options from least effort to most:
Do nothing. Downside: relies on users seeing broken link icon to get visibility, and relies on users knowing to unlink (if they want to get updates).
Auto un-link. Downside: loses level of intended reuse with low visibility to users. May cause future issues for permissions / publish model.
Auto un-link raises some questions: when does this unlink happen? How can we differentiate (to user) permission loss vs. an object being deleted? What happens when the object is restored from trash?
Add broken links section to Library Updates page as a new category. Downside: Dev effort: need new CTA interface and action modals to communicate child object deletion (or could just surface as a top-of-page health indicator / count).
For Ulmo, we recommend doing nothing. There are some real questions about intent that should be addressed through interviews/ discovery, ‘do nothing’ for now allows us to move forward in some direction in the future without having to backtrack on some decision here.
@Edward Byun GitHub issue tracking remaining Ulmo tasks: https://github.com/openedx/frontend-app-authoring/issues/2462 . I’ll update as we go through and address tickets.
And, bug tracker for Ulmo bug-fixing period: https://github.com/openedx/frontend-app-authoring/issues/2451
@Dave Ormsbee (Axim) Resiliency questions on error handling in restore.
Decision: Fail the whole creation for Ulmo. Will need to do something more resilient for partial import of large libraries post-Ulmo. We’ll generate an error log file as a downloadable artifact. Target audience is technical, so debug info here.
Sep 12, 2025
@Sam Daitzman: Share out Verawood design priorities / discuss scoping and areas that could use definition soonest to support future Verawood development.
Overrides
Text overrides, as previously planned
Possibly partial sync by un-linking. For example, Section is linked, but you only want to sync a subset of its Subsections. So, you “unlink” the Section, and now you can sync individual Subsections.
Not targeting more complicated overrides.
Inheritance
Q: In a course, can you set max_attempts at the Section level and have it inherit down?
Yes, in OLX. Not in the UI.
But, for library-referenced content, each individual Problem sets a max_attempts, so the Section-level-OLX-set inherited value would be ignored.
Templates?
Not for verawood probably
Rather, we’re taking advantage of all the structural block work that has happened
Dynamic content in libs - not targeting for Verawood
Dave: would be cool to do cross-library search.
Braden: this is basically ready to go, can turn it on when it’s wanted
@Kyle McCormick Legacy Course Unit and Problem editors will still be available in Ulmo. IMO, we don’t need to support library syncing in these legacy editors, but we should have some graceful degradation or error mesage. i.e., the legacy editors shouldn’t raise a 500 or corrupt the course if you’re looking at lib-linked content.
In what cases will someone see legacy editor? (Is it: manually toggled that on?)
Course-level or instance-level toggle; only reason to have it toggled on is for advanced use cases new problem editor won’t yet support, or new problem editor bugs are an issue for you