Thank you for the Brightspace content write spec
(Course Offering orgUnitId + Path + Table of Contents)
and for confirming Deploy identity as Module type 101.
Below are the points we need confirmed so Publish content
uses the correct coursesite — without asking instructors for a Course ID.
Question 1 should only need a yes. The rest each carry at least one decision that is
still open — where an option is already what we have built, it says so, so you are
choosing whether to keep it or change it. Note that Publish is not yet released to
staging: “what we have built” below means what the software does, not something you
can see there yet.
SIT Course Builder20 Aug 2026
What we already treat as settled
Deploy / Save identify the subject on LMS as Module (type 101) via Module code (fallback: MC code → the matching 101).
Content write cannot use that 101 as the write target. APIs need a Course Offering (type 3) with a content Path and ToC.
If no Course Offering matches, Deploy already fails with a message. A module in that state cannot be published at all, so Publish never has to handle “no coursesite”.
When the same module is published again, unchanged pages are not re-uploaded. The write spec keeps Brightspace module/topic IDs and a content hash, so a later Publish skips what has not changed. (Publishing one module never reads its siblings at all — see Q4.)
We never delete anything on Brightspace. Publish only creates and updates objects it owns. Content it no longer recognises is left in place, never removed — recorded on the push job, but not surfaced to the instructor today. See Q5.
As built, Publish puts one folder per lesson of the Builder module on the ToC, titled after the lesson. There is no folder for the Builder module itself — see Q4.
Creating a Course Builder module does not write LMS by itself. Content appears only after an explicit Publish of that module.
Publish writes the module currently open — not every sibling under the same MC in one click, unless you tell us otherwise in Q4.
Terms used below
Module (type 101)
LMS module definition — parent org unit. Used for identity / Deploy lookup. No student class list and no content Path; Publish refuses to write to any org unit without a Path.
Coursesite / Course Offering (type 3)
LMS offering under a Module (and semester). Roster lives here. This is the orgUnitId in the content write spec.
Content module (ToC, Type 0)
A folder on the offering’s Table of Contents. Not the same thing as org unit 101.
Lesson (Course Builder)
A chapter inside a Builder module. As built, each lesson becomes one folder (content module) at the top level of the offering’s ToC, titled after the lesson.
Micro-credential (MC)
Optional Course Builder grouping. Several Builder modules may share one MC code. Deploy fallback looks up a 101 from that code.
Publish content
Write HTML / files into a coursesite ToC for the Builder module the instructor has open.
1. Instructor enters a Module code (101) — which Offering list may we push to?
The field on Course Builder is a Module code. That matches an LMS
Module (type 101). HTML cannot be written on the 101: it has no content
Path. Under that 101, LMS can have several Course Offerings (type 3)
for the same trimester. We do not ask for a Course ID. We build a
list of Offerings:
1. Module code
typed on Course Builder e.g. ICT2101
→
2. Find 101
one parent org unit code = ICT2101
→
3. List children
all Course Offerings (type 3) under that 101
→
4. Keep this term
semester = Builder trimester e.g. 2610 — may be 0, 1, or N
result = a list of Offerings (not “the” one course). Deploy already binds this whole list for roster.
One Course Builder modulecode ICT2101 · trimester 2610
LMS Module 101 · ICT2101 — identity only, nothing is written here
Offering 25801 · 2610 ← in the list
Offering 25802 · 2610 ← also in the list (same module, same term)
Offering 26105 · 2620 ← dropped (different term)
Option A is only: Publish uses this list — no extra Course ID.
If the list has more than one Offering, that is question 2 (write all vs one).
A Same lookup list as Deploy
Module code → 101 → Offerings for this trimester.
The list can be several coursesites.
Publish may only write into Offerings on that list.
How to treat N sites → Q2. Not a second lookup.
B A different list
e.g. type a Course ID, or push to an Offering that Deploy did not bind.
Then we need that rule from you.
Please confirm
Option A is what we have built: the allowed Publish targets are exactly the
Course Offering list already found for Deploy
(Module code → 101 → children matching the Builder trimester), and Publish
refuses any other org unit. Please confirm that is right.
That list may contain more than one Offering; Q2 asks what to do then.
If you need Option B instead, how is the coursesite chosen?
2. If one Module + trimester matches several Course Offerings — where does HTML go?
Under one 101, the same semester can have 0, 1, or N Course Offerings
(this is the list from Q1 Option A). Deploy already binds all of them
and can merge roster. Content cannot be merged: each Offering has its own
Path and ToC. Publish must pick a write rule for N.
Same 101 + same trimester
0Deploy already fails — module cannot be published
1write that ToC
NN separate ToCs
Merging class lists does not copy HTML. Each site is a separate content store.
If N — choose one rule
A Write one Offering, chosen at Publish
What we have built: the Publish screen lists the bound Offerings and the person publishing
picks one of them. If you would rather have a fixed rule than a person choosing — a primary
site, or first match — tell us which.
B Write every matched Offering
The same HTML is upserted into each coursesite ToC (skip unchanged pages on each site).
Cost: pushes to one coursesite run one at a time and each site is prepared
separately, so this is a sequential batch across N sites rather than one action.
Please confirm0 and 1 are already built — 0 stops at Deploy with a message, 1 writes the HTML into that site.
Please confirm both are what you expect.
The open case is N: Option A (one site, picked at Publish — what we have built)
or Option B (write every matched site)? If Option A, also tell us whether picking at Publish is
right, or whether you want a fixed rule instead.
3. A Module code that gives no coursesite — fall back to the MC code, or stop?
Course Builder has a fallback so that a module whose own LMS Module code cannot produce a
coursesite can still be deployed: instead of failing, it uses the 101 behind the
MC code. It was built to keep Deploy working; this question is whether it
should also be allowed to decide where content is written.
There are two ways a module ends up on the MC’s 101, triggered at different
moments by different conditions. They look different on screen, but they end in the
same place.
Path 1 — the Module code matches no 101 at all (fires on Save)
Module code
not found in the LMS
→
MC code → its 101
stored as this module’s LMS identity, right here
→
Deploy
reads that stored 101 and binds the MC’s Offerings
Save does not pick a coursesite itself, but it decides which 101 Deploy will use —
so the coursesite is effectively settled here. The module also takes its title from the matched
101, which on this path means it is renamed after the MC.
Path 2 — the 101 exists but has no Offering this term (fires on Deploy)
Module code
e.g. ICT2102 — found, and confirmed at Save
→
0 Offerings for 2610
nothing to bind
→
MC code → its 101
bind its Offerings instead
A Module code can pass the Save check and still be overridden at Deploy: Save asks
“does this subject exist?”, Deploy asks “does it have a coursesite this term?”.
Both paths end here
ExampleMC-ABC groups three Builder modules, all for trimester 2610
Module A · code ICT2100 → its 101 has Offering 25958 · 2610
→ publishes to its own coursesite
Module B · code ICT2102 → 101 exists, no 2610 Offering
→ Path 2 → publishes to the MC-ABC coursesite
Module C · code not in the LMS at all
→ Path 1 → publishes to the same MC-ABC coursesite as B
B and C now share one ToC — the layout problem in question 4 — while A does not.
Nobody chose that split. It follows from which 101 happens to resolve, and from which 101 happens to
have an Offering this term — and the second of those can change from one trimester to the next.
Deploy succeeds on both paths, with no warning. The Publish screen does list the coursesite by name and
id, so an attentive instructor could notice it belongs to the MC rather than to their module — but
nothing on screen tells them a fallback happened.
A Keep it silent
Current behaviour, on both paths.
Deploy succeeds as often as possible.
Publish may land on a coursesite shared with sibling modules, so question 4 applies to every module that falls back.
B Stop with an error
“No coursesite found for this Module code.”
Nothing is ever published to a shared site by accident.
Cost: the module cannot be deployed until staff fix the code or create the
Offering in the LMS — and for trimester-based modules Deploy only opens in the two weeks
before the trimester starts.
Please check how many modules rely on the fallback today; Option B stops all of them.
C Keep it, but ask first
The operator is told which coursesite is about to be used, and confirms it — on whichever
path triggered the fallback.
e.g. “No coursesite found for ICT2102. Use the MC-ABC coursesite instead?”
Same reach as Option A, without the silence.
Please confirm
When a Module code gives no coursesite of its own, should Course Builder fall back to the MC
silently (A), refuse (B), or fall back only after the operator confirms the named coursesite (C)?
Please answer for both paths — or tell us if they should behave differently
(for example: allow Path 1, where the code was never valid, but refuse Path 2, where the module has
a real 101 that is simply missing an Offering this term).
If you pick A or C, question 4 applies to every module that lands on a shared MC coursesite.
4. Several Course Builder modules share one coursesite — the life of that ToC
One Micro-credential can group 3–4 Course Builder modules, and through the fallback in
question 3 they can resolve to the same Offering —
modules B and C in that example.
Everything below follows from that one situation: how the shared Table of Contents is laid out
to begin with, what happens when a further module is added later, and who decides the order.
Part 1 — how Publish lays out the ToC
One Offering· one Path · one ToC
Lesson 1 of module B ← folder, titled after the lesson
Lesson 2 of module B
Lesson 1 of module C ← same level, nothing separates them
Lesson 2 of module C
Publish creates one folder per lesson at the top level of the ToC.
There is no folder for the Builder module itself, so two modules published
into one coursesite interleave and cannot be told apart by a learner.
A One Builder module = one coursesite
Module Bown Module code 101 own Offering ToC
Module Cown Module code 101 own Offering ToC
Works with what we have built, no change needed. A module’s lessons are the only thing on
that ToC, so the flat
folder-per-lesson layout reads correctly, and parts 2 and 3 below stop being a problem.
Requires that every Builder module has a Module code resolving to a 101 that
has an Offering — i.e. Option B in question 3.
B Several Builder modules = one coursesite
One Offeringone Path · one ToC
→
Folder “Module B”lessons nested inside
Folder “Module C”lessons nested inside
To keep the modules apart we would add a new folder level — one folder per
Builder module, lessons nested one level deeper. That is a change to how Publish builds the
ToC, not a setting, so we need to know before we build it.
Part 2 — a further module is added later
B and C published
on the shared coursesite
→
Create D
Course Builder only LMS unchanged
→
Publish D
D’s lesson folders are added to the same ToC
Creating D writes nothing to the LMS — content appears only when someone opens D and presses
Publish. And publishing D does not touch B or C at all: a push job is scoped to
one Builder module, so its siblings are never even read. This is not “they get skipped because
nothing changed” — they are outside the job.
Part 3 — who controls the order
Two things Publish does with the ToC order, and one it deliberately does not:
Orders its own folders
the lessons of the module being published are put into that module’s order
Never moves anyone else’s
by design, it never repositions a folder it does not own
Does not choose where a new folder lands
on creation Publish sends no position at all — the placement is Brightspace’s
One further limit is worth stating plainly: the reorder pass only issues a move when one of its own
folders sits earlier than the folder it is supposed to follow. It never issues a move
merely to close a gap — so another module’s content sitting in between stays in between.
A state this permitson a shared ToC
Lesson 1 of B
Lesson 2 of B
Lesson 1 of C
Lesson 2 of C
Lesson 1 of D
Lesson 2 of D
Lesson 3 of B← added later, and separated from the rest of B
B’s lessons are in the correct order — 1, then 2, then 3. They are simply not together, and Publish
will not correct that: nothing is out of order, there is only a gap. On a coursesite holding a single
module this never shows, because there is nothing to sit in the gap.
Please confirm(1) Layout. For Builder modules that share an MC: Option A (each module has its own
Module code 101 and its own Offering ToC) or Option B (they share one Offering, with a new
module-level folder)? If Option B, what should that folder be titled — Builder module title, Module
code, or both — and is pushing the lessons one level deeper acceptable to your instructors? (2) Adding a module later. Please confirm a new module reaches the LMS only after
Publish on that module, and that its siblings are never rewritten. If you also want
an MC-level “publish everything not yet published”, tell us — note that pushes to one coursesite run
one at a time, so it would be a sequential batch rather than a single action. (3) Order. If several modules do share one ToC, does their order matter to you?
If it does, where should that order come from — the MC’s module list, staff arranging it in
Brightspace, or something else? Today nothing in Course Builder expresses “module B comes before
module C”.
5. The coursesite already has content — adopt it, or always create our own?
A coursesite may already carry content: made by staff, left by an earlier system, or brought in
by a Brightspace course copy. Before writing anything, Publish reads the ToC and sorts every
top-level folder into three groups.
Ours
we created it on an earlier Publish → update in place
Same title as a lesson we are about to publish
offered to the instructor: “adopt instead of duplicating?”
Everything else
left untouched, listed as “not managed by Course Builder”
Nothing is adopted silently — the instructor ticks each one. Adopting marks the folder as ours
from then on, so later Publishes keep updating it instead of creating a second copy.
A Keep adopt-by-title
What we have built.
Avoids duplicate folders when the site already mirrors the module.
Please confirm
(1) Should Publish keep offering adopt-by-title (Option A), or always create its own
folders (Option B)?
(2) Please confirm the delete policy: we never remove anything on Brightspace.
When a lesson is deleted in Course Builder, its folder stays on the coursesite with its content and
learners keep seeing it. The leftover is recorded on the push job, but we do not show it to the
instructor today. Is leaving it what you want — and should we surface these leftovers on screen so
staff know what to clean up?