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
- How Lifecycles Work
- Lifecycle Structure
- Stages
- Gating Rules (Stage Dimensions)
- How Stage Enabling Works
- How Lifecycles Connect to Projects
- Complete Example
- Quick Reference
- Important Notes
- Submitting a Lifecycle
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
- Define a lifecycle template — a JSON document with an ordered list of stages and their gating rules.
- Assign the lifecycle to a project — when a project is created, it receives a copy of the lifecycle template.
- The platform evaluates gating rules — as users complete assessments, the platform checks whether each stage’s requirements are met.
- Stages unlock sequentially — when a stage’s requirements are satisfied, it becomes enabled and the next stage is evaluated.
- 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:
statusis optional metadata for display purposes. The platform uses theenabledfield (notstatus) 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:
- For each policy identifier in
requiredPolicies, the platform finds the matching assessment on the project. - It calculates the assessment’s completion percentage.
- If the completion falls within
[lowerBound, upperBound)(using the first two elements ofassessmentsCompletionThresholds), the assessment is considered incomplete. - 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
requiredPoliciesmust match theidentifierof 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:
- The platform looks up the project dimension matching
dimensionIdentifier. - It checks whether the dimension’s score falls within
[thresholds[1], thresholds[2]](inclusive on both ends). - 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
nextStagesincludes 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
enabledstate. - The updated
enabledflags 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:
- The user must be a project lead or owner.
- The platform finds the predecessor stage — the stage whose StageDimension
nextStagesfield includes the selected stage’s identifier. - If the predecessor stage is
enabled = true, the selected stage is set toenabled = 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
nextStagesstring array always starts with the current stage’s identifier (stay) and ends with the next stage’s identifier (advance). - The final stage (
stage.deployment) hasrequiredPolicies: []and only references itself innextStages. assessmentsCompletionThresholdsuses[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
-
nextStagestypically 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
requiredPoliciesto an empty array[]. The assessment check will pass automatically. -
assessmentsCompletionThresholdsonly 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 againstrequiredPolicies. -
The
nextStagesstring 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
nextStagesstring array is used by manual advancement to determine predecessor relationships. If a stage’snextStagesdoes not reference the correct next stage identifier, manual advancement to that next stage will silently fail. -
dimensionIdentifierandthresholdsare optional. Only include them in a second StageDimension element when you need dimension score gating. If omitted, no dimension check is performed. -
The
thresholdsarray uses positional indexing when present. The platform readsthresholds[1]as the lower bound andthresholds[2]as the upper bound (inclusive on both ends).thresholds[0]is not used in the dimension check but should be present (typically set to0). -
The
enableNextStagesquery 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:
- Define your stages in order, from the first phase to the last.
- Set gating rules for each stage — decide which assessments must be complete and what completion threshold is required.
- Use identifiers from your policies — the
requiredPoliciesvalues must match theidentifierof policies attached to projects. - Send the lifecycle JSON to the Asenion team for review and activation.
Versioning and updates:
- The combination of
identifier+versionacts as a unique key. - If you submit a lifecycle with an
identifier+versionthat already exists, the existing template is updated in place. - If you change the
versionfield, 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
requiredPoliciesto an empty array and the stage will pass automatically.