{
  "format": "recallweave-deck/1",
  "title": "Causal order with Lamport and vector clocks",
  "attribution": "Original questions, examples, explanations and transfer prompts by HAMON contributors for RecallWeave (2026). Mathematical sources: Leslie Lamport, Time, Clocks, and the Ordering of Events in a Distributed System (1978), https://lamport.azurewebsites.net/pubs/time-clocks.pdf; Friedemann Mattern, Virtual Time and Global States of Distributed Systems (1989), https://vs.inf.ethz.ch/publ/papers/VirtTimeGlobStates.pdf. The source papers supply the definitions and algorithms; these lesson questions and the worked event graph are original.",
  "license": "Original lesson text and examples: Creative Commons Attribution 4.0 International (CC BY 4.0), https://creativecommons.org/licenses/by/4.0/. Attribution: HAMON contributors for RecallWeave, Causal order with Lamport and vector clocks, 2026. This permission covers the original lesson, not the linked source papers.",
  "concepts": [
    "causal-order",
    "lamport-clocks",
    "vector-clocks",
    "reading-concurrency"
  ],
  "items": [
    {
      "id": "lc-causal-send",
      "concept": "causal-order",
      "prerequisites": [],
      "prompt": "A sends message m at event S, and B receives that same message at distinct event R. In the happens-before relation generated by program order, message delivery and transitivity, which statement holds?",
      "options": [
        "R happens before S because receiving reveals the message.",
        "S and R are concurrent because they are on different processes.",
        "S happens before R.",
        "S and R must have the same logical timestamp."
      ],
      "answer": 2,
      "explanation": "A message send is a generating edge of happens-before to the corresponding receive: S → R. Different processes can be causally connected. The sender and receiver record distinct events, and a correct scalar clock assigns the receive a strictly larger value than the send.",
      "transfer": "Sketch a request and its reply. Include the receive and the later reply-send as separate events, then mark a transitive path from the original request-send to the reply-receive."
    },
    {
      "id": "lc-causal-chain",
      "concept": "causal-order",
      "prerequisites": [],
      "prompt": "A sends at A1. B receives that message at B2, then sends a new message at B3. C receives B's message at C2. The receive at B2 and send at B3 are distinct events in that program order. Which relation follows?",
      "options": [
        "C2 happens before A1.",
        "A1 happens before C2.",
        "A1 and C2 are concurrent until clocks are assigned.",
        "B3 happens before B2."
      ],
      "answer": 1,
      "explanation": "The path is A1 → B2 → B3 → C2. The first and last edges are message deliveries; B2 → B3 is B's program order. Transitivity gives A1 → C2. Clocks describe this relation; assigning timestamps is not what creates it.",
      "transfer": "In a three-service workflow, identify the actual send/receive and local-order edges that let information from the first service reach the third."
    },
    {
      "id": "lc-causal-fork",
      "concept": "causal-order",
      "prerequisites": [],
      "prompt": "The complete event graph has program order A1 → A2 → A3 and B1 → B2 → B3. Its only message edge is A2 → B2. Here → denotes a generating happens-before edge. How are A3 and B3 related?",
      "options": [
        "They are concurrent: neither has a directed path to the other.",
        "A3 happens before B3 because A3 follows the send at A2.",
        "B3 happens before A3 because B received A's message.",
        "They are the same event because both have local index 3."
      ],
      "answer": 0,
      "explanation": "A2 reaches both later A3 and B3, but sharing a predecessor does not create a path between those later events. A3 cannot travel backward to A2, and no message leaves A3 for B. Neither A3 → B3 nor B3 → A3 exists, so they are concurrent in this complete graph. That does not claim physical simultaneity.",
      "transfer": "Draw a common ancestor with two descendants. Explain why evidence that both descendants depend on the ancestor does not establish an order between the descendants."
    },
    {
      "id": "lc-causal-wall-time",
      "concept": "causal-order",
      "prerequisites": [],
      "prompt": "Two different processes log events a at 10:00:01 and b at 10:00:02 using wall clocks whose offsets and synchronization error are unknown. No program-order or communication relationship between the events is supplied. What do these two readings establish by themselves?",
      "options": [
        "a causally precedes b by exactly one second.",
        "a physically occurred first, although causality remains unknown.",
        "The events are concurrent because the readings differ.",
        "Neither a causal relation nor which event physically occurred first."
      ],
      "answer": 3,
      "explanation": "Unknown clock offsets can reverse the apparent order of these readings. The readings supply no message or program-order path between the events, so they do not establish causality either. The available evidence also does not prove concurrency: an unreported causal path may exist. 'Unknown' is different from 'known concurrent in a complete graph.'",
      "transfer": "When inspecting logs from two machines, list the synchronization bounds and communication evidence you would need before making an ordering claim."
    },
    {
      "id": "lc-lamport-send",
      "concept": "lamport-clocks",
      "prerequisites": [
        "causal-order"
      ],
      "prompt": "A process starts with Lamport counter 0. Each local event or send increments its counter by 1, and a send carries the resulting value. It performs two local events, then sends a message. What timestamp does the message carry?",
      "options": [
        "2",
        "3",
        "1",
        "0"
      ],
      "answer": 1,
      "explanation": "The counter starts at 0, becomes 1 at the first local event and 2 at the second, then increments to 3 for the send. The message carries the send event's post-increment value. These are event counters, not elapsed seconds.",
      "transfer": "If another local event is inserted before this send, recompute the sent value and explain why the difference says nothing about how long the event took."
    },
    {
      "id": "lc-lamport-receive-low",
      "concept": "lamport-clocks",
      "prerequisites": [
        "causal-order"
      ],
      "prompt": "A Lamport counter is 7 immediately before a receive. The incoming message carries timestamp 3. The receive rule is max(local counter, message timestamp) + 1. What timestamp is assigned to this receive event?",
      "options": [
        "4",
        "7",
        "10",
        "8"
      ],
      "answer": 3,
      "explanation": "max(7, 3) + 1 = 8. The receive follows both the receiver's already-recorded history and the send represented by the incoming timestamp. Replacing 7 with 3 would move the local clock backward; adding the two counters is not the receive rule.",
      "transfer": "Suppose a local counter is 12 and a delayed message is stamped 4. Calculate the receive timestamp and identify the larger constraint."
    },
    {
      "id": "lc-lamport-receive-high",
      "concept": "lamport-clocks",
      "prerequisites": [
        "causal-order"
      ],
      "prompt": "A process has Lamport counter 2. It receives a message stamped 8 using max(local, message) + 1, then performs one local event, which increments by 1. What are the receive timestamp and the following local-event timestamp, in that order?",
      "options": [
        "9, then 10",
        "8, then 9",
        "3, then 4",
        "11, then 12"
      ],
      "answer": 0,
      "explanation": "The receive uses max(2, 8) + 1 = 9. The subsequent local event increments 9 to 10. The receive can jump over unused scalar values; it does not claim the process executed every skipped count or waited that many time units.",
      "transfer": "Calculate a receive followed by a send when the local counter is 5 and the incoming timestamp is 11. State the value actually attached to the outgoing message."
    },
    {
      "id": "lc-lamport-one-way",
      "concept": "lamport-clocks",
      "prerequisites": [
        "causal-order"
      ],
      "prompt": "Correct Lamport clocks give distinct events a and b timestamps L(a) = 4 and L(b) = 9. The clock condition says that causal precedence implies a strictly smaller timestamp. What can you conclude?",
      "options": [
        "a must causally precede b.",
        "a and b must be concurrent.",
        "b cannot causally precede a; a may precede b or be concurrent with b.",
        "b must causally precede a because its timestamp is larger."
      ],
      "answer": 2,
      "explanation": "If b causally preceded a, the clock condition would require L(b) < L(a), which contradicts 9 > 4. That direction is therefore impossible. The smaller timestamp of a is compatible with a preceding b and also with a being concurrent with b; scalar order alone does not choose between those cases.",
      "transfer": "Find two concurrent events in the worked graph that have different Lamport timestamps. Explain the useful direction that the inequality rules out and the direction it fails to prove."
    },
    {
      "id": "lc-vector-send",
      "concept": "vector-clocks",
      "prerequisites": [
        "lamport-clocks"
      ],
      "prompt": "Vector components are ordered [A, B, C] and start at [0, 0, 0]. Each local event or send increments only the acting process's component before recording or sending the vector. B performs one local event, then sends. What vector does this message carry?",
      "options": [
        "[2, 0, 0]",
        "[0, 1, 0]",
        "[1, 1, 1]",
        "[0, 2, 0]"
      ],
      "answer": 3,
      "explanation": "B owns the middle component. Its local event changes [0, 0, 0] to [0, 1, 0], and its send changes that to [0, 2, 0]. With no received messages, B has learned nothing about A or C. A vector is recorded after the event's increment in this convention.",
      "transfer": "If C instead performs three local events and then sends without receiving anything, write its outgoing [A, B, C] vector."
    },
    {
      "id": "lc-vector-receive",
      "concept": "vector-clocks",
      "prerequisites": [
        "lamport-clocks"
      ],
      "prompt": "Components are [A, B, C]. Immediately before receiving a message, C has vector [2, 0, 4]. The message carries [1, 3, 2]. A receive takes the componentwise maximum, then increments C's component once. What vector labels the receive event?",
      "options": [
        "[1, 3, 3]",
        "[2, 3, 5]",
        "[3, 4, 5]",
        "[2, 3, 4]"
      ],
      "answer": 1,
      "explanation": "The componentwise maximum of [2, 0, 4] and [1, 3, 2] is [2, 3, 4]. Increment the receiver's C component once to get [2, 3, 5]. The lower A and C values in the message do not erase local knowledge; the message does add B's history through count 3.",
      "transfer": "Try a receive whose incoming vector is smaller in every component. Explain why the receiver still records a new event even though the merge adds no remote information."
    },
    {
      "id": "lc-vector-strict-order",
      "concept": "vector-clocks",
      "prerequisites": [
        "lamport-clocks"
      ],
      "prompt": "Assume standard vector clocks that record every relevant event and message, with no resets. Define u < v to mean every component of u is at most the corresponding component of v, with at least one strict inequality. Distinct events have vectors [2, 1, 0] and [2, 3, 1]. What follows?",
      "options": [
        "The events are concurrent because their A components are equal.",
        "The second event causally precedes the first.",
        "The first event causally precedes the second.",
        "No relation is available unless every component is strictly smaller."
      ],
      "answer": 2,
      "explanation": "Compare components: 2 ≤ 2, 1 ≤ 3 and 0 ≤ 1, with strict inequalities in B and C. The first vector is strictly below the second under the stated definition. In the standard complete model this means the first event causally precedes the second. Requiring every component to be strictly smaller would wrongly discard causal links that leave other processes' knowledge unchanged.",
      "transfer": "Compare [1, 0, 0] with [2, 0, 0]. Explain why two unchanged components do not make the corresponding events concurrent."
    },
    {
      "id": "lc-vector-incomparable",
      "concept": "vector-clocks",
      "prerequisites": [
        "lamport-clocks"
      ],
      "prompt": "Under standard, complete vector-clock instrumentation with no resets, distinct events a and b have vectors [3, 1, 0] and [2, 2, 0]. Causal precedence corresponds to componentwise ≤ with at least one strict component. Which relation holds?",
      "options": [
        "The events are concurrent: each vector exceeds the other in a different component.",
        "a causally precedes b because its component sum is smaller.",
        "b causally precedes a because its A component is smaller.",
        "The events are identical because their component sums are equal."
      ],
      "answer": 0,
      "explanation": "The first vector has more A history (3 > 2), while the second has more B history (2 > 1). Neither is componentwise at most the other, so the vectors are incomparable and the distinct events are concurrent under the stated model. Adding components or comparing one chosen component loses this information.",
      "transfer": "Construct another pair of incomparable three-component vectors, and point to one coordinate that blocks each possible ordering."
    },
    {
      "id": "lc-reading-scalar-trap",
      "concept": "reading-concurrency",
      "prerequisites": [
        "causal-order",
        "lamport-clocks",
        "vector-clocks"
      ],
      "prompt": "In a correctly and completely instrumented execution, A3 has Lamport timestamp 3 and vector [3, 0, 0]; C3 has Lamport timestamp 6 and vector [2, 3, 3]. Which interpretation is valid?",
      "options": [
        "A3 caused C3 because 3 < 6.",
        "C3 caused A3 because C3's B and C components are larger.",
        "The clock implementations disagree, so one timestamp must be invalid.",
        "A3 and C3 are concurrent; the scalar inequality does not prove causality."
      ],
      "answer": 3,
      "explanation": "A3's A component is larger (3 > 2), but C3's B and C components are larger (3 > 0). The vectors are incomparable. Their valid scalar timestamps can still satisfy 3 < 6 because the Lamport clock condition is one-way. In the worked graph, A2 sent before A3 occurred, so A3 is not part of the history carried onward to C3.",
      "transfer": "Trace the message chain A2 → B2 → B3 → C2 → C3 and identify exactly which local A event is absent from that chain."
    },
    {
      "id": "lc-reading-equal-components",
      "concept": "reading-concurrency",
      "prerequisites": [
        "causal-order",
        "lamport-clocks",
        "vector-clocks"
      ],
      "prompt": "In a complete execution, B3 sends a message with vector [2, 3, 0]. C receives it at C2 and records [2, 3, 2]. The listed send and receive are distinct. Which reading is correct?",
      "options": [
        "B3 causally precedes C2; equality in A and B does not prevent strict vector order.",
        "The events are concurrent because two components are equal.",
        "C2 causally precedes B3 because its C component is greater.",
        "All three components must differ before a message can carry causal information."
      ],
      "answer": 0,
      "explanation": "The explicit send-to-receive edge already establishes B3 → C2. The vector comparison agrees: [2, 3, 0] is componentwise at most [2, 3, 2], with a strict C component. Equality in A and B is allowed. C's local history and this receive explain why the last component is 2.",
      "transfer": "Use C's pre-receive vector [0, 0, 1] to calculate max([0, 0, 1], [2, 3, 0]) plus one C event."
    },
    {
      "id": "lc-reading-tie-break",
      "concept": "reading-concurrency",
      "prerequisites": [
        "causal-order",
        "lamport-clocks",
        "vector-clocks"
      ],
      "prompt": "Distinct events A3 and B2 both have valid Lamport timestamp 3. A system orders all events lexicographically by (Lamport timestamp, process ID), with A before B. What does placing A3 before B2 mean?",
      "options": [
        "The process-ID tie-break proves A3 caused B2.",
        "The tie-break chooses an order for these concurrent events; it creates no causal edge.",
        "B2 must physically occur later by one clock tick.",
        "Equal Lamport timestamps make this total ordering impossible."
      ],
      "answer": 1,
      "explanation": "Causally ordered distinct events must have strictly increasing Lamport timestamps. These equal timestamps therefore rule out either causal direction in a valid execution. The process-ID tie-break chooses A3 before B2 to make a total order, but it adds no message or program-order edge and says nothing about elapsed physical time.",
      "transfer": "Reverse the agreed process-ID order. Explain what happens to the A3/B2 tie and what remains unchanged in the causal graph."
    },
    {
      "id": "lc-reading-conflict-policy",
      "concept": "reading-concurrency",
      "prerequisites": [
        "causal-order",
        "lamport-clocks",
        "vector-clocks"
      ],
      "prompt": "Two document edits have incomparable vector clocks in a model that records all relevant edit events and communications. What does this establish, and what must the application still decide?",
      "options": [
        "The edits are duplicates, so it can discard either without inspecting content.",
        "The edit with the larger component sum is the correct version.",
        "The edits are concurrent; a content or conflict-resolution policy must still decide how to handle them.",
        "Vector clocks authenticate both authors and identify which text is factually correct."
      ],
      "answer": 2,
      "explanation": "Incomparable vectors establish concurrency within the stated event and communication model. They do not choose the appropriate merged document, settle a semantic conflict, authenticate a writer or establish factual truth. The application still needs a content-aware merge rule, a user decision or another explicit policy.",
      "transfer": "Describe a concurrent change to a document title and a concurrent change to its body. Then describe two competing edits to the same word. Why might the application handle these cases differently even though both are concurrent?"
    }
  ]
}
