From 0bdda8775a2b0b1b6897f22522afa242369e921a Mon Sep 17 00:00:00 2001 From: Agrendalath Date: Thu, 20 Aug 2026 20:03:19 +0200 Subject: [PATCH] docs: add ADR for mapping pathway items to fulfillment --- .../0006-pathway-item-fulfillment.rst | 61 ++++++++++++++ .../images/pathway-item-fulfillment.dot | 20 +++++ .../images/pathway-item-fulfillment.svg | 81 +++++++++++++++++++ 3 files changed, 162 insertions(+) create mode 100644 docs/openedx_learning/decisions/0006-pathway-item-fulfillment.rst create mode 100644 docs/openedx_learning/decisions/images/pathway-item-fulfillment.dot create mode 100644 docs/openedx_learning/decisions/images/pathway-item-fulfillment.svg diff --git a/docs/openedx_learning/decisions/0006-pathway-item-fulfillment.rst b/docs/openedx_learning/decisions/0006-pathway-item-fulfillment.rst new file mode 100644 index 000000000..480f212e7 --- /dev/null +++ b/docs/openedx_learning/decisions/0006-pathway-item-fulfillment.rst @@ -0,0 +1,61 @@ +.. _openedx-learning-adr-0006: + +6. Pathways: Mapping Pathway Items to the Things That Fulfill Them +================================================================== + +Status +------ + +Draft + +Context +------- + +:ref:`openedx-learning-adr-0005` establishes that a Pathway Item is a stable requirement whose fulfillment can change +over time. This ADR describes how we intend to map Items to the things that fulfill them, starting with the only +fulfillment type in the first release: passing a course. + +The exact data model here will likely need adjustment; we expect to modify it in an actual code PR. +Development does not gate on this ADR - it captures intent and boundaries, not field-level models. + +Decisions +--------- + +1. In the MVP, a Pathway Item is fulfilled by passing a course run: + + - Each Item holds an **author-defined list of course runs** that fulfill it. Passing *any one* of them fulfills + the Item. The runs may belong to different catalog courses. + - The list is explicit rather than "any run of this catalog course", because we don't necessarily want to give + credit for every possible older version of a course. + - "Passing" is determined by each course's own grading policy. The grade and passed/failed state are read directly + from the course; Pathways define no grading of their own. + - Each Item designates a **default course run** - the one a learner is enrolled in when they begin the Item - and, + if that course uses multiple enrollment tracks, the track to enroll them in. The default can change over time. + +2. Fulfillment types attach at this layer only. Potential future types - section completion, competency attainment, + admin override - plug in as alternative ways to fulfill an Item, without touching Item identity, Pathway structure, + or Pathway completion criteria. + +3. Edge cases are resolved at this layer and never leak upward. For example: multiple passed runs fulfilling the same + Item (the Item is simply fulfilled), or one passed run fulfilling several Items simultaneously (each Item is + fulfilled independently). + +4. Prior work counts. If a learner passed a course before enrolling in a Pathway that contains it, that pass fulfills + the corresponding Item - fulfillment is evaluated against the learner's record, not against activity that happened + "inside" the Pathway. + +.. Run `dot -Tsvg images/pathway-item-fulfillment.dot > images/pathway-item-fulfillment.svg` to regenerate the + diagram after making changes to `images/pathway-item-fulfillment.dot`. + +.. image:: images/pathway-item-fulfillment.svg + :alt: Pathway Item fulfillment mapping + :width: 100% + +Consequences +------------ + +- Authors control exactly which runs count, at the cost of manually updating the list when new runs are created. +- Because passing state comes directly from course grading, there is no Pathway-side duplication of grades to keep in + sync. +- The fulfillment mapping is the natural extension point for everything post-MVP, and the part of the model we + expect to iterate on in code. diff --git a/docs/openedx_learning/decisions/images/pathway-item-fulfillment.dot b/docs/openedx_learning/decisions/images/pathway-item-fulfillment.dot new file mode 100644 index 000000000..bf92643f3 --- /dev/null +++ b/docs/openedx_learning/decisions/images/pathway-item-fulfillment.dot @@ -0,0 +1,20 @@ +digraph pathway_item_fulfillment { + rankdir=LR; + fontname="Helvetica"; + node [shape=box, style=rounded, fontname="Helvetica", fontsize=11]; + edge [fontname="Helvetica", fontsize=10]; + + item [label="Pathway Item"]; + runA [label="Course Run A1\n(default: enroll here)"]; + runB [label="Course Run A2\n(older run, still counts)"]; + runC [label="Course Run B1\n(different catalog course)"]; + future [label="future fulfillment types:\nsection completion,\ncompetency, admin override", style="rounded,dashed"]; + + item -> runA [label="pass any one"]; + item -> runB; + item -> runC; + item -> future [style=dashed]; + + grading [label="passed/failed read directly\nfrom each course's\ngrading policy", shape=plaintext, fontsize=10, fontcolor=gray30]; + runB -> grading [style=invis]; +} diff --git a/docs/openedx_learning/decisions/images/pathway-item-fulfillment.svg b/docs/openedx_learning/decisions/images/pathway-item-fulfillment.svg new file mode 100644 index 000000000..94b29dc44 --- /dev/null +++ b/docs/openedx_learning/decisions/images/pathway-item-fulfillment.svg @@ -0,0 +1,81 @@ + + + + + + +pathway_item_fulfillment + + + +item + +Pathway Item + + + +runA + +Course Run A1 +(default: enroll here) + + + +item->runA + + +pass any one + + + +runB + +Course Run A2 +(older run, still counts) + + + +item->runB + + + + + +runC + +Course Run B1 +(different catalog course) + + + +item->runC + + + + + +future + +future fulfillment types: +section completion, +competency, admin override + + + +item->future + + + + + +grading +passed/failed read directly +from each course's +grading policy + + + +