Lifecycle Configuration Guide

A lifecycle defines the stages that a project moves through — from initial risk assessment to deployment and monitoring. Each stage has gating rules that determine when the project is ready to advance. The platform evaluates these rules automatically based on assessment completion and, optionally, dimension scores.

This guide explains how to define a lifecycle, configure its stages and gating rules, and how the platform uses it.

Table of Contents


Overview

A lifecycle is a linear pipeline of stages. Each stage represents a phase of the AI project (e.g., Operational Risk Assessment, Data, Model, Deployment). Stages are evaluated in order — a stage can only be enabled if all previous stages have passed their gating rules.

Stage 1               Stage 2       Stage 3       Stage 4
Operational Risk  ──▶  Data     ──▶  Model    ──▶  Deployment
     ✓                  ✓              ✗              ✗
  (enabled)          (enabled)      (blocked)    (not evaluated)

When a stage fails its gating rules, the pipeline stops — later stages are not evaluated. This ensures projects progress through a controlled, sequential process.


How Lifecycles Work

  1. Define a lifecycle template — a JSON document with an ordered list of stages and their gating rules.
  2. Assign the lifecycle to a project — when a project is created, it receives a copy of the lifecycle template.
  3. The platform evaluates gating rules — as users complete assessments, the platform checks whether each stage’s requirements are met.
  4. Stages unlock sequentially — when a stage’s requirements are satisfied, it becomes enabled and the next stage is evaluated.
  5. Project leads can manually advance — once the previous stage is enabled, a project lead can advance the project to the next stage via the dashboard.

Lifecycle Structure

A lifecycle is a JSON object with the following fields:

Field Type Required Description
identifier string Yes Unique identifier for the lifecycle (e.g., com.fairly.ai.lc.default).
name string Yes Display name (e.g., “Default Asenion Project Lifecycle”).
description string Yes Explanation of what this lifecycle represents.
version string Yes Version string (e.g., "1.0.v20240531"). The combination of identifier + version must be unique.
labels string[] No Tags for categorisation.
stages Stage[] Yes Ordered array of stages. Order matters — stages are evaluated sequentially from first to last.
{
  "identifier": "com.fairly.ai.lc.default",
  "name": "Default Asenion Project Lifecycle",
  "description": "Default lifecycle for projects created in the Asenion app",
  "version": "1.0.v20240531",
  "labels": ["default_life_cycle"],
  "stages": [ ... ]
}

Stages

Stage Object

Each stage in the stages array has the following fields:

Field Type Required Description
identifier string Yes Unique identifier within the lifecycle (e.g., stage.operationalrisk).
name string Yes Display name shown in the UI (e.g., “Operational Risk Assessment”).
description string Yes Explanation of what this stage represents.
labels string[] No Tags for categorisation.
status string No One of START, IN_PROGRESS, or DONE. See Stage Status.
enabled boolean No Whether this stage is currently enabled. Defaults to false. Computed automatically by the platform — you do not need to set this.
nextStages StageDimension[] Yes Gating rules that must be satisfied before the project can move past this stage. See Gating Rules.
{
  "identifier": "stage.operationalrisk",
  "name": "Operational Risk Assessment",
  "description": "Initial stage to identify inherent risks of the project.",
  "nextStages": [ ... ]
}

Stage Status

Value Meaning
START The project begins at this stage. Typically set on the first stage.
IN_PROGRESS The project is currently working through this stage.
DONE This stage has been completed.

Note: status is optional metadata for display purposes. The platform uses the enabled field (not status) to determine which stages are unlocked.


Gating Rules (Stage Dimensions)

Each stage has a nextStages array that defines the gating rules — the conditions that must be met before the project can advance past this stage. The nextStages array contains Stage Dimension objects.

The nextStages array can have 1 or 2 elements:

  • 1 element — only an assessment completion check is performed. This is the most common configuration.
  • 2 elements — an assessment completion check (nextStages[0]) followed by a dimension score check (nextStages[1]). Both must pass.

Stage Dimension Object

Field Type Required Description
identifier string No Identifier for this gating rule.
name string No Display name.
description string No Explanation of what this rule checks.
labels string[] No Tags for categorisation.
requiredPolicies string[] Yes Policy identifiers whose assessments must be completed. Used in nextStages[0].
assessmentsCompletionThresholds number[] Yes Threshold array — the platform reads the first two elements as [lowerBound, upperBound]. An assessment is considered incomplete if its completion percentage falls within [lowerBound, upperBound). See Assessment Completion Check.
nextStages string[] Yes Stage identifiers for transitions. First element is typically the current stage’s own identifier (stay), second is the next stage (advance). See Next Stage Identifiers.
dimensionIdentifier string No Identifier of the project dimension whose score to check. Only needed if using a second element for dimension gating.
thresholds number[] No Score thresholds for the dimension check. Only needed if using a second element for dimension gating. The platform checks [thresholds[1], thresholds[2]].

Assessment Completion Check

The first element of the nextStages array (nextStages[0]) defines which assessments must be completed.

How it works:

  1. For each policy identifier in requiredPolicies, the platform finds the matching assessment on the project.
  2. It calculates the assessment’s completion percentage.
  3. If the completion falls within [lowerBound, upperBound) (using the first two elements of assessmentsCompletionThresholds), the assessment is considered incomplete.
  4. If any required assessment is missing or incomplete, the stage fails.

How policy matching works:

Assessment names in the platform follow the format <policyIdentifier>:<assessmentName> (e.g., com.fairly.ai.projectinfo:Project Info). The platform matches requiredPolicies values against the prefix before the colon. So a requiredPolicies value of com.fairly.ai.projectinfo will match any assessment whose name starts with com.fairly.ai.projectinfo:.

Important: The values in requiredPolicies must match the identifier of policies that are attached to the project. If a required policy has no matching assessment on the project, the check fails.

How assessmentsCompletionThresholds works:

The platform reads only the first two elements of this array:

  • [0] = lower bound
  • [1] = upper bound

An assessment is incomplete if its completion percentage is >= lowerBound AND < upperBound. An assessment passes (is complete) if its completion is >= upperBound.

assessmentsCompletionThresholds Meaning
[0, 99, 100] Assessment must be ≥ 99% complete to pass
[0, 50, 100] Assessment must be ≥ 50% complete to pass
[0, 100] Assessment must be exactly 100% complete to pass

Note: If the array has more than 2 elements (e.g., [0, 99, 100]), only the first two are used by the assessment check. The additional elements are metadata and do not affect the evaluation.

Example: To require the com.fairly.ai.projectinfo assessment to be at least 99% complete:

{
  "requiredPolicies": ["com.fairly.ai.projectinfo"],
  "assessmentsCompletionThresholds": [0, 99, 100],
  "nextStages": ["stage.operationalrisk", "stage.data"]
}

Dimension Score Check (Optional)

If the nextStages array has a second element (nextStages[1]), the platform also performs a dimension score check. If there is no second element, this check is skipped entirely.

How it works:

  1. The platform looks up the project dimension matching dimensionIdentifier.
  2. It checks whether the dimension’s score falls within [thresholds[1], thresholds[2]] (inclusive on both ends).
  3. If the score is within the range, the check passes.

Example: To require that the risk dimension score is between 0.25 and 0.75:

{
  "dimensionIdentifier": "risk",
  "thresholds": [0, 0.25, 0.75],
  "requiredPolicies": [],
  "assessmentsCompletionThresholds": [],
  "nextStages": ["stage.development", "stage.deployment"]
}

Note: If the project does not have the specified dimension, the dimension check is skipped (treated as passing).

Note: Most lifecycles only use assessment-based gating (1 element in nextStages) and do not require dimension score checks.

Next Stage Identifiers

The nextStages field (within each Stage Dimension) is a list of stage identifiers that define the transition from the current stage. The standard convention is:

  • First element — the current stage’s own identifier (represents “stay in this stage” if incomplete).
  • Second element — the next stage’s identifier (represents “advance to this stage” when complete).

Example:

"nextStages": ["stage.operationalrisk", "stage.data"]

This means: stay in stage.operationalrisk if incomplete, advance to stage.data when complete.

For the final stage, only include the stage’s own identifier:

"nextStages": ["stage.deployment"]

Critical: This field is not just descriptive — the platform uses it to determine predecessor relationships for manual stage advancement. When a user manually advances to a stage, the system finds the predecessor by searching for a stage whose StageDimension nextStages includes the target stage’s identifier. If this field does not reference the correct next stage identifier, manual advancement to that stage will silently fail.


How Stage Enabling Works

Automatic Evaluation

When the platform evaluates stages (e.g., when the project dashboard loads), it processes stages in array order:

For each stage (in order):
  1. Run assessment completion check (nextStages[0])
  2. If nextStages[1] exists, run dimension score check
  3. If all checks pass → stage.enabled = true → continue to next stage
  4. If any check fails → stage.enabled = false → STOP (don't evaluate later stages)

Key behaviours:

  • Stages form a linear pipeline — you cannot unlock stage 3 without stage 2 passing first.
  • Once a stage fails, all subsequent stages are not evaluated and keep their current enabled state.
  • The updated enabled flags are saved to the project automatically.

Example flow:

Stage Assessment Check Result
Operational Risk com.fairly.ai.projectinfo ≥ 99% complete enabled = true
Data com.fairly.ai.data.integrity.analysis ≥ 50% complete enabled = true
Model iso.24027 ≥ 50% complete enabled = false (assessment incomplete)
Deployment not evaluated (pipeline stopped)

Manual Stage Advancement

Project leads and owners can manually advance the project to the next stage via the dashboard lifecycle stepper. The rules are:

  1. The user must be a project lead or owner.
  2. The platform finds the predecessor stage — the stage whose StageDimension nextStages field includes the selected stage’s identifier.
  3. If the predecessor stage is enabled = true, the selected stage is set to enabled = true.

How predecessor detection works:

When you manually advance to stage stage.data, the platform searches all stages for one whose StageDimension nextStages array contains "stage.data". If stage.operationalrisk has "nextStages": ["stage.operationalrisk", "stage.data"], then stage.operationalrisk is the predecessor. If stage.operationalrisk is enabled, then stage.data can be manually advanced.

Note: Manual advancement does not bypass the gating rules for future stages — it only enables the selected stage if its predecessor is already enabled. The next stage will still need to pass its own gating rules (or be manually advanced in turn).


How Lifecycles Connect to Projects

When a project is created, the user selects a lifecycle from the available templates. The platform then embeds a full copy of the lifecycle template into the project.

Important behaviours:

  • The project carries its own snapshot of the lifecycle. If the lifecycle template is updated later, existing projects are not affected.
  • Lifecycle assignment happens at project creation time and cannot be changed afterwards.
  • Only top-level projects (e.g., AI Systems) receive a lifecycle. Child projects (e.g., Functional Models, Model Candidates) do not have a lifecycle.

Complete Example

Here is a complete lifecycle configuration with 4 stages. Each stage uses assessment-based gating to control when the project can advance:

{
  "organization": {
    "name": "Example Organisation",
    "identifier": "com.example.org",
    "pgId": "2"
  },
  "lifecycles": [
    {
      "name": "Default Project Lifecycle",
      "identifier": "com.example.org.lc.default",
      "version": "1.0.v20240531",
      "description": "Default lifecycle for projects.",
      "labels": ["default_life_cycle"],
      "stages": [
        {
          "identifier": "stage.operationalrisk",
          "name": "Operational Risk Assessment",
          "description": "Initial stage to identify inherent risks by assessing sector, jurisdictions, use cases, and other factors.",
          "nextStages": [
            {
              "requiredPolicies": ["com.example.org.projectinfo"],
              "assessmentsCompletionThresholds": [0, 99, 100],
              "nextStages": ["stage.operationalrisk", "stage.data"]
            }
          ]
        },
        {
          "identifier": "stage.data",
          "name": "Data",
          "description": "Data integrity analysis phase.",
          "nextStages": [
            {
              "requiredPolicies": ["com.example.org.data.integrity.analysis"],
              "assessmentsCompletionThresholds": [0, 50, 100],
              "nextStages": ["stage.data", "stage.model"]
            }
          ]
        },
        {
          "identifier": "stage.model",
          "name": "Model",
          "description": "Model analysis phase.",
          "nextStages": [
            {
              "requiredPolicies": ["iso.24027"],
              "assessmentsCompletionThresholds": [0, 50, 100],
              "nextStages": ["stage.model", "stage.deployment"]
            }
          ]
        },
        {
          "identifier": "stage.deployment",
          "name": "Deployment",
          "description": "Deployment phase.",
          "nextStages": [
            {
              "requiredPolicies": [],
              "assessmentsCompletionThresholds": [0, 100],
              "nextStages": ["stage.deployment"]
            }
          ]
        }
      ]
    }
  ]
}

What This Example Does

Stage Assessment Requirement Transitions To
Operational Risk com.example.org.projectinfo ≥ 99% complete Data
Data com.example.org.data.integrity.analysis ≥ 50% complete Model
Model iso.24027 ≥ 50% complete Deployment
Deployment No assessment requirements (final stage) Stays in Deployment

Key patterns to note:

  • Each stage has 1 StageDimension — only assessment-based gating, no dimension score checks.
  • The nextStages string array always starts with the current stage’s identifier (stay) and ends with the next stage’s identifier (advance).
  • The final stage (stage.deployment) has requiredPolicies: [] and only references itself in nextStages.
  • assessmentsCompletionThresholds uses [0, 99, 100] for 99% threshold and [0, 50, 100] for 50% threshold. Only the first two elements affect evaluation.

Quick Reference

Lifecycle Fields

Field Type Required Description
identifier string Yes Unique lifecycle identifier
name string Yes Display name
description string Yes What this lifecycle represents
version string Yes Version string (identifier + version must be unique)
labels string[] No Tags
stages Stage[] Yes Ordered array of stages

Stage Fields

Field Type Required Description
identifier string Yes Unique stage identifier within the lifecycle
name string Yes Display name
description string Yes What this stage represents
labels string[] No Tags
status string No START, IN_PROGRESS, or DONE
enabled boolean No Computed by platform (default false)
nextStages StageDimension[] Yes Gating rules (1 element for assessment-only, 2 elements to add dimension check)

Stage Dimension Fields

Field Type Required Description
identifier string No Identifier for this rule
name string No Display name
description string No What this rule checks
labels string[] No Tags
requiredPolicies string[] Yes Policy identifiers whose assessments must be complete
assessmentsCompletionThresholds number[] Yes First two elements used as [lowerBound, upperBound] — incomplete if in [lower, upper)
nextStages string[] Yes [currentStageId, nextStageId] — current stage for stay, next stage for advance
dimensionIdentifier string No Project dimension to check (only needed with 2 StageDimension elements)
thresholds number[] No Dimension score thresholds (only needed with 2 StageDimension elements)

Gating Logic Summary

For each stage (in order):
  ┌─────────────────────────────────────────┐
  │  Step 1: Assessment Completion Check    │
  │  (from nextStages[0])                   │
  │                                         │
  │  For each policy in requiredPolicies:   │
  │    Find matching assessment             │
  │    If missing → FAIL                    │
  │    If completion in [lower, upper) →    │
  │      FAIL (incomplete)                  │
  └──────────────────┬──────────────────────┘
                     │ All passed?
  ┌──────────────────▼──────────────────────┐
  │  Step 2: Dimension Score Check          │
  │  (from nextStages[1], if present)       │
  │                                         │
  │  If nextStages[1] not provided → SKIP   │
  │  Find dimension by dimensionIdentifier  │
  │  If not found → SKIP (pass)             │
  │  If score in [thresholds[1],            │
  │    thresholds[2]] → PASS                │
  │  Otherwise → FAIL                       │
  └──────────────────┬──────────────────────┘
                     │
              All checks passed?
           ╱                ╲
         Yes                 No
          │                   │
   stage.enabled = true    stage.enabled = false
   continue to next stage  STOP pipeline

Important Notes

  • nextStages typically has 1 element for assessment-only gating. Add a second element only if you need dimension score gating. Most lifecycles use just 1 element.

  • If a stage has no assessment requirements (e.g., the final stage), set requiredPolicies to an empty array []. The assessment check will pass automatically.

  • assessmentsCompletionThresholds only uses the first 2 elements. The platform reads [0] as the lower bound and [1] as the upper bound. If you provide 3 elements (e.g., [0, 50, 100]), the third element is not used in evaluation.

  • Assessment matching uses the policy identifier prefix. Assessment names follow the <policyIdentifier>:<name> convention. The platform strips the portion after the colon when matching against requiredPolicies.

  • The nextStages string array convention is [currentStageId, nextStageId]. The first element should be the current stage’s own identifier (representing “stay”). The second element should be the next stage’s identifier (representing “advance”). For the final stage, use only the current stage’s identifier: ["stage.deployment"].

  • The nextStages string array is used by manual advancement to determine predecessor relationships. If a stage’s nextStages does not reference the correct next stage identifier, manual advancement to that next stage will silently fail.

  • dimensionIdentifier and thresholds are optional. Only include them in a second StageDimension element when you need dimension score gating. If omitted, no dimension check is performed.

  • The thresholds array uses positional indexing when present. The platform reads thresholds[1] as the lower bound and thresholds[2] as the upper bound (inclusive on both ends). thresholds[0] is not used in the dimension check but should be present (typically set to 0).

  • The enableNextStages query appears in the platform schema but is not implemented. Stage enabling is handled exclusively by the automatic evaluation and manual advancement described above.


Submitting a Lifecycle

To create or update a lifecycle for your organisation, prepare a JSON document in the following format:

{
  "organization": {
    "name": "Your Organisation Name",
    "identifier": "com.yourorg",
    "pgId": "2"
  },
  "lifecycles": [
    {
      "identifier": "com.yourorg.lc.default",
      "name": "Your Lifecycle Name",
      "version": "1.0",
      "description": "Description of your lifecycle.",
      "labels": ["default_life_cycle"],
      "stages": [ ... ]
    }
  ]
}

Steps:

  1. Define your stages in order, from the first phase to the last.
  2. Set gating rules for each stage — decide which assessments must be complete and what completion threshold is required.
  3. Use identifiers from your policies — the requiredPolicies values must match the identifier of policies attached to projects.
  4. Send the lifecycle JSON to the Asenion team for review and activation.

Versioning and updates:

  • The combination of identifier + version acts as a unique key.
  • If you submit a lifecycle with an identifier + version that already exists, the existing template is updated in place.
  • If you change the version field, a new lifecycle template is created.
  • Existing projects are not affected by template changes — they keep their snapshot from when they were created. Only new projects receive the updated template.

Tip: If a stage has no assessment requirements (e.g., the final stage), set requiredPolicies to an empty array and the stage will pass automatically.