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
create
  make(
    task_id: String,
    origin: String,
    destination: String,
    status: String,
    assigned_robot_id: String
  ) do
    this.task_id := task_id
    this.origin := origin
    this.destination := destination
    this.status := status
    this.assigned_robot_id := assigned_robot_id
  end
feature
  task_id: String
  origin: String
  destination: String
  status: String
  assigned_robot_id: String
invariant
  id_present: task_id /= ""
end

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

class Doc_Link
create
  make(from_doc_id: String, to_doc_id: String, link_type: String) do
    this.from_doc_id := from_doc_id
    this.to_doc_id := to_doc_id
    this.link_type := link_type
  end
feature
  from_doc_id: String
  to_doc_id: String
  link_type: String
invariant
  endpoints_present: from_doc_id /= "" 
                     and to_doc_id /= ""
end

class World_Object
create
  make(object_id: String, x: Integer, vx: Integer) do
    this.object_id := object_id
    this.x := x
    this.vx := vx
  end
feature
  object_id: String
  x: Integer
  vx: Integer

  shift(delta: Integer) do
    x := x + delta
  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(
    t1: Delivery_Task,
    t2: Delivery_Task,
    t3: Delivery_Task,
    t4: Delivery_Task,
    t5: Delivery_Task
  ) do
    this.t1 := t1
    this.t2 := t2
    this.t3 := t3
    this.t4 := t4
    this.t5 := t5
  end
feature
  t1: Delivery_Task
  t2: Delivery_Task
  t3: Delivery_Task
  t4: Delivery_Task
  t5: Delivery_Task

  find_status(task_id: String): Measure_Result
  require
    id_present: task_id /= ""
  do
    let steps: Integer := 1
    let value: String := "NOT_FOUND"
    if t1.task_id = task_id then
      value := t1.status
    elseif t2.task_id = task_id then
      steps := steps + 1
      value := t2.status
    elseif t3.task_id = task_id then
      steps := steps + 1
      value := t3.status
    elseif t4.task_id = task_id then
      steps := steps + 1
      value := t4.status
    elseif t5.task_id = task_id then
      steps := steps + 1
      value := t5.status
    else
      steps := steps + 1
    end

    result := create Measure_Result.make(value, steps)
  ensure
    bounded_steps: result.steps >= 1 
                   and result.steps <= 5
  end
end

class Delivery_Task_Store_V3
create
  make(
    k1: String, v1: Delivery_Task,
    k2: String, v2: Delivery_Task,
    k3: String, v3: Delivery_Task,
    k4: String, v4: Delivery_Task,
    k5: String, v5: Delivery_Task
  ) do
    this.k1 := k1
    this.v1 := v1
    this.k2 := k2
    this.v2 := v2
    this.k3 := k3
    this.v3 := v3
    this.k4 := k4
    this.v4 := v4
    this.k5 := k5
    this.v5 := v5
  end
feature
  -- Index from task id to 
  -- task object (teaching-sized map form).
  k1: String
  v1: Delivery_Task
  k2: String
  v2: Delivery_Task
  k3: String
  v3: Delivery_Task
  k4: String
  v4: Delivery_Task
  k5: String
  v5: Delivery_Task

  find_status(task_id: String): Measure_Result
  require
    id_present: task_id /= ""
  do
    let value: String := "NOT_FOUND"
    if task_id = k1 then
      value := v1.status
    elseif task_id = k2 then
      value := v2.status
    elseif task_id = k3 then
      value := v3.status
    elseif task_id = k4 then
      value := v4.status
    elseif task_id = k5 then
      value := v5.status
    end

    result := create Measure_Result.make(value, 1)
  ensure
    constant_step: 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(
    w1: World_Object,
    w2: World_Object,
    w3: World_Object,
    w4: World_Object
  ) do
    this.w1 := w1
    this.w2 := w2
    this.w3 := w3
    this.w4 := w4
  end
feature
  w1: World_Object
  w2: World_Object
  w3: World_Object
  w4: World_Object

  move_by_id(object_id: String,
             delta: Integer): Measure_Result
  require
    id_present: object_id /= ""
  do
    let value: String := "NOT_FOUND"
    let steps: Integer := 1
    if w1.object_id = object_id then
      w1.shift(delta)
      value := "UPDATED"
    elseif w2.object_id = object_id then
      steps := steps + 1
      w2.shift(delta)
      value := "UPDATED"
    elseif w3.object_id = object_id then
      steps := steps + 1
      w3.shift(delta)
      value := "UPDATED"
    elseif w4.object_id = object_id then
      steps := steps + 1
      w4.shift(delta)
      value := "UPDATED"
    else
      steps := steps + 1
    end

    result := create Measure_Result.make(value, steps)
  ensure
    bounded_steps: result.steps >= 1 
                   and result.steps <= 4
  end
end

class World_Model_V3
create
  make(wk1: String, wv1: World_Object) do
    this.wk1 := wk1
    this.wv1 := wv1
  end
feature
  wk1: String
  wv1: World_Object

  move_by_id(object_id: String,
             delta: Integer): Measure_Result
  require
    id_present: object_id /= ""
  do
    let value: String := "NOT_FOUND"
    if object_id = wk1 then
      wv1.shift(delta)
      value := "UPDATED"
    end

    result := create Measure_Result.make(value, 1)
  ensure
    constant_step: 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)
    let t1: Delivery_Task
      := create Delivery_Task.make(
           "T-1", "Hub-A", "Zone-1", "PENDING", "R-1"
         )
    let t2: Delivery_Task
      := create Delivery_Task.make(
           "T-2", "Hub-A", "Zone-2", "IN_TRANSIT", "R-2"
         )
    let t3: Delivery_Task
      := create Delivery_Task.make(
           "T-3", "Hub-B", "Zone-3", "FAILED", "R-3"
         )
    let t4: Delivery_Task
      := create Delivery_Task.make(
           "T-4", "Hub-B", "Zone-4", "DELIVERED", "R-4"
         )
    let t5: Delivery_Task
      := create Delivery_Task.make(
           "T-5", "Hub-C", "Zone-5", "PENDING", "R-5"
         )

    let d_v2: Delivery_Task_Store_V2 
     := create Delivery_Task_Store_V2.make(t1, t2, t3, t4, t5)

    let d_v3: Delivery_Task_Store_V3 
     := create Delivery_Task_Store_V3.make(
         t1.task_id, t1,
         t2.task_id, t2,
         t3.task_id, t3,
         t4.task_id, t4,
         t5.task_id, t5
       )

    let d2r: Measure_Result 
     := d_v2.find_status("T-5")
    let d3r: Measure_Result 
     := d_v3.find_status("T-5")
    print("Delivery V2 steps: " + d2r.steps)
    print("Delivery V3 steps: " + d3r.steps)

    -- Knowledge documents + links 
    -- (Studio 2 model objects)
    let doc1: Document
      := create Document.make("D-1", "Graphs", "Graph notes")
    let doc2: Document
      := create Document.make("D-2", "Trees", "Tree notes")
    let doc3: Document
      := create Document.make("D-3", "Maps", "Map notes")

    let link: Doc_Link
      := create Doc_Link.make("D-1", "D-3", "references")

    let k_v2: Knowledge_Model_V2 
     := create Knowledge_Model_V2.make(doc1, doc2, doc3, link, link)

    let k_v3: Knowledge_Model_V3 
     := create Knowledge_Model_V3.make(
         doc1.doc_id, doc1,
         doc2.doc_id, doc2,
         doc3.doc_id, doc3
       )

    let k2r: Measure_Result := k_v2.validate_link(link)
    let k3r: Measure_Result := 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 o1: World_Object := create World_Object.make("E-1", 1, 0)
    let o2: World_Object := create World_Object.make("E-2", 2, 0)
    let o3: World_Object := create World_Object.make("E-3", 3, 0)
    let o4: World_Object := create World_Object.make("E-4", 4, 0)

    let w_v2: World_Model_V2
      := create World_Model_V2.make(o1, o2, o3, o4)

    let w_v3: World_Model_V3
      := create World_Model_V3.make(o4.object_id, o4)

    let w2r: Measure_Result := w_v2.move_by_id("E-4", 3)
    let w3r: Measure_Result := w_v3.move_by_id("E-4", 3)
    print("World V2 steps: " + w2r.steps)
    print("World V3 steps: " + w3r.steps)
  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