# ADR-0008: Forking, Remixing, and Attribution Lineage - **Status:** Accepted - **Date:** 2024-06-02 - **Deciders:** FablePool core team - **Related:** ADR-0005 (CC BY-SA), ADR-0007 (versioning), `docs/architecture/04-versioning-and-forking.md` ## Context The brief requires problems and courses to be *forkable, remixable, and attributable*. Forking serves several distinct needs that one mechanism must cover: - **Improvement forks:** "this problem is good but the hints are weak." - **Variant forks:** translated versions, easier/harder variants, curriculum-specific adaptations. - **Remix into courses:** a course author includes someone else's problem, possibly modified. - **Disagreement forks:** the original author declines a change; the community can route around without hostility. CC BY-SA (ADR-0005) makes all of this lawful; the platform must make it *traceable and credited*. ## Decision Implement the lineage model of `04-versioning-and-forking.md`: 1. **Fork = new entity with lineage.** Forking problem P at version V creates problem P′ owned by the forker, whose first draft is a copy of V's content, with `forked_from_version_id = V.id` recorded immutably on P′. Course forks deep-link contained problems by reference (no implicit mass-forking of every problem). 2. **Lineage is append-only and public.** Every problem/course page shows its ancestry chain ("forked from *X* by *A*, which was forked from…") and a list of public forks. The `attribution` block in the content schema serializes this chain into exports. 3. **Forks go through the same review pipeline** to publish. A fork with trivial differences from an already-published ancestor is a valid rejection reason ("insufficient differentiation") to prevent leaderboard farming via copy-publishing. 4. **Merge-back is by patch, not by git-merge.** A forker can open a *suggested revision* against the upstream entity: structurally, a new draft version on the upstream whose parent is the upstream's current version, carrying `suggested_by` credit. The upstream owner (or reviewers, if the owner is inactive > 60 days) routes it through normal review. We deliberately avoid three-way content merging in the MVP. 5. **Reputation flows along lineage:** when a fork is published, the ancestor's authors receive a small reputation credit; when a suggested revision is accepted, the suggester is added to the version's contributor list. This makes being forked desirable rather than threatening. 6. **Private forks do not exist.** Drafts are private; forks of *published* content are public from creation (the lineage link is visible even while the fork is a draft). This prevents covert appropriation. ## Alternatives Considered - **Git-style branches within one entity.** Conflates "variant by another author" with "edit by the same author"; permissioning branches per-user inside one entity is far more complex than separate entities with lineage. Rejected. - **Copy without lineage (manual attribution).** Violates BY in practice and destroys the reputation economy. Rejected. - **Automatic three-way merge of suggested revisions.** JSON+MDX merging has poor conflict semantics; review of a whole proposed version is simpler and matches the review pipeline we already have. Deferred, not rejected — field-level merge assistance may come later. - **Transclusion (live reference to upstream version) instead of fork.** Courses *do* use version-pinned references for inclusion; but for modification, live references would let upstream edits silently change downstream content. Pin-by-version + explicit fork chosen instead. ## Consequences - ✅ Every reuse path (improve, translate, remix, disagree) has a sanctioned mechanism with automatic attribution and reputation credit. - ✅ Exported OER bundles carry full machine-readable lineage, satisfying CC BY downstream. - ⚠️ Fork spam is possible; mitigated by the "insufficient differentiation" review ground and rate limits on fork creation for low-reputation users. - ⚠️ Lineage chains can grow long; the UI shows immediate parent + root and folds the middle. The full chain stays in the data and exports. - ⚠️ No automatic merge means popular upstreams may accumulate divergent forks; the suggested-revision flow plus inactivity takeover (60-day rule) is our pressure valve, to be re-evaluated with real usage data.