Studio 3

The Scaling Crisis

Refactoring Studio 2 models for scale without losing correctness.

The Situation

Studio 2 gave us explicit entities, relationships, and invariants, and the models are still correct. What has changed is volume: thousands of delivery tasks, documents, links, and world objects. Looking up a task’s status, checking that a link points at a real document, and finding the object to move all scan a list from the start, so their cost grows with every item we add. The fix belongs in how we reach the objects, not in the objects themselves. The symptoms:

  • latency spikes on common lookups
  • repeated linear scans in hot paths (the operations that run most often)
  • update loops that do unnecessary work

Engineering Brief

Keep the Studio 2 model semantics. Improve runtime behavior.

Required outcomes:

  • identify one bottleneck operation per domain
  • show a before-and-after refactor using Studio 2 classes
  • measure operation-count improvement
  • preserve behavior contracts and invariants

Implementation guidance:

  • optimize access paths, not domain meaning
  • use explicit failure statuses (NOT_FOUND, NO_MATCH, etc.)
  • keep model classes intact; add indexing and organization layers around them

Implementation In Nex

Use operation counts to compare baseline and refactored paths.

Suggested files:

  • delivery_scale_from_studio2.nex
  • knowledge_scale_from_studio2.nex
  • world_scale_from_studio2.nex
  • studio_3_main.nex

Reused Studio 2 Models (Unchanged)

class Delivery_Task
feature
  task_id: String
  origin: String
  destination: String
  status: String
  assigned_robot_id: String

  assign(robot_id: String)
  require
    robot_present: robot_id /= ""
    can_assign: status = "PENDING" 
                or status = "FAILED"
  do
    assigned_robot_id := robot_id
    status := "IN_TRANSIT"
  ensure
    assigned: assigned_robot_id = robot_id 
              and status = "IN_TRANSIT"
  end

  complete()
  require
    in_transit: status = "IN_TRANSIT"
  do
    status := "DELIVERED"
  ensure
    delivered: status = "DELIVERED"
  end

  fail(reason: String)
  require
    reason_present: reason /= ""
    not_delivered: status /= "DELIVERED"
  do
    status := "FAILED"
  ensure
    failed: status = "FAILED"
  end
create
  pending(task_id: String, origin: String, 
          destination: String) do
    this.task_id := task_id
    this.origin := origin
    this.destination := destination
    this.status := "PENDING"
  end
invariant
  id_present: task_id /= ""
  endpoints_present: origin /= "" 
                     and destination /= ""
  valid_status:
    status = "PENDING" or status = "IN_TRANSIT" 
             or status = "DELIVERED" 
             or status = "FAILED"
  in_transit_has_robot:
    status /= "IN_TRANSIT" 
    or assigned_robot_id /= ""
end

class Document
feature
  doc_id: String
  title: String
  body: String
create
  make(doc_id: String, title: String) do
    this.doc_id := doc_id
    this.title := title
  end
invariant
  id_present: doc_id /= ""
  title_present: title /= ""
end

class Doc_Link
feature
  from_doc_id: String
  to_doc_id: String
  link_type: String

  is_valid(): Boolean do
    result :=
      from_doc_id /= "" and
      to_doc_id /= "" and
      from_doc_id /= to_doc_id and
      (link_type = "references" 
       or link_type = "related" 
       or link_type = "contradicts")
  end
create
  make(f: String, t: String, lt: String) do
    from_doc_id := f
    to_doc_id := t
    link_type := lt
  end
invariant
  endpoints_present: from_doc_id /= "" 
                     and to_doc_id /= ""
  no_self_link: from_doc_id /= to_doc_id
end

class World_Object
feature
  object_id: String
  x: Integer
  vx: Integer

  step(max_x: Integer)
  require
    valid_bound: max_x >= 0
  do
    let next: Integer := x + vx
    if next < 0 then
      x := 0
    elseif next > max_x then
      x := max_x
    else
      x := next
    end
  ensure
    bounded_after_step: x >= 0 and x <= max_x
  end
create
  make(id: String, x: Integer, vx: Integer) do
    object_id := id
    this.x := x
    this.vx := vx
  end
invariant
  id_present: object_id /= ""
end

class Measure_Result
create
  make(value: String, steps: Integer) do
    this.value := value
    this.steps := steps
  end
feature
  value: String
  steps: Integer
invariant
  value_present: value /= ""
  non_negative_steps: steps >= 0
end

Delivery Refactor: Task Lookup

Before (Studio 2-style collection usage): linear scan over Delivery_Task objects.

After: index layer for direct key access while keeping Delivery_Task as source object.

class Delivery_Task_Store_V2
create
  make(tasks: Array[Delivery_Task]) do
    this.tasks := tasks
  end
feature
  tasks: Array[Delivery_Task]

  find_status(task_id: String): Measure_Result
  require
    id_present: task_id /= ""
  do
    let value: String := "NOT_FOUND"
    let steps: Integer := 0
    from let i := 0
    until i >= tasks.length or value /= "NOT_FOUND" do
      steps := steps + 1
      if tasks.get(i).task_id = task_id then
        value := tasks.get(i).status
      end
      i := i + 1
    end
    result := create Measure_Result.make(value, steps)
  ensure
    bounded_steps: result.steps <= tasks.length
  end
end

class Delivery_Task_Store_V3
create
  make(tasks: Array[Delivery_Task]) do
    -- Index derived from model identity: task_id.
    by_id := {}
    across tasks as t do
      by_id.put(t.task_id, t)
    end
  end
feature
  by_id: Map[String, Delivery_Task]

  find_status(task_id: String): Measure_Result
  require
    id_present: task_id /= ""
  do
    let value: String := "NOT_FOUND"
    if by_id.contains_key(task_id) then
      value := by_id.get(task_id).status
    end
    result := create Measure_Result.make(value, 1)
  ensure
    one_lookup: result.steps = 1
  end
end

Virtual World Refactor: Targeted Update

Before: scan all World_Object entries to find target.

After: id index for direct target selection, then apply same position update semantics.

class World_Model_V2
create
  make(objects: Array[World_Object]) do
    this.objects := objects
  end
feature
  objects: Array[World_Object]

  step_by_id(object_id: String,
             max_x: Integer): Measure_Result
  require
    id_present: object_id /= ""
    valid_bound: max_x >= 0
  do
    let value: String := "NOT_FOUND"
    let steps: Integer := 0
    from let i := 0
    until i >= objects.length or value = "UPDATED" do
      steps := steps + 1
      if objects.get(i).object_id = object_id then
        objects.get(i).step(max_x)
        value := "UPDATED"
      end
      i := i + 1
    end
    result := create Measure_Result.make(value, steps)
  ensure
    bounded_steps: result.steps <= objects.length
  end
end

class World_Model_V3
create
  make(objects: Array[World_Object]) do
    by_id := {}
    across objects as w do
      by_id.put(w.object_id, w)
    end
  end
feature
  by_id: Map[String, World_Object]

  step_by_id(object_id: String,
             max_x: Integer): Measure_Result
  require
    id_present: object_id /= ""
    valid_bound: max_x >= 0
  do
    let value: String := "NOT_FOUND"
    if by_id.contains_key(object_id) then
      by_id.get(object_id).step(max_x)
      value := "UPDATED"
    end
    result := create Measure_Result.make(value, 1)
  ensure
    one_lookup: result.steps = 1
  end
end

Studio Driver (Before and After on Studio 2 Models)

class App
feature
  run() do
    -- Delivery tasks (Studio 2 model objects, 
    -- moved through Studio 2 transitions)
    let t1 := create Delivery_Task.pending("T-1", "Hub-A", "Zone-1")
    let t2 := create Delivery_Task.pending("T-2", "Hub-A", "Zone-2")
    let t3 := create Delivery_Task.pending("T-3", "Hub-B", "Zone-3")
    let t4 := create Delivery_Task.pending("T-4", "Hub-B", "Zone-4")
    let t5 := create Delivery_Task.pending("T-5", "Hub-C", "Zone-5")
    t2.assign("R-2")
    t3.assign("R-3")
    t3.fail("robot offline")
    t4.assign("R-4")
    t4.complete
    let tasks: Array[Delivery_Task] := [t1, t2, t3, t4, t5]
    let d_v2 := create Delivery_Task_Store_V2.make(tasks)
    let d_v3 := create Delivery_Task_Store_V3.make(tasks)
    let d2r := d_v2.find_status("T-5")
    let d3r := d_v3.find_status("T-5")
    print("Delivery V2 status/steps: " + d2r.value 
          + "/" + d2r.steps)
    print("Delivery V3 status/steps: " + d3r.value 
          + "/" + d3r.steps)
    -- Knowledge documents + links 
    -- (Studio 2 model objects)
    let docs: Array[Document] := [
      create Document.make("D-1", "Graphs"),
      create Document.make("D-2", "Trees"),
      create Document.make("D-3", "Maps")
    ]
    let link := create Doc_Link.make("D-1", "D-3", "references")
    let k_v2 := create Knowledge_Model_V2.make(docs)
    let k_v3 := create Knowledge_Model_V3.make(docs)
    let k2r := k_v2.validate_link(link)
    let k3r := k_v3.validate_link(link)
    print("Knowledge V2 status/steps: " + k2r.value 
          + "/" + k2r.steps)
    print("Knowledge V3 status/steps: " + k3r.value 
          + "/" + k3r.steps)
    -- World objects (Studio 2 model objects)
    let objects: Array[World_Object] := [
      create World_Object.make("E-1", 1, 0),
      create World_Object.make("E-2", 2, 0),
      create World_Object.make("E-3", 3, 0),
      create World_Object.make("E-4", 4, 3)
    ]
    let w_v2 := create World_Model_V2.make(objects)
    let w_v3 := create World_Model_V3.make(objects)
    let w2r := w_v2.step_by_id("E-4", 10)
    let w3r := w_v3.step_by_id("E-4", 10)
    print("World V2 status/steps: " + w2r.value 
          + "/" + w2r.steps)
    print("World V3 status/steps: " + w3r.value 
          + "/" + w3r.steps)
    print("E-4 x after both steps: " + objects.get(3).x)
  end
end

Expected pattern:

  • V2 keeps Studio 2 model semantics but uses scan-heavy access
  • V3 keeps the same model objects and adds index layers for critical operations
  • behavior stays consistent; operation counts improve

Studio Challenges

Level 1 — One Refactor

  • choose one Studio 2 operation with repeated scans
  • implement V2 baseline and V3 indexed refactor
  • compare step counts on hit and miss cases

Level 2 — Three-Domain Refactor

  • implement before-and-after versions for delivery, knowledge, and world
  • keep model classes unchanged
  • document where indexes are derived from model identity

Level 3 — Competing Strategies

  • for one domain, compare two refactors:
    • index-heavy approach
    • batch or partition approach
  • state when each approach wins

Postmortem

Discuss with evidence:

  • Which Studio 2 operation became the worst bottleneck and why?
  • Which refactor changed asymptotic behavior versus constants only?
  • Which invariant or contract protected correctness during optimization?
  • Which optimization should be postponed until higher load?

Deliverables

  • Nex code showing V2 (baseline) and V3 (refactor) on Studio 2 model classes
  • output logs with step-count comparisons
  • one-page design note:
    • bottleneck operation
    • chosen refactor
    • correctness safeguards
    • limitations and next trigger point

Exit Criteria

We are ready for Part V if:

  • we can optimize access paths without changing domain meaning
  • we can preserve model contracts while changing data organization
  • we can justify changes with measured evidence, not intuition
  • we can explain when the next redesign will be necessary