Skip to content
Agile Defense

Curriculum / Data Scientist on Foundry

INTERMEDIATEUnit 2unit-02

Train a disruption-risk model in Code Repositories / Code Workspaces

not started~360 min
Train and publish a Foundry model asset (artifact + adapter) with version history and training-dataset lineage.

Introduction

Scenario: The disruption-risk forecast now needs a model behind it: the labeled feature dataset from Unit 1 must become a trained classifier that scores each supplier's likelihood of disruption. Your job is to train and publish that model as a governed Foundry model asset so the rest of the pipeline can evaluate, deploy, and operationalize it.

In Unit 1 you framed the disruption-risk problem and built a feature-engineered, labeled training dataset with a held-out test split. This unit turns that dataset into a trained model and publishes it as a first-class Foundry asset. In Foundry, a model is an artifact for inference, and it has two parts: the model artifact (the trained weights or container produced by your code) and the ModelAdapter, a Python class that defines how the model loads and saves, declares its input/output API, and runs prediction. You will author and train a scikit-learn disruption-risk classifier, wrap it in a ModelAdapter, and publish a versioned model asset that carries its own lineage back to the training datasets.

You can author this work in either Code Repositories or Code Workspaces. The Code Repositories Model Training template gives you model_training and model_adapters modules: you implement a ModelAdapter (save/load, an api() method that declares the input feature columns and the prediction output, and predict()), then call model_output.publish(model_adapter=...) to produce a versioned model with lineage, training datasets, and an API spec. The Code Workspaces (Jupyter) path is equivalent: you train in a notebook, wrap the result in a ModelAdapter, and publish via ModelOutput(...).publish(adapter). Either way the published model gains versioning, permissions, lineage, no-code live-inference hosting, and batch inference downstream — the capabilities the later units depend on.

A word on what is and is not verifiable here, because it shapes how this unit is graded. Foundry's Filesystem read API (Get By Path) can confirm that the published model asset, a model version, and your training notebook artifact exist by resolving each path to a resource type and RID. That is existence-only: the read API will not introspect your ModelAdapter's api() schema, your training code, or the build job's dependency resolution. So the checks that confirm artifacts are automated, while the checks that confirm the adapter's declared API and a clean training run are honest manual attestations. Producing a real, lineage-bearing model asset — not just a notebook full of code — is the deliverable that every subsequent unit (Modeling Objective, batch inference, live deployment, model Function) builds on.

Capability focus: Model training (Code Repositories / Code Workspaces); ModelAdapter input/output API; published model assets + versions. · Artifact: A published Foundry model asset with version history, training lineage, and a declared input/output API.

Key concepts

  • Model (artifact + adapter): A Foundry model is an artifact for inference (machine learning, forecasting, optimization, physical models, or business rules) comprising a model artifact — the trained weights or container — and a ModelAdapter, the Python class that wraps it. Publishing the model integrates it into Foundry with versioning, permissions, lineage, no-code live-inference hosting, and batch inference.
  • ModelAdapter: The Python class that makes a trained model usable in Foundry. It implements save/load (serialize and restore the artifact, commonly with dill), an api() method that declares the model's input and output schemas (the feature columns in, the prediction columns out), and predict() that runs inference. The adapter is the contract between your training code and every downstream consumer; its internals are code, not a read-API-introspectable schema.
  • Model asset and model version: The published model is a resource (Filesystem type MODELS_MODEL). Each publish call produces an immutable model version (type MODELS_MODEL_VERSION) under it, giving you version history. Calling model_output.publish(model_adapter=...) (Code Repositories) or ModelOutput(...).publish(adapter) (Code Workspaces) is what produces the versioned artifact and records training-dataset lineage and the API spec.
  • Code Repositories Model Training template: A repository template that scaffolds model_training and model_adapters modules. You implement the ModelAdapter and a training transform, then publish the model output; the build resolves the Python environment (scikit-learn, pandas, dill) and emits a versioned model with lineage back to its input training datasets.
  • Code Workspaces (Jupyter) training: The notebook-based authoring path. You train a model interactively (e.g., a scikit-learn classifier on the feature dataset), wrap it in a ModelAdapter, and publish it via ModelOutput(...).publish(adapter). The notebook itself is a resource (Filesystem type BLOBSTER_JUPYTERNOTEBOOK), and the published model can then be submitted to a Modeling Objective.
  • Training lineage and versioning: Publishing records which training datasets fed the model and stamps a version, so each model version traces back to the exact feature/train datasets it learned from. This lineage is the audit trail later units rely on when evaluating and operationalizing successive model versions.
  • Existence-only confirmation vs. introspection: Filesystem v2 Get By Path returns a resource's RID and type from a free-string resource-type enum (MODELS_MODEL, MODELS_MODEL_VERSION, BLOBSTER_JUPYTERNOTEBOOK, and others), confirming an artifact exists at a path. It does not expose the ModelAdapter's api() schema, the training code, or build-job internals — those are confirmed by manual attestation, not a read API.

Companion video

Introduction to Machine Learning Operations · watch the model build, train & evaluate section · open on YouTube

Hands-on activity

each step validates · the unit completes when all steps pass
  1. 1

    Published model asset exists

    This step confirms that you actually published a model asset, not just that you have training code. After you train your disruption-risk classifier and call publish (model_output.publish(model_adapter=...) in the Code Repositories template, or ModelOutput(...).publish(adapter) in a Code Workspaces notebook), Foundry creates a model resource. The check resolves the model's path with Filesystem Get By Path and confirms it returns type MODELS_MODEL with an RID. Note this is existence-only: it proves a published model lives at that path, but it does not inspect the adapter's internals. Make sure the model is published to the expected location so the path resolves.

    not startedinstance check

    Confirms a published Foundry model asset exists (type MODELS_MODEL).

  2. 2

    At least one model version exists

    A model with no version is just an empty container, so this step confirms your publish call actually produced a versioned artifact. Each successful publish creates an immutable model version under the model asset. The check resolves the version path with Get By Path and confirms it returns type MODELS_MODEL_VERSION. This is what gives you version history and what records the training-dataset lineage and API spec for that specific version. If you re-train and re-publish, you accumulate versions; the later Modeling Objective unit submits a specific version as a candidate, so confirm at least one exists now. As with the model asset, this is existence-only confirmation — it does not read the version's contents.

    not startedinstance check

    Confirms a model version exists (type MODELS_MODEL_VERSION).

  3. 3

    Training-source notebook artifact exists (Code Workspaces path)

    This step confirms the training-source artifact for the authoring path you chose. For the Code Workspaces (Jupyter) path, your training notebook is itself a Foundry resource, and the check resolves its path with Get By Path and confirms it returns type BLOBSTER_JUPYTERNOTEBOOK. That ties the published model to a concrete authoring artifact in addition to the model's recorded lineage. If you instead authored in a Code Repository, be aware the repository does not have a confirmed resource-type enum value used here, so you would attest to that path manually rather than rely on this automated check. Either way, the point is that the model traces to real authored code, not an opaque binary.

    not startedinstance check

    Confirms the training notebook artifact exists (type BLOBSTER_JUPYTERNOTEBOOK).

  4. 4

    Model adapter declares input/output API

    This is a manual attestation because no documented read API can introspect a ModelAdapter's declared API. Confirm that your adapter's api() method explicitly declares the feature inputs the model expects (the columns from the Unit 1 feature dataset, such as supplier_id and the engineered risk features) and the prediction output it returns (the disruption-risk score and any confidence field). This declared input/output API is the contract every downstream consumer depends on — the Modeling Objective evaluation, the live deployment, and the model Function all bind to it. Attest honestly: the platform confirms the model and version exist, but the correctness and completeness of the api() schema are yours to verify in code and self-report here.

    not startedself-attested

    Self-attested: the ModelAdapter api() declares the feature inputs and prediction output.

  5. 5

    Training run completed without dependency conflicts

    This is a manual attestation because build-job internals are not exposed by the documented read APIs. Confirm that your training transform or notebook resolved its Python environment (scikit-learn, pandas, dill, and any other dependencies) without conflicts and ran to completion, producing the model artifact you published. A model asset can be published from a run that silently used a stale environment or skipped a step, so the existence checks above cannot vouch for a clean training run. Self-report that the environment resolved, the training executed end-to-end, and the published version reflects the model you intended to train — this honesty is what makes the version trustworthy when the next unit evaluates it.

    not startedself-attested

    Self-attested: the training transform/notebook resolved its Python environment and ran.