Index: org/transitions.org
===================================================================
--- org/transitions.org	(revision c1144fd13d1332dc1a70a49f1b21fe91f5c7565f)
+++ org/transitions.org	(revision c1144fd13d1332dc1a70a49f1b21fe91f5c7565f)
@@ -0,0 +1,201 @@
+FLEXO ID Decision Flowchart
+
+We assume:
+
+flexo_base_id = logical identity
+
+flexo_version = content evolution
+
+lifecycle suffix = process state
+
+fingerprint = canonical JSON hash
+
+STEP 0 — What is happening?
+
+You must classify the operation into one of three categories:
+
+State transition
+
+Content modification
+
+Logical duplication / fork
+
+Everything falls into one of these.
+
+FLOWCHART
+START
+  |
+  |-- Is this operation creating a new independent lineage?
+  |       (copy into new catalog? fork? split ownership?)
+  |
+  |-- YES --> Generate NEW flexo_base_id
+  |            flexo_version = 1
+  |            lifecycle_state = Draft
+  |            origin_flexo_id = previous full ID
+  |            END
+  |
+  |-- NO
+  |
+  |-- Is canonical content different from last saved version?
+  |       (compare normalized JSON, excluding lifecycle metadata)
+  |
+  |-- YES --> flexo_base_id stays the same
+  |            flexo_version = previous_version + 1
+  |            lifecycle_state = Draft
+  |            END
+  |
+  |-- NO
+  |
+  |-- Is this a lifecycle transition?
+  |
+  |-- YES --> flexo_base_id stays the same
+  |            flexo_version stays the same
+  |            lifecycle_state changes
+  |            END
+  |
+  |-- NO
+  |
+  |-- No ID change required
+         (metadata only, DB-only operation)
+         END
+Now Let’s Make It Concrete
+1️⃣ Logical Duplication (NEW BASE ID)
+
+Trigger conditions:
+
+Copy question into new catalog (independent evolution)
+
+Split catalog into two
+
+Fork domain for separate governance
+
+“Save as new” intentionally
+
+Effect:
+
+new_base_id = generate()
+version = 1
+state = Draft
+origin_flexo_id = previous full ID
+
+Strict rule:
+
+If future changes must not affect original lineage → new base ID.
+
+2️⃣ Content Modification (VERSION BUMP)
+
+Trigger:
+
+Canonical JSON changed (after normalization).
+
+Examples:
+
+Question text edited
+
+Options reordered (if order matters)
+
+Points changed
+
+Domain description changed
+
+Exam layout changed
+
+Embedded question snapshot changed
+
+Effect:
+
+base_id unchanged
+version += 1
+state = Draft
+
+Strict rule:
+
+If fingerprint changes → version bump.
+
+No exceptions.
+
+3️⃣ Lifecycle Transition (STATE ONLY)
+
+Trigger:
+
+Draft → Approved
+
+Approved → Signed
+
+Signed → Published
+
+Published → Obsolete
+
+Effect:
+
+base_id unchanged
+version unchanged
+state changes
+
+Strict rule:
+
+Lifecycle does not alter content version.
+
+Edge Case Handling
+Approved entity edited
+
+Flow:
+
+Content change detected
+
+Version bump
+
+State automatically reset to Draft
+
+So:
+
+BASE@001P → edit → BASE@002D
+
+Clean and auditable.
+
+Draft → Approved where draft ID is “temporary”
+
+Your earlier idea suggested generating new ID at approval.
+
+Under strict logic:
+
+That is unnecessary and breaks lineage.
+
+Instead:
+
+BASE@001D → BASE@001A
+
+Same logical identity.
+
+If you must isolate drafts operationally:
+Use different database tiers, not different IDs.
+
+* Decision Matrix Summary
+
+| Operation               | New Base ID | Version++  | State Change |
+|-------------------------+-------------+------------+--------------|
+| Copy/fork               |             | reset to 1 | Draft        |
+| Content edit            |             |            | Draft        |
+| State promotion         | No          | No         | Yes          |
+| Metadata-only DB change |             |            |              |
+
+One Important Constraint
+
+Fingerprint must exclude:
+
+- lifecycle_state
+- owner_id
+- DB storage metadata
+
+Otherwise state transitions would falsely trigger version bump.
+
+Fingerprint must represent semantic content only !!!
+
+Final Integrity Principle
+
+There must never exist:
+
+- two different canonical JSONs with same base ID + version
+- two identical canonical JSONs with different base ID (unless forked intentionally)
+
+If those invariants hold, your identity system is mathematically clean.
