Skip to content

Flow: Session DeliveryΒΆ

Trigger: a session is started β€” either an operator picks a session and starts a delivery, or the scheduler automatically starts one from a booked timeslot.

Operator / Author summaryΒΆ

A Session orchestrates one or more Parts in a gated sequence. Each part is itself a timed resource that walks through the same phase flow; CPA drives the order (across parts and within a part), and SE does the automation inside the phases that need it. A classic single-lab delivery (LabletSession) is simply a session with one part.

flowchart LR
    subgraph Session
      direction LR
      P0["Part 1"] --> P1["Part 2"] --> P2["Part 3"]
    end
    P1 -.->|"within a part"| Q
    subgraph Q["Part phase flow"]
      direction LR
      A["instantiate"] --> C["ready"] --> D["student work"] --> E["collect & grade"] --> F["report"] --> G["teardown"]
    end
    style C fill:#0d9488,color:#fff
    style E fill:#0d9488,color:#fff
    style F fill:#0d9488,color:#fff
  • Session level β€” resolves its SessionDefinition into pinned parts, then activates parts in order, gating each on the previous. A later part's eager pod may provision early.
  • Part level β€” each part runs the phase flow below. A part may have 0 pods (e.g. a web-only DES design part) or one pod of any PodType.
  • instantiate / ready / collect & grade / report / teardown β€” as before, but per part.

Phases shaded teal are SE jobs; the rest are native LCM steps.

Examples: a Lablet = 1 part / 1 cml_on_aws pod; a CCIE exam = DES (no pod) β†’ DOO (eager hardware pod) β†’ AI-DOO (JIT cml_on_aws pod). See session-model.md for profiles.


Architect detailΒΆ

Session orchestration (across parts)ΒΆ

The Session manager resolves the SessionDefinition, pins each part's content via its selector (at schedule time), then activates parts in order with gating. Parts are sequential, but a later part's eager pod (large Timeslot.lead_time) may provision while an earlier part is still active.

sequenceDiagram
    autonumber
    participant OP as Operator / Scheduler
    participant SM as Session Mgr (CPA)
    participant PM as Part Mgr (CPA)
    participant PoM as Pod Mgr (controllers)
    participant SE as SE

    OP->>SM: set Session.desired = Active (from SessionDefinition)
    SM->>SM: resolve part selectors β†’ pin parts
    SM->>PM: set Part[DES].desired = Active (order 0)

    Note over PM: DES has no pod (web items)
    PM->>SE: workflow phase (grade web items)
    SE-->>PM: job.completed
    PM-->>SM: Part[DES] status = Completed

    Note over SM,PoM: eager pod for DOO provisioned early (overlap)
    SM->>PM: set Part[DOO].desired = Active (gated on DES)
    PM->>PoM: set Pod[hw-rack].desired = Ready (large lead_time)
    PoM-->>PM: Pod Ready
    PM->>SE: workflow phases (collect / grade)
    SE-->>PM: job.completed (ScoreReport)
    PM-->>SM: Part[DOO] status = Completed

    SM->>PM: set Part[AI-DOO].desired = Active
    PM->>PoM: set Pod[cml-aws].desired = Ready (JIT)
    PoM-->>PM: Pod Ready
    PM->>SE: workflow phases
    SE-->>PM: job.completed
    PM-->>SM: Part[AI-DOO] status = Completed
    SM-->>OP: Session Completed β†’ teardown cascade

Phase β†’ step/job binding (within a part)ΒΆ

Phase Native LCM step(s) SE JobDefinition (content) Process type
schedule schedule (resource-scheduler) β€” β€”
instantiate worker_lab_resolve, pod_locator, lab_start*, ports_alloc, lds_register lab_resolve@v1, lab_start@v1 β€”
ready mark_ready readiness_check@v1 Initialization β†’ ReadinessReport
collect & grade β€” collect_evidence@v1, grade_item@v1 Grading β†’ ScoreReport
report β€” score_report@v1 Grading β†’ ScoreReport
teardown archive lab_wipe@v1 Archive β†’ ArchiveReport

* lab_start is a content-driven SE job, but it is sequenced by CPA inside the instantiate phase β€” illustrating the split: CPA owns ordering, SE owns the job body.

Entry pointsΒΆ

Entry Who How
Manual Operator Selects a SessionDefinition and starts a Session.
Scheduled resource-scheduler Booked timeslot reaches its start time β†’ session auto-created.

Grading triggersΒΆ

Grading is not tied to a single moment. The collect & grade phase can be entered by:

  1. Operator on-demand β€” re-grade at any time.
  2. Scheduled β€” at timeslot end.
  3. Student submit β€” a submission event from the student.

Each trigger results in the same SE Collect→Evaluate→Report run; re-grading is idempotent and produces a new ScoreReport.

Sequence β€” single part (detail)ΒΆ

The per-part flow below is exactly the single-part LabletSession case; in a multi-part session it runs once per part under the Part manager.

sequenceDiagram
    autonumber
    participant OP as Operator / Scheduler
    participant CPA as CPA (Session/Part)
    participant SCH as resource-scheduler
    participant LC as lablet-controller
    participant WC as worker-controller
    participant SE as SE
    participant ROC as ROC
    participant LDS as LDS

    OP->>CPA: start session (LabletDefinition)
    CPA->>SCH: request allocation (pod type, timeslot)
    SCH->>WC: ensure worker
    WC-->>SCH: worker ready
    SCH-->>CPA: allocation (worker, slot)

    Note over CPA: Phase: instantiate
    CPA->>LC: worker_lab_resolve, pod_locator (native)
    CPA->>SE: submit_job(lab_start@v1, session_ctx)
    SE-->>CPA: job.completed
    CPA->>LC: ports_alloc, lds_register (native)
    LC->>LDS: register delivery
    CPA->>CPA: mark_ready (native)

    Note over CPA: Phase: ready
    CPA->>SE: submit_job(readiness_check@v1)
    SE->>ROC: collect health
    SE-->>CPA: job.completed (ReadinessReport)

    Note over CPA: student works...

    Note over CPA: Phase: collect & grade (on-demand / scheduled / submit)
    CPA->>SE: submit_job(grade_item@v1, Grading)
    SE->>ROC: POST /execute/bulk (show commands)
    ROC-->>SE: device outputs
    SE->>SE: evaluate rubric
    SE-->>CPA: job.completed (ScoreReport)

    Note over CPA: Phase: teardown
    CPA->>SE: submit_job(lab_wipe@v1, Archive)
    SE-->>CPA: job.completed (ArchiveReport)
    CPA->>LC: archive (native)
    CPA-->>OP: session complete

Commands / queries / eventsΒΆ

Step Actor Operation Kind
Start CPA start_instantiation Command
Phase transition CPA transition_lablet_session Command
Progress CPA update_pipeline_progress Command
Ready CPA mark_session_ready Command
Step retry/fail CPA resume_pipeline_step, fail_pipeline_step Command
Terminate CPA terminate Command
Job trigger CPA β†’ SE submit_job, cancel_job Command (HTTP)
Job status CPA β†’ SE get_job Query (HTTP)
Job result SE β†’ CPA job.completed / job.failed CloudEvent
Device collect SE β†’ ROC POST /devices, POST /execute/bulk, GET/DELETE /execute/bulk/{uuid} HTTP

Reconciliation noteΒΆ

The Session and Part managers (CPA) reconcile session/part state; Pod and Host managers (controllers) reconcile infrastructure β€” all under the generic reconciliation framework (ADR-047). desired_status cascades down (Session β†’ Part β†’ Pod), observed status bubbles up. CPA publishes desired state to etcd; controllers watch and reconcile, reporting progress back. SE results arrive as CloudEvents and advance the owning part's phase. This keeps CPA the single writer of session/part state while controllers and SE act asynchronously. See resource-model.md and unified-resource-management.md.