From 64985974d2d04acaad2c360d8cff01ae122df3ee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mattias=20Linn=C3=A9r?= Date: Wed, 16 Jul 2025 17:15:34 +0200 Subject: [PATCH 1/5] First draft of documentation for source change approved using CLM --- .../clm-source-change-approved-ai-version.md | 268 ++++++++++++++++++ .../clm-source-change-approved.md | 202 +++++++++++++ 2 files changed, 470 insertions(+) create mode 100644 eiffel-syntax-and-usage/clm-source-change-approved-ai-version.md create mode 100644 eiffel-syntax-and-usage/clm-source-change-approved.md diff --git a/eiffel-syntax-and-usage/clm-source-change-approved-ai-version.md b/eiffel-syntax-and-usage/clm-source-change-approved-ai-version.md new file mode 100644 index 00000000..743a946f --- /dev/null +++ b/eiffel-syntax-and-usage/clm-source-change-approved-ai-version.md @@ -0,0 +1,268 @@ + + +# Source Change Approval Using Confidence Levels + +_Source change approval_ is the process of signaling when a source change has been reviewed and approved according to project requirements. This document describes how to represent source change approval states using [EiffelConfidenceLevelModifiedEvent][CLM] events, providing a standardized way to communicate approval status in the Eiffel protocol. + +Source change approval is a critical gate in software development workflows, determining when changes are ready for integration. By modeling approval as confidence levels, teams can create flexible approval workflows that integrate naturally with existing Eiffel-based CI/CD pipelines. + +## Confidence Level as Approval State + +The [EiffelConfidenceLevelModifiedEvent][CLM] provides a natural way to represent approval states by treating approval as a confidence level in the source change. This approach offers several advantages: + +- **Semantic alignment**: Approval represents confidence in the quality and readiness of a change +- **Graduated states**: Can represent progressive approval states (pending, partial, full) +- **Standard tooling**: Existing Eiffel tools understand confidence level events +- **Flexible values**: Supports different approval schemes and requirements + +## Approval State Representations + +### Simple Approval States + +The most straightforward approach uses discrete approval states: + +```json +{ + "data": { + "name": "review-approval", + "value": "APPROVED" + } +} +``` + +**Supported values:** +- `PENDING`: Review process initiated but not complete +- `APPROVED`: All required approvals received +- `REJECTED`: Change rejected during review +- `INSUFFICIENT_REVIEWS`: Not enough reviews to meet requirements + +### Graduated Confidence Levels + +For more nuanced approval processes, use confidence levels that reflect approval strength: + +```json +{ + "data": { + "name": "review-confidence", + "value": "HIGH" + } +} +``` + +**Supported values:** +- `INSUFFICIENT`: Below minimum approval threshold +- `LOW`: Some approvals but below recommended level +- `MEDIUM`: Adequate approvals for most changes +- `HIGH`: Strong approval consensus, suitable for critical changes + +### Numeric Confidence Scores + +For organizations using approval scoring systems: + +```json +{ + "data": { + "name": "approval-score", + "value": "85" + } +} +``` + +The numeric value can represent: +- Percentage of required approvals received +- Weighted approval score based on reviewer expertise +- Composite score including automated and human reviews + +## Event Structure and Linking + +### Basic Event Structure + +```json +{ + "meta": { + "type": "EiffelConfidenceLevelModifiedEvent", + "version": "3.0.0" + }, + "data": { + "name": "review-approval", + "value": "APPROVED", + "issuer": { + "name": "Review Management System", + "email": "reviews@example.com" + }, + "customData": [ + { + "key": "approvalCount", + "value": "3" + }, + { + "key": "requiredApprovals", + "value": "2" + }, + { + "key": "approvers", + "value": "john.doe@example.com,jane.smith@example.com" + } + ] + }, + "links": [ + { + "type": "SUBJECT", + "target": "source-change-event-id" + } + ] +} +``` + +### Link Types Involved + +#### SUBJECT +Identifies the source change that this confidence level applies to. This link connects the approval event to the relevant [EiffelSourceChangeCreatedEvent][SCC] or [EiffelSourceChangeSubmittedEvent][SCS]. + +**Required:** Yes +**Legal sources:** [EiffelConfidenceLevelModifiedEvent][CLM] +**Legal targets:** [EiffelSourceChangeCreatedEvent][SCC], [EiffelSourceChangeSubmittedEvent][SCS] +**Multiple allowed:** No + +#### CAUSE +Identifies what triggered this confidence level change. This could link to events representing individual reviews, automated analysis results, or policy changes. + +**Required:** No +**Legal sources:** [EiffelConfidenceLevelModifiedEvent][CLM] +**Legal targets:** Any +**Multiple allowed:** Yes + +## Integration with Pipeline Workflows + +### Pre-merge Pipeline Gating + +Pipeline activities can wait for appropriate confidence levels before proceeding: + +```json +{ + "pipelineGate": { + "waitFor": { + "eventType": "EiffelConfidenceLevelModifiedEvent", + "conditions": { + "data.name": "review-approval", + "data.value": "APPROVED" + }, + "linkType": "SUBJECT", + "linkTarget": "source-change-id" + } + } +} +``` + +### Progressive Approval Workflows + +Different pipeline stages can trigger based on different confidence levels: + +1. **Basic CI triggers** on `review-confidence: LOW` +2. **Integration tests** trigger on `review-confidence: MEDIUM` +3. **Deployment pipeline** triggers on `review-confidence: HIGH` + +### Approval Workflow Examples + +#### Simple Approval Flow + +``` +EiffelSourceChangeCreatedEvent +↓ +EiffelConfidenceLevelModifiedEvent (value: "PENDING") +↓ +EiffelConfidenceLevelModifiedEvent (value: "APPROVED") +↓ +Pipeline triggered +``` + +#### Multi-stage Approval Flow + +``` +EiffelSourceChangeCreatedEvent +↓ +EiffelConfidenceLevelModifiedEvent (name: "review-approval", value: "PENDING") +↓ +EiffelConfidenceLevelModifiedEvent (name: "review-approval", value: "APPROVED") +↓ +EiffelConfidenceLevelModifiedEvent (name: "security-review", value: "APPROVED") +↓ +Final pipeline triggered +``` + +## Custom Data Fields + +### Recommended Fields + +- `approvalCount`: Number of approvals received +- `requiredApprovals`: Number of approvals required +- `approvers`: List of reviewers who approved +- `approvalRules`: Which approval rules were satisfied +- `reviewDuration`: Time taken for review process +- `approvalTimestamp`: When approval was granted + +### Integration-Specific Fields + +- `mergeRequestId`: Reference to SCM merge request +- `pullRequestUrl`: Direct link to review interface +- `reviewComments`: Number of review comments +- `approvalPolicy`: Policy version used for approval + +## Best Practices + +### Event Naming Conventions + +- Use descriptive confidence level names that reflect the approval aspect +- Maintain consistency across projects and teams +- Consider using namespaced names for organization-specific approval types + +### Value Standardization + +- Establish organization-wide standards for approval values +- Document the meaning and requirements for each approval level +- Ensure tooling can interpret and act on the defined values + +### Linking Strategy + +- Always link to the specific source change being approved +- Use CAUSE links to trace approval decisions back to triggering events +- Consider linking to related compliance or policy events + +### Tooling Integration + +- Configure CI/CD systems to recognize and act on approval confidence levels +- Implement approval dashboards that consume confidence level events +- Create approval metrics and reporting based on confidence level history + +## Migration from Activity-Based Approval + +Organizations currently using [EiffelActivityTriggeredEvent][ActT] and [EiffelActivityFinishedEvent][ActF] for approval modeling can migrate to confidence levels: + +1. **Identify existing approval activities** in your event streams +2. **Map approval outcomes** to appropriate confidence level values +3. **Update pipeline triggers** to listen for confidence level events +4. **Gradually transition** while maintaining backward compatibility + +The confidence level approach provides better semantic clarity and simpler integration patterns compared to activity-based modeling for approval workflows. + + +[ActT]: ../eiffel-vocabulary/EiffelActivityTriggeredEvent.md +[ActF]: ../eiffel-vocabulary/EiffelActivityFinishedEvent.md +[CLM]: ../eiffel-vocabulary/EiffelConfidenceLevelModifiedEvent.md +[SCC]: ../eiffel-vocabulary/EiffelSourceChangeCreatedEvent.md +[SCS]: ../eiffel-vocabulary/EiffelSourceChangeSubmittedEvent.md \ No newline at end of file diff --git a/eiffel-syntax-and-usage/clm-source-change-approved.md b/eiffel-syntax-and-usage/clm-source-change-approved.md new file mode 100644 index 00000000..e84f1d50 --- /dev/null +++ b/eiffel-syntax-and-usage/clm-source-change-approved.md @@ -0,0 +1,202 @@ + + +# Source Change Approval Using Confidence Levels + +_Source change approval_ is the process of signaling when a source change has been reviewed and approved according to project requirements. This document describes how to represent source change approval states using [EiffelConfidenceLevelModifiedEvent][CLM] events, providing a standardized way to communicate approval status in the Eiffel protocol. + +Source change approval is a critical gate in software development workflows, determining when changes are ready for integration. By modeling approval as confidence levels, teams can create flexible approval workflows that integrate naturally with existing Eiffel-based CI/CD pipelines. + +## Confidence Level as Approval State + +The [EiffelConfidenceLevelModifiedEvent][CLM] provides a natural way to represent approval states by treating approval as a confidence level in the source change. This approach offers several advantages: + +- **Semantic alignment**: Approval represents confidence in the quality and readiness of a change +- **Graduated states**: Can represent progressive approval states (pending, partial, full) +- **Standard tooling**: Existing Eiffel tools understand confidence level events +- **Flexible values**: Supports different approval schemes and requirements + +## Approval State Representations + +### Simple Approval States + +The most straightforward approach uses discrete approval states: + +```json +{ + "data": { + "name": "review-approval", + "value": "APPROVED" + } +} +``` + +**Supported values:** +- `PENDING`: Review process initiated but not complete +- `APPROVED`: All required approvals received +- `REJECTED`: Change rejected during review +- `INSUFFICIENT_REVIEWS`: Not enough reviews to meet requirements + +### Graduated Confidence Levels + +For more nuanced approval processes, use confidence levels that reflect approval strength: + +```json +{ + "data": { + "name": "review-confidence", + "value": "HIGH" + } +} +``` + +**Supported values:** +- `INSUFFICIENT`: Below minimum approval threshold +- `LOW`: Some approvals but below recommended level +- `MEDIUM`: Adequate approvals for most changes +- `HIGH`: Strong approval consensus, suitable for critical changes + +### Numeric Confidence Scores + +For organizations using approval scoring systems: + +```json +{ + "data": { + "name": "approval-score", + "value": "85" + } +} +``` + +The numeric value can represent: +- Percentage of required approvals received +- Weighted approval score based on reviewer expertise +- Composite score including automated and human reviews + +## Event Structure and Linking + +### Basic Event Structure + +```json +{ + "meta": { + "type": "EiffelConfidenceLevelModifiedEvent", + "version": "3.0.0" + }, + "data": { + "name": "review-approval", + "value": "APPROVED", + "issuer": { + "name": "Review Management System", + "email": "reviews@example.com" + }, + }, + "links": [ + { + "type": "SUBJECT", + "target": "source-change-event-id" + } + ] +} +``` + +### Link Types Involved + +#### SUBJECT +Identifies the source change that this confidence level applies to. This link connects the approval event to the relevant [EiffelSourceChangeCreatedEvent][SCC] or [EiffelSourceChangeSubmittedEvent][SCS]. + +**Required:** Yes +**Legal sources:** [EiffelConfidenceLevelModifiedEvent][CLM] +**Legal targets:** [EiffelSourceChangeCreatedEvent][SCC], [EiffelSourceChangeSubmittedEvent][SCS] +**Multiple allowed:** No + +#### CAUSE +Identifies what triggered this confidence level change. This could link to events representing individual reviews, automated analysis results, or policy changes. + +**Required:** No +**Legal sources:** [EiffelConfidenceLevelModifiedEvent][CLM] +**Legal targets:** Any +**Multiple allowed:** Yes + +## Integration with Pipeline Workflows + +### Pre-merge Pipeline Gating + +Pipeline activities can wait for appropriate confidence levels before proceeding: + +```json +{ + "pipelineGate": { + "waitFor": { + "eventType": "EiffelConfidenceLevelModifiedEvent", + "conditions": { + "data.name": "review-approval", + "data.value": "APPROVED" + }, + "linkType": "SUBJECT", + "linkTarget": "source-change-id" + } + } +} +``` + +### Progressive Approval Workflows + +Different pipeline stages can trigger based on different confidence levels: + +1. **Basic CI triggers** on `review-confidence: LOW` +2. **Integration tests** trigger on `review-confidence: MEDIUM` +3. **Deployment pipeline** triggers on `review-confidence: HIGH` + +### Approval Workflow Examples + +#### Simple Approval Flow + +``` +EiffelSourceChangeCreatedEvent +↓ +EiffelConfidenceLevelModifiedEvent (value: "PENDING") +↓ +EiffelConfidenceLevelModifiedEvent (value: "APPROVED") +↓ +Pipeline triggered +``` + +#### Multi-stage Approval Flow + +``` +EiffelSourceChangeCreatedEvent +↓ +EiffelConfidenceLevelModifiedEvent (name: "review-approval", value: "PENDING") +↓ +EiffelConfidenceLevelModifiedEvent (name: "review-approval", value: "APPROVED") +↓ +EiffelConfidenceLevelModifiedEvent (name: "security-review", value: "APPROVED") +↓ +Final pipeline triggered +``` + + + + + +[ActT]: ../eiffel-vocabulary/EiffelActivityTriggeredEvent.md +[ActF]: ../eiffel-vocabulary/EiffelActivityFinishedEvent.md +[CLM]: ../eiffel-vocabulary/EiffelConfidenceLevelModifiedEvent.md +[SCC]: ../eiffel-vocabulary/EiffelSourceChangeCreatedEvent.md +[SCS]: ../eiffel-vocabulary/EiffelSourceChangeSubmittedEvent.md \ No newline at end of file From b9e8fc5e216df708d8f1030c8ca1399b3f9528f4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mattias=20Linn=C3=A9r?= Date: Wed, 29 Oct 2025 12:05:18 +0100 Subject: [PATCH 2/5] Add PREDECESSOR link --- .../4.1.0.yml | 208 ++++++++++++++++ .../EiffelConfidenceLevelModifiedEvent.md | 11 +- .../4.1.0.json | 234 ++++++++++++++++++ 3 files changed, 452 insertions(+), 1 deletion(-) create mode 100644 definitions/EiffelConfidenceLevelModifiedEvent/4.1.0.yml create mode 100644 schemas/EiffelConfidenceLevelModifiedEvent/4.1.0.json diff --git a/definitions/EiffelConfidenceLevelModifiedEvent/4.1.0.yml b/definitions/EiffelConfidenceLevelModifiedEvent/4.1.0.yml new file mode 100644 index 00000000..5645818e --- /dev/null +++ b/definitions/EiffelConfidenceLevelModifiedEvent/4.1.0.yml @@ -0,0 +1,208 @@ +# Copyright 2017-2025 Ericsson AB and others. +# For a full list of individual contributors, please see the commit history. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +--- +$schema: https://json-schema.org/draft/2020-12/schema# +_name: EiffelConfidenceLevelModifiedEvent +_version: 4.1.0 +_abbrev: CLM +_description: |- + The EiffelConfidenceLevelModifiedEvent declares that an entity has achieved (or failed to achieve) a certain level of confidence, or in a broader sense to annotate it as being applicable or relevant to a certain case (e.g. fit for release to a certain customer segment or having passed certain criteria). This is particularly useful for promoting various engineering artifacts, such as product revisions, through the continuous integration and delivery pipeline. + + Confidence levels may operate at high or low levels of abstraction - ranging from "smokeTestsOk" to "releasable" or "released" - and they may group other confidence levels of lower abstraction levels. They may also be general or very niched, e.g. "releasable" or "releasableToCustomerX". Confidence levels frequently figure in automated delivery interfaces within a tiered system context: lower level tiers issue an agreed confidence level signaling that a new version is ready for integration in a higher level tier. + + See [Source Change Approval Using Confidence Levels](../eiffel-syntax-and-usage/clm-source-change-approved.md) for guidance on how to use the CLM event for reviews. +type: object +properties: + meta: + $ref: ../EiffelMetaProperty/4.0.1.yml + data: + type: object + properties: + name: + _description: The name of the confidence level. It is recommended + for confidence level names to conform with camelCase formatting, + in line with the format of key names of the Eiffel protocol + as a whole. + type: string + value: + _description: |- + The value of the confidence level. + SUCCESS signifies that the confidence level has been successfully achieved. + FAILURE signifies that the confidence level could not be achieved. + INCONCLUSIVE signifies that achievement of the confidence level could not be determined. + type: string + enum: + - SUCCESS + - FAILURE + - INCONCLUSIVE + issuer: + _description: The individual or entity issuing the confidence + level. + type: object + properties: + name: + _description: The name of the issuer. + type: string + email: + _description: The e-mail address of the issuer. + type: string + id: + _description: Any identity, alias or handle of the issuer, + such as a corporate id or username. + type: string + group: + _description: Any group, such as a development team, committee + or test group, to which the issuer belongs. + type: string + additionalProperties: false + customData: + type: array + items: + $ref: ../EiffelCustomDataProperty/2.0.0.yml + required: + - name + - value + additionalProperties: false + links: + type: array + contains: + type: object + properties: + type: + enum: + - SUBJECT + items: + $ref: ../EiffelEventLink/2.0.0.yml +required: + - meta + - data + - links +additionalProperties: false +_links: + CAUSE: + description: 'Identifies a cause of the event occurring. SHOULD + not be used in conjunction with __CONTEXT__: individual events + providing __CAUSE__ within a larger context gives rise to ambiguity. + It is instead recommended to let the root event of the context + declare __CAUSE__.' + required: false + multiple: true + targets: + any_type: true + types: [] + CONFIDENCE_BASIS: + description: 'Used to declare the basis for which confidence statement(s) this event have used. + The __CAUSE__ link tells what caused the event sending whereas __CONFIDENCE_BASIS__ declares the reason for + selecting the provided __data.name__ and/or __data.value__.' + required: false + multiple: true + targets: + any_type: false + types: + - EiffelConfidenceLevelModifiedEvent + - EiffelTestCaseFinishedEvent + - EiffelTestSuiteFinishedEvent + CONTEXT: + description: Identifies the activity or test suite of which this + event constitutes a part. + required: false + multiple: false + targets: + any_type: false + types: + - EiffelActivityTriggeredEvent + - EiffelTestSuiteStartedEvent + FLOW_CONTEXT: + description: 'Identifies the flow context of the event: which is + the continuous integration and delivery flow in which this occurred + – e.g. which product, project, track or version this is applicable + to.' + required: false + multiple: true + targets: + any_type: false + types: + - EiffelFlowContextDefinedEvent + PREDECESSOR: + description: 'Identifies which other CLM events this event supersedes. For example, in a scenario where CLM events signal reviews, this link indicates which earlies reviews became outdated due to this review.' + required: false + multiple: true + targets: + any_type: false + types: + - EiffelConfidenceLevelModifiedEvent + SUBJECT: + description: Identifies a subject of the confidence level; in other + words, what the confidence level applies to. + required: true + multiple: true + targets: + any_type: false + types: + - EiffelArtifactCreatedEvent + - EiffelArtifactDeployedEvent + - EiffelCompositionDefinedEvent + - EiffelSourceChangeCreatedEvent + - EiffelSourceChangeSubmittedEvent + SUB_CONFIDENCE_LEVEL: + description: 'Used in events summarizing multiple confidence levels. + Example use case: the confidence level "allTestsOk" summarizes + the confidence levels "unitTestsOk, "scenarioTestsOk" and "deploymentTestsOk", + and consequently links to them via __SUB_CONFIDENCE_LEVEL__. + This is intended for purely descriptive, rather than prescriptive, + use. Future editions might deprecate this link in favour of CONFIDENCE_BASIS.' + required: false + multiple: true + targets: + any_type: false + types: + - EiffelConfidenceLevelModifiedEvent +_history: + - version: 4.1.0 + changes: Add PREDECESSOR link (see [Issue 236](https://github.com/eiffel-community/eiffel/issues/236)). + - version: 4.0.1 + changes: Detail the expected representation of public key and signature in meta.security (see [Issue 375](https://github.com/eiffel-community/eiffel/issues/375)). + - version: 4.0.0 + changes: Update meta schema to Draft 2020-12 and add link validation. + - version: 3.4.0 + changes: Add CONFIDENCE_BASIS link (see [Issue 323](https://github.com/eiffel-community/eiffel/issues/323)). + - version: 3.3.0 + introduced_in: edition-orizaba + changes: Add EiffelArtifactDeployedEvent as legal target type for + SUBJECT link (see + [Issue 239](https://github.com/eiffel-community/eiffel/issues/239)). + - version: 3.2.0 + introduced_in: edition-arica + changes: Add schema URL to the meta object (see [Issue 280](https://github.com/eiffel-community/eiffel/issues/280)). + - version: 3.1.0 + introduced_in: edition-lyon + changes: Add links.domainId member (see [Issue 233](https://github.com/eiffel-community/eiffel/issues/233)). + - version: 3.0.0 + introduced_in: edition-agen + changes: Improved information integrity protection (see [Issue + 185](https://github.com/eiffel-community/eiffel/issues/185)). + - version: 2.0.0 + introduced_in: edition-agen + changes: Introduced purl identifiers instead of GAVs (see [Issue + 182](https://github.com/eiffel-community/eiffel/issues/182)) + - version: 1.1.0 + introduced_in: edition-toulouse + changes: Multiple links of type FLOW_CONTEXT allowed. + - version: 1.0.0 + introduced_in: edition-bordeaux + changes: Initial version. +_examples: + - title: Simple example + url: ../examples/events/EiffelConfidenceLevelModifiedEvent/simple.json diff --git a/eiffel-vocabulary/EiffelConfidenceLevelModifiedEvent.md b/eiffel-vocabulary/EiffelConfidenceLevelModifiedEvent.md index 75489ecb..072a18b6 100644 --- a/eiffel-vocabulary/EiffelConfidenceLevelModifiedEvent.md +++ b/eiffel-vocabulary/EiffelConfidenceLevelModifiedEvent.md @@ -1,5 +1,5 @@ @@ -9,6 +9,8 @@ The EiffelConfidenceLevelModifiedEvent declares that an entity has achieved (or Confidence levels may operate at high or low levels of abstraction - ranging from "smokeTestsOk" to "releasable" or "released" - and they may group other confidence levels of lower abstraction levels. They may also be general or very niched, e.g. "releasable" or "releasableToCustomerX". Confidence levels frequently figure in automated delivery interfaces within a tiered system context: lower level tiers issue an agreed confidence level signaling that a new version is ready for integration in a higher level tier. +See [Source Change Approval Using Confidence Levels](../eiffel-syntax-and-usage/clm-source-change-approved.md) for guidance on how to use the CLM event for reviews. + ## Data Members ### data.name @@ -78,6 +80,12 @@ __Legal targets:__ [EiffelFlowContextDefinedEvent](../eiffel-vocabulary/EiffelFl __Multiple allowed:__ Yes __Description:__ Identifies the flow context of the event: which is the continuous integration and delivery flow in which this occurred – e.g. which product, project, track or version this is applicable to. +### PREDECESSOR +__Required:__ No +__Legal targets:__ [EiffelConfidenceLevelModifiedEvent](../eiffel-vocabulary/EiffelConfidenceLevelModifiedEvent.md) +__Multiple allowed:__ Yes +__Description:__ Identifies which other CLM events this event supersedes. For example, in a scenario where CLM events signal reviews, this link indicates which earlies reviews became outdated due to this review. + ### SUBJECT __Required:__ Yes __Legal targets:__ [EiffelArtifactCreatedEvent](../eiffel-vocabulary/EiffelArtifactCreatedEvent.md), [EiffelArtifactDeployedEvent](../eiffel-vocabulary/EiffelArtifactDeployedEvent.md), [EiffelCompositionDefinedEvent](../eiffel-vocabulary/EiffelCompositionDefinedEvent.md), [EiffelSourceChangeCreatedEvent](../eiffel-vocabulary/EiffelSourceChangeCreatedEvent.md), [EiffelSourceChangeSubmittedEvent](../eiffel-vocabulary/EiffelSourceChangeSubmittedEvent.md) @@ -227,6 +235,7 @@ __Description:__ A URI pointing at a location from where the schema used when cr | Version | Introduced in | Changes | | ------- | ------------- | ------- | +| 4.1.0 | Not yet released in an edition | Add PREDECESSOR link (see [Issue 236](https://github.com/eiffel-community/eiffel/issues/236)). | | 4.0.1 | Not yet released in an edition | Detail the expected representation of public key and signature in meta.security (see [Issue 375](https://github.com/eiffel-community/eiffel/issues/375)). | | 4.0.0 | Not yet released in an edition | Update meta schema to Draft 2020-12 and add link validation. | | 3.4.0 | Not yet released in an edition | Add CONFIDENCE_BASIS link (see [Issue 323](https://github.com/eiffel-community/eiffel/issues/323)). | diff --git a/schemas/EiffelConfidenceLevelModifiedEvent/4.1.0.json b/schemas/EiffelConfidenceLevelModifiedEvent/4.1.0.json new file mode 100644 index 00000000..4f9b1237 --- /dev/null +++ b/schemas/EiffelConfidenceLevelModifiedEvent/4.1.0.json @@ -0,0 +1,234 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema#", + "type": "object", + "properties": { + "meta": { + "type": "object", + "properties": { + "id": { + "type": "string", + "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$" + }, + "type": { + "type": "string", + "enum": [ + "EiffelConfidenceLevelModifiedEvent" + ] + }, + "version": { + "type": "string", + "enum": [ + "4.1.0" + ], + "default": "4.1.0" + }, + "time": { + "type": "integer" + }, + "tags": { + "type": "array", + "items": { + "type": "string" + } + }, + "source": { + "type": "object", + "properties": { + "domainId": { + "type": "string" + }, + "host": { + "type": "string" + }, + "name": { + "type": "string" + }, + "serializer": { + "type": "string", + "pattern": "^pkg:" + }, + "uri": { + "type": "string" + } + }, + "additionalProperties": false + }, + "security": { + "type": "object", + "properties": { + "authorIdentity": { + "type": "string" + }, + "integrityProtection": { + "type": "object", + "properties": { + "signature": { + "type": "string", + "pattern": "^[-A-Za-z0-9+/]*={0,3}$", + "contentEncoding": "base64", + "contentMediaType": "application/octet-stream" + }, + "alg": { + "type": "string", + "enum": [ + "HS256", + "HS384", + "HS512", + "RS256", + "RS384", + "RS512", + "ES256", + "ES384", + "ES512", + "PS256", + "PS384", + "PS512" + ] + }, + "publicKey": { + "type": "string", + "pattern": "^[-A-Za-z0-9+/]*={0,3}$", + "contentEncoding": "base64", + "contentMediaType": "application/octet-stream" + } + }, + "required": [ + "signature", + "alg" + ], + "additionalProperties": false + }, + "sequenceProtection": { + "type": "array", + "items": { + "type": "object", + "properties": { + "sequenceName": { + "type": "string" + }, + "position": { + "type": "integer" + } + }, + "additionalProperties": false, + "required": [ + "sequenceName", + "position" + ] + } + } + }, + "additionalProperties": false, + "required": [ + "authorIdentity" + ] + }, + "schemaUri": { + "type": "string" + } + }, + "required": [ + "id", + "type", + "version", + "time" + ], + "additionalProperties": false + }, + "data": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "value": { + "type": "string", + "enum": [ + "SUCCESS", + "FAILURE", + "INCONCLUSIVE" + ] + }, + "issuer": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "email": { + "type": "string" + }, + "id": { + "type": "string" + }, + "group": { + "type": "string" + } + }, + "additionalProperties": false + }, + "customData": { + "type": "array", + "items": { + "type": "object", + "properties": { + "key": { + "type": "string" + }, + "value": {} + }, + "required": [ + "key", + "value" + ], + "additionalProperties": false + } + } + }, + "required": [ + "name", + "value" + ], + "additionalProperties": false + }, + "links": { + "type": "array", + "contains": { + "type": "object", + "properties": { + "type": { + "enum": [ + "SUBJECT" + ] + } + } + }, + "items": { + "type": "object", + "properties": { + "type": { + "type": "string" + }, + "target": { + "type": "string", + "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$" + }, + "domainId": { + "type": "string" + } + }, + "required": [ + "type", + "target" + ], + "additionalProperties": false + } + } + }, + "required": [ + "meta", + "data", + "links" + ], + "additionalProperties": false +} From 53ec4b961ca237b446a65590152ff9fd24a413da Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mattias=20Linn=C3=A9r?= Date: Wed, 29 Oct 2025 13:53:35 +0100 Subject: [PATCH 3/5] Update description text --- .../clm-source-change-approved.md | 105 ++- .../predecessor-simple.png | Bin 0 -> 34654 bytes .../predecessor-simple.svg | 653 ++++++++++++++++++ 3 files changed, 722 insertions(+), 36 deletions(-) create mode 100644 eiffel-syntax-and-usage/predecessor-simple.png create mode 100644 eiffel-syntax-and-usage/predecessor-simple.svg diff --git a/eiffel-syntax-and-usage/clm-source-change-approved.md b/eiffel-syntax-and-usage/clm-source-change-approved.md index e84f1d50..e8b74eb5 100644 --- a/eiffel-syntax-and-usage/clm-source-change-approved.md +++ b/eiffel-syntax-and-usage/clm-source-change-approved.md @@ -1,5 +1,5 @@ diff --git a/eiffel-syntax-and-usage/predecessor-simple.png b/eiffel-syntax-and-usage/predecessor-simple.png new file mode 100644 index 0000000000000000000000000000000000000000..7a07d42d02d159eeceae8b44a3e54f75016ec9b7 GIT binary patch literal 34654 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 + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + SCC 1 + + + + + + PREVIOUS_VERSION + + + + SUBJECT + + CLM 2 + CLM 1 + + + + + PREDECESSOR + + +1 + -2 + + + SCC 2 + + + CLM 3 + +2 + + + + From ec08130353a585edcda4c203522a0120081d3142 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mattias=20Linn=C3=A9r?= Date: Wed, 29 Oct 2025 13:54:26 +0100 Subject: [PATCH 4/5] Remove AI genereated version --- .../clm-source-change-approved-ai-version.md | 268 ------------------ 1 file changed, 268 deletions(-) delete mode 100644 eiffel-syntax-and-usage/clm-source-change-approved-ai-version.md diff --git a/eiffel-syntax-and-usage/clm-source-change-approved-ai-version.md b/eiffel-syntax-and-usage/clm-source-change-approved-ai-version.md deleted file mode 100644 index 743a946f..00000000 --- a/eiffel-syntax-and-usage/clm-source-change-approved-ai-version.md +++ /dev/null @@ -1,268 +0,0 @@ - - -# Source Change Approval Using Confidence Levels - -_Source change approval_ is the process of signaling when a source change has been reviewed and approved according to project requirements. This document describes how to represent source change approval states using [EiffelConfidenceLevelModifiedEvent][CLM] events, providing a standardized way to communicate approval status in the Eiffel protocol. - -Source change approval is a critical gate in software development workflows, determining when changes are ready for integration. By modeling approval as confidence levels, teams can create flexible approval workflows that integrate naturally with existing Eiffel-based CI/CD pipelines. - -## Confidence Level as Approval State - -The [EiffelConfidenceLevelModifiedEvent][CLM] provides a natural way to represent approval states by treating approval as a confidence level in the source change. This approach offers several advantages: - -- **Semantic alignment**: Approval represents confidence in the quality and readiness of a change -- **Graduated states**: Can represent progressive approval states (pending, partial, full) -- **Standard tooling**: Existing Eiffel tools understand confidence level events -- **Flexible values**: Supports different approval schemes and requirements - -## Approval State Representations - -### Simple Approval States - -The most straightforward approach uses discrete approval states: - -```json -{ - "data": { - "name": "review-approval", - "value": "APPROVED" - } -} -``` - -**Supported values:** -- `PENDING`: Review process initiated but not complete -- `APPROVED`: All required approvals received -- `REJECTED`: Change rejected during review -- `INSUFFICIENT_REVIEWS`: Not enough reviews to meet requirements - -### Graduated Confidence Levels - -For more nuanced approval processes, use confidence levels that reflect approval strength: - -```json -{ - "data": { - "name": "review-confidence", - "value": "HIGH" - } -} -``` - -**Supported values:** -- `INSUFFICIENT`: Below minimum approval threshold -- `LOW`: Some approvals but below recommended level -- `MEDIUM`: Adequate approvals for most changes -- `HIGH`: Strong approval consensus, suitable for critical changes - -### Numeric Confidence Scores - -For organizations using approval scoring systems: - -```json -{ - "data": { - "name": "approval-score", - "value": "85" - } -} -``` - -The numeric value can represent: -- Percentage of required approvals received -- Weighted approval score based on reviewer expertise -- Composite score including automated and human reviews - -## Event Structure and Linking - -### Basic Event Structure - -```json -{ - "meta": { - "type": "EiffelConfidenceLevelModifiedEvent", - "version": "3.0.0" - }, - "data": { - "name": "review-approval", - "value": "APPROVED", - "issuer": { - "name": "Review Management System", - "email": "reviews@example.com" - }, - "customData": [ - { - "key": "approvalCount", - "value": "3" - }, - { - "key": "requiredApprovals", - "value": "2" - }, - { - "key": "approvers", - "value": "john.doe@example.com,jane.smith@example.com" - } - ] - }, - "links": [ - { - "type": "SUBJECT", - "target": "source-change-event-id" - } - ] -} -``` - -### Link Types Involved - -#### SUBJECT -Identifies the source change that this confidence level applies to. This link connects the approval event to the relevant [EiffelSourceChangeCreatedEvent][SCC] or [EiffelSourceChangeSubmittedEvent][SCS]. - -**Required:** Yes -**Legal sources:** [EiffelConfidenceLevelModifiedEvent][CLM] -**Legal targets:** [EiffelSourceChangeCreatedEvent][SCC], [EiffelSourceChangeSubmittedEvent][SCS] -**Multiple allowed:** No - -#### CAUSE -Identifies what triggered this confidence level change. This could link to events representing individual reviews, automated analysis results, or policy changes. - -**Required:** No -**Legal sources:** [EiffelConfidenceLevelModifiedEvent][CLM] -**Legal targets:** Any -**Multiple allowed:** Yes - -## Integration with Pipeline Workflows - -### Pre-merge Pipeline Gating - -Pipeline activities can wait for appropriate confidence levels before proceeding: - -```json -{ - "pipelineGate": { - "waitFor": { - "eventType": "EiffelConfidenceLevelModifiedEvent", - "conditions": { - "data.name": "review-approval", - "data.value": "APPROVED" - }, - "linkType": "SUBJECT", - "linkTarget": "source-change-id" - } - } -} -``` - -### Progressive Approval Workflows - -Different pipeline stages can trigger based on different confidence levels: - -1. **Basic CI triggers** on `review-confidence: LOW` -2. **Integration tests** trigger on `review-confidence: MEDIUM` -3. **Deployment pipeline** triggers on `review-confidence: HIGH` - -### Approval Workflow Examples - -#### Simple Approval Flow - -``` -EiffelSourceChangeCreatedEvent -↓ -EiffelConfidenceLevelModifiedEvent (value: "PENDING") -↓ -EiffelConfidenceLevelModifiedEvent (value: "APPROVED") -↓ -Pipeline triggered -``` - -#### Multi-stage Approval Flow - -``` -EiffelSourceChangeCreatedEvent -↓ -EiffelConfidenceLevelModifiedEvent (name: "review-approval", value: "PENDING") -↓ -EiffelConfidenceLevelModifiedEvent (name: "review-approval", value: "APPROVED") -↓ -EiffelConfidenceLevelModifiedEvent (name: "security-review", value: "APPROVED") -↓ -Final pipeline triggered -``` - -## Custom Data Fields - -### Recommended Fields - -- `approvalCount`: Number of approvals received -- `requiredApprovals`: Number of approvals required -- `approvers`: List of reviewers who approved -- `approvalRules`: Which approval rules were satisfied -- `reviewDuration`: Time taken for review process -- `approvalTimestamp`: When approval was granted - -### Integration-Specific Fields - -- `mergeRequestId`: Reference to SCM merge request -- `pullRequestUrl`: Direct link to review interface -- `reviewComments`: Number of review comments -- `approvalPolicy`: Policy version used for approval - -## Best Practices - -### Event Naming Conventions - -- Use descriptive confidence level names that reflect the approval aspect -- Maintain consistency across projects and teams -- Consider using namespaced names for organization-specific approval types - -### Value Standardization - -- Establish organization-wide standards for approval values -- Document the meaning and requirements for each approval level -- Ensure tooling can interpret and act on the defined values - -### Linking Strategy - -- Always link to the specific source change being approved -- Use CAUSE links to trace approval decisions back to triggering events -- Consider linking to related compliance or policy events - -### Tooling Integration - -- Configure CI/CD systems to recognize and act on approval confidence levels -- Implement approval dashboards that consume confidence level events -- Create approval metrics and reporting based on confidence level history - -## Migration from Activity-Based Approval - -Organizations currently using [EiffelActivityTriggeredEvent][ActT] and [EiffelActivityFinishedEvent][ActF] for approval modeling can migrate to confidence levels: - -1. **Identify existing approval activities** in your event streams -2. **Map approval outcomes** to appropriate confidence level values -3. **Update pipeline triggers** to listen for confidence level events -4. **Gradually transition** while maintaining backward compatibility - -The confidence level approach provides better semantic clarity and simpler integration patterns compared to activity-based modeling for approval workflows. - - -[ActT]: ../eiffel-vocabulary/EiffelActivityTriggeredEvent.md -[ActF]: ../eiffel-vocabulary/EiffelActivityFinishedEvent.md -[CLM]: ../eiffel-vocabulary/EiffelConfidenceLevelModifiedEvent.md -[SCC]: ../eiffel-vocabulary/EiffelSourceChangeCreatedEvent.md -[SCS]: ../eiffel-vocabulary/EiffelSourceChangeSubmittedEvent.md \ No newline at end of file From 1aaefff1728abf446ba676babd4d1b1645d1d26b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mattias=20Linn=C3=A9r?= Date: Wed, 29 Oct 2025 15:44:41 +0100 Subject: [PATCH 5/5] Fix lint issues --- .../clm-source-change-approved.md | 25 +++++++++---------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/eiffel-syntax-and-usage/clm-source-change-approved.md b/eiffel-syntax-and-usage/clm-source-change-approved.md index e8b74eb5..353fac84 100644 --- a/eiffel-syntax-and-usage/clm-source-change-approved.md +++ b/eiffel-syntax-and-usage/clm-source-change-approved.md @@ -48,6 +48,7 @@ The most straightforward approach uses discrete approval states: ``` **Supported values:** + - `PENDING`: Review process initiated but not complete - `APPROVED`: All required approvals received - `REJECTED`: Change rejected during review @@ -67,6 +68,7 @@ For more nuanced approval processes, use confidence levels that reflect approval ``` **Supported values:** + - `INSUFFICIENT`: Below minimum approval threshold - `LOW`: Some approvals but below recommended level - `MEDIUM`: Adequate approvals for most changes @@ -86,6 +88,7 @@ For organizations using approval scoring systems: ``` The numeric value can represent: + - Percentage of required approvals received - Weighted approval score based on reviewer expertise - Composite score including automated and human reviews @@ -138,7 +141,7 @@ Identifies what triggered this confidence level change. This could link to event **Multiple allowed:** Yes #### PREDECESSOR -Identifies previous confidence level events that this event supersedes. +Identifies previous confidence level events that this event supersedes. This link indicates which earlier CLM events have been outdated or replaced by the current confidence level assessment. **Required:** No @@ -150,10 +153,10 @@ This link indicates which earlier CLM events have been outdated or replaced by t The following example shows one way to model multiple reviews and their dependence: -1. A developer pushes code for review (`SCC 1`). -1. The first reviewer gives a `+1` as they think it looks good (`CLM 1`). -1. The second reviewer spots a serious mistake and gives a `-2` (`CLM 2`). -1. The developer updates the code and pushes the new code for review (`SCC 2`). +1. A developer pushes code for review (`SCC 1`). +1. The first reviewer gives a `+1` as they think it looks good (`CLM 1`). +1. The second reviewer spots a serious mistake and gives a `-2` (`CLM 2`). +1. The developer updates the code and pushes the new code for review (`SCC 2`). 1. The second reviewer accepts the changes by giving a `+2` (`CLM 3`). ![Override example](./predecessor-simple.png) @@ -191,9 +194,8 @@ CLM 2 could look like this ### Value of the PREDECESSOR Link -With the `PREDECESSOR` link you can express which events superseded each other -without relying on conventions that might not be known to all readers. - +With the `PREDECESSOR` link you can express which events superseded each other +without relying on conventions that might not be known to all readers. ## Integration with Pipeline Workflows @@ -225,11 +227,8 @@ Different pipeline stages can trigger based on different confidence levels: 2. **Integration tests** trigger on `review-confidence: MEDIUM` 3. **Deployment pipeline** triggers on `review-confidence: HIGH` - - -[ActT]: ../eiffel-vocabulary/EiffelActivityTriggeredEvent.md -[ActF]: ../eiffel-vocabulary/EiffelActivityFinishedEvent.md + [CLM]: ../eiffel-vocabulary/EiffelConfidenceLevelModifiedEvent.md [SCC]: ../eiffel-vocabulary/EiffelSourceChangeCreatedEvent.md -[SCS]: ../eiffel-vocabulary/EiffelSourceChangeSubmittedEvent.md \ No newline at end of file +[SCS]: ../eiffel-vocabulary/EiffelSourceChangeSubmittedEvent.md