The global half. A curated lesson is widened by editing src/seed/lessons.base.ts and running pnpm lessons:generate-migration; the generator detects the drift against its content hash and emits an UPDATE. That UPDATE sets content, the three axes, updatedAt and — when an embedded field moved — embedding = NULL. It touches neither counter (scripts/generate-lessons-migration.ts:186), so widening the most-consulted rows in the corpus leaves them ageing on the clock they had before anyone learned they applied more broadly.
A per-lesson OCCURRENCE marker in the authored source. The seed row gains an optional field naming the occurrence that prompted the widening — a MOTIR-<n> key. Its presence is what makes this correction an occurrence; its absence is what makes a correction editorial.
updateStatement emits the bump ONLY when that marker is present, and as a ledger insert plus a counter write, not a bare UPDATE: INSERT INTO "LessonOccurrence" … ON CONFLICT ("lessonId", "occurrenceRef") DO NOTHING, and the lastOccurredAt / recurrenceCount write guarded on that insert having happened. The chain stays forward-only and re-appliable in any order, which is the property every statement in this generator already has.
The generator ALREADY emits an UPDATE for any content drift: a typo fix, a reworded sentence, a retag. Bumping on drift would make every wording correction a fabricated occurrence and would make recurrenceCount lie at corpus scale — precisely the outcome LessonHumanOverride.exempt exists to avoid, arrived at from the other direction. The marker is what separates the two, and it is written by the person doing the widening because they are the only one who knows whether an incident prompted it.
lastOccurredAt and recurrenceCount by exactly one.UPDATE exactly as it does today and leaves both counters untouched. Asserted as its own test; this is the assertion that separates the rule from every edit bumps, and without it the rule is untested.ON CONFLICT DO NOTHING property the generator already guarantees, extended to the ledger.scripts/generate-lessons-migration.ts — updateStatement (:186), insertStatement / marker and the content-hash drift detection, the header block describing the forward-only chain.src/seed/lessons.base.ts — the authored source and BaseLessonSeed's shape.tests/helpers/lessonMigrationGuard.ts — where the generator's emitted SQL is already asserted.MOTIR-3547 (the parent) — the rule, stated once.