-
-
Notifications
You must be signed in to change notification settings - Fork 93
Introduce pre-defined perspectives #1067
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: 2.0-dev
Are you sure you want to change the base?
Changes from all commits
dc0b20a
f7efd6a
95afc94
ebb5184
3140a3a
ec23bed
f549215
c00b7af
945aeb9
3fb9f36
7e7043e
5828cdd
b9a6c3e
81a9bea
6b177ff
5867d5b
30abb8d
4c7c7c2
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,77 @@ | ||
| name: Generate Perspectives Registry | ||
|
|
||
| on: | ||
| push: | ||
| branches: | ||
| - 'master' | ||
| - 'main' | ||
| - '2.0-dev' | ||
| paths: | ||
| - '.github/workflows/generate_perspectives_registry.yml' # self | ||
| - 'tools/src/main/js/perspectives-registry/**' | ||
| - 'schema/perspectives-defs.schema.json' | ||
| - 'perspectives/**' | ||
| workflow_dispatch: # Allows manual trigger | ||
|
|
||
| concurrency: | ||
| group: ${{ github.workflow }}-${{ github.ref }} | ||
| cancel-in-progress: true | ||
|
|
||
| # https://docs.github.com/en/actions/writing-workflows/choosing-what-your-workflow-does/controlling-permissions-for-github_token | ||
| permissions: {} | ||
|
|
||
| jobs: | ||
| generate-registry: | ||
| name: Generate Registry | ||
| runs-on: ubuntu-latest | ||
| timeout-minutes: 30 | ||
| permissions: | ||
| contents: write # Required to push the update branch | ||
| pull-requests: write # Required to open the pull request | ||
| env: | ||
| REGISTRY_FILE: schema/perspectives-defs.json | ||
| BASE_BRANCH: ${{ github.ref_name }} | ||
| UPDATE_BRANCH: update-perspectives-registry/${{ github.ref_name }} | ||
| steps: | ||
| - name: Checkout repository | ||
| # see https://github.com/actions/checkout | ||
| uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 | ||
| with: | ||
| persist-credentials: false | ||
| - name: Setup Node.js | ||
| # see https://github.com/actions/setup-node | ||
| uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0 | ||
| with: | ||
| node-version: '24.x' | ||
| - name: Generate registry | ||
| # registers catalog document versions that are not registered yet; | ||
| # fails if a catalog document changed without a version bump | ||
| run: | | ||
| set -eux | ||
| node tools/src/main/js/perspectives-registry/generate-perspectives-registry.js | ||
| - name: Create Pull Request | ||
| env: | ||
| GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | ||
| run: | | ||
| set -eu | ||
|
|
||
| if git diff --quiet -- "$REGISTRY_FILE" | ||
| then | ||
| echo "No changes to the perspectives registry" | ||
| exit 0 | ||
| fi | ||
|
|
||
| git config --local user.email "github-actions[bot]@users.noreply.github.com" | ||
| git config --local user.name "github-actions[bot]" | ||
|
|
||
| git checkout -b "$UPDATE_BRANCH" | ||
| git add "$REGISTRY_FILE" | ||
| git commit -m "chore: update perspectives registry" | ||
|
|
||
| git push -u "https://x-access-token:${GH_TOKEN}@github.com/${GITHUB_REPOSITORY}.git" "$UPDATE_BRANCH" --force | ||
|
|
||
| gh pr create \ | ||
| --title "chore: update perspectives registry" \ | ||
| --body "This PR updates \`${REGISTRY_FILE}\` with the catalog document versions registered by \`tools/src/main/js/perspectives-registry/generate-perspectives-registry.js\` for \`${BASE_BRANCH}\`." \ | ||
| --base "$BASE_BRANCH" \ | ||
| --head "$UPDATE_BRANCH" || echo "Pull request already exists" |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,238 @@ | ||
| { | ||
| "$schema": "https://cyclonedx.org/schema/2.0/cyclonedx-2.0.schema.json", | ||
| "specFormat": "CycloneDX", | ||
| "specVersion": "2.0", | ||
| "version": 1, | ||
| "metadata": { | ||
| "timestamp": "2026-09-04T12:00:00Z" | ||
| }, | ||
| "perspectives": [ | ||
| { | ||
| "bom-ref": "perspective-model-card", | ||
| "name": "Model Card", | ||
| "description": "Defines the data elements of a machine learning model card, following the industry-standard model card structure: model details, intended use, training data and procedure, quantitative analysis, technical limitations, and ethical, fairness, and environmental considerations. The mappings project that structure onto the CycloneDX 2.0 decomposition of the former first-class modelCard entity: intrinsic technical characteristics live in modelProperties, which may only appear on components of type machine-learning-model; training datasets are components of type data; intended use cases are use case definitions referenced from the model; and ethical and fairness considerations are entries in the document's risk model. This perspective assumes the AI/ML model properties proposed in CycloneDX/specification#990. Model data is located by descendant search so the perspective applies whether models are declared at the document root, in inventories, or in definitions; related data such as training datasets and use cases is reached through traversal steps from the model's references.", | ||
| "domains": [ | ||
| "machine-learning", | ||
| "artificial-intelligence", | ||
| "transparency", | ||
| "ethics" | ||
| ], | ||
| "mappings": [ | ||
| { | ||
| "expression": "$..[?(@.type=='machine-learning-model')]['name','version','description']", | ||
| "nativeName": "Model Details", | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Not quite sure what "native" means.
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is part of the existing perspective model and means the domain-specific term the target audience uses for that data, so a perspective can translate CycloneDX nomenclature into a familiar vocabulary. If you want this adjusted for this case, lmk. |
||
| "nativeDescription": "The identifying facts of the model: its name, version, and a description of what it is and does.", | ||
| "relevance": "required", | ||
| "weight": 1.0, | ||
| "rationale": "A model card is meaningless without stating which model, and which revision of it, the card describes." | ||
| }, | ||
| { | ||
| "expression": "$..[?(@.type=='machine-learning-model')].identifiers", | ||
| "nativeName": "Model Identifiers", | ||
| "nativeDescription": "Identifiers under which the model is published or catalogued, such as a Package-URL for a model hub entry, grouped by the party asserting them.", | ||
| "relevance": "recommended", | ||
| "weight": 0.7, | ||
| "rationale": "Name and version alone are ambiguous across hubs and forks; asserted identifiers let a card be matched to the published artefact." | ||
| }, | ||
| { | ||
| "expression": "$..[?(@.type=='machine-learning-model')].parties[?(@.roles[?(@.role=='supplier')])]", | ||
| "nativeName": "Developed By", | ||
| "nativeDescription": "The organization or individuals responsible for developing and supplying the model.", | ||
| "relevance": "required", | ||
| "weight": 0.9, | ||
| "rationale": "Accountability for a model's behaviour requires knowing who produced it. Expressed through the party model with the supplier role." | ||
| }, | ||
| { | ||
| "expression": "$..[?(@.type=='machine-learning-model')].licenses", | ||
| "nativeName": "License", | ||
| "nativeDescription": "The license under which the model, and by extension its weights, may be used.", | ||
| "relevance": "required", | ||
| "weight": 0.8, | ||
| "rationale": "Model cards conventionally state usage terms; license determines whether a given use is permitted at all." | ||
| }, | ||
| { | ||
| "expression": "$..[?(@.type=='machine-learning-model')].modelProperties.tasks", | ||
| "nativeName": "Supported Tasks", | ||
| "nativeDescription": "The machine learning tasks the model is designed to perform.", | ||
| "relevance": "required", | ||
| "weight": 0.9, | ||
| "rationale": "Tasks anchor the card: they determine the applicable inputs, outputs, and evaluation metrics." | ||
| }, | ||
| { | ||
| "expression": "$..[?(@.type=='machine-learning-model')].modelProperties.learningTypes", | ||
| "nativeName": "Learning Paradigms", | ||
| "nativeDescription": "The learning paradigms applied when training the model, such as supervised or reinforcement learning.", | ||
| "relevance": "recommended", | ||
| "weight": 0.5, | ||
| "rationale": "Helps readers judge what kinds of data and feedback shaped the model's behaviour." | ||
| }, | ||
| { | ||
| "expression": "$..[?(@.type=='machine-learning-model')].modelProperties.architecture", | ||
| "nativeName": "Model Architecture", | ||
| "nativeDescription": "The architecture family and structural characteristics of the model.", | ||
| "relevance": "recommended", | ||
| "weight": 0.7, | ||
| "rationale": "Architecture contextualizes capability and performance claims and supports reproducibility." | ||
| }, | ||
| { | ||
| "expression": "$..[?(@.type=='machine-learning-model')].modelProperties['inputs','outputs']", | ||
| "nativeName": "Input and Output Parameters", | ||
| "nativeDescription": "The modalities, formats, and constraints of the data the model consumes and produces.", | ||
| "relevance": "recommended", | ||
| "weight": 0.6, | ||
| "rationale": "Input and output specifications define the model's operational envelope and integration contract." | ||
| }, | ||
| { | ||
| "expression": "$..[?(@.type=='machine-learning-model')].modelProperties['parameterCount','quantization']", | ||
| "nativeName": "Model Size and Quantization", | ||
| "nativeDescription": "The parameter count of the model and any quantization applied to its weights.", | ||
| "relevance": "optional", | ||
| "weight": 0.3, | ||
| "rationale": "Size and quantization inform deployment cost and can affect accuracy relative to the unquantized model." | ||
| }, | ||
| { | ||
| "expression": "$..[?(@.type=='machine-learning-model')].modelProperties.training", | ||
| "nativeName": "Training Data and Procedure", | ||
| "nativeDescription": "How the model was trained: the training formula and the datasets used.", | ||
| "relevance": "recommended", | ||
| "weight": 0.8, | ||
| "rationale": "Training data provenance is central to assessing bias, capability boundaries, and data protection obligations." | ||
| }, | ||
| { | ||
| "expression": "$.formulation[*]", | ||
| "via": [ | ||
| { | ||
| "refs": "$..[?(@.type=='machine-learning-model')].modelProperties.training.formula" | ||
| } | ||
| ], | ||
| "nativeName": "Training Procedure", | ||
| "nativeDescription": "The formula describing how the model was trained: its workflows and tasks, such as pre-training, fine-tuning, and alignment stages, and the data each consumed.", | ||
| "relevance": "recommended", | ||
| "weight": 0.7, | ||
| "rationale": "Training stages and the datasets each consumed show how the data was used, which a description of the datasets alone cannot convey." | ||
| }, | ||
| { | ||
| "expression": "$..[?(@.type=='data')]['name','version','identifiers','licenses']", | ||
| "via": [ | ||
| { | ||
| "refs": "$..[?(@.type=='machine-learning-model')].modelProperties.training.datasets[*]" | ||
| } | ||
| ], | ||
| "nativeName": "Dataset Identity and Licensing", | ||
| "nativeDescription": "Which dataset was used, at which version, under which identifiers and licence terms.", | ||
| "relevance": "required", | ||
| "weight": 0.8, | ||
| "rationale": "A dataset a model card reader cannot identify or check licence terms for cannot be assessed; identity and licensing are the minimum the EU AI Act's data documentation expects." | ||
| }, | ||
| { | ||
| "expression": "$..[?(@.type=='data')].data[*]['type','description','contents']", | ||
| "via": [ | ||
| { | ||
| "refs": "$..[?(@.type=='machine-learning-model')].modelProperties.training.datasets[*]" | ||
| } | ||
| ], | ||
| "nativeName": "Dataset Description and Contents", | ||
| "nativeDescription": "What the dataset is: its general theme, a description of its size and role, and its contents or where they are held.", | ||
| "relevance": "recommended", | ||
| "weight": 0.6, | ||
| "rationale": "Describing composition and contents lets a reader judge coverage and representativeness of the training data." | ||
| }, | ||
| { | ||
| "expression": "$..[?(@.type=='data')].data[*]['classification','sensitiveData']", | ||
| "via": [ | ||
| { | ||
| "refs": "$..[?(@.type=='machine-learning-model')].modelProperties.training.datasets[*]" | ||
| } | ||
| ], | ||
| "nativeName": "Dataset Classification and Sensitive Data", | ||
| "nativeDescription": "The protection level the dataset requires and any sensitive or personal data it contains.", | ||
| "relevance": "recommended", | ||
| "weight": 0.7, | ||
| "rationale": "Sensitive-data declarations drive data protection obligations and are a primary concern of AI regulation." | ||
| }, | ||
| { | ||
| "expression": "$..[?(@.type=='data')].data[*].governance", | ||
| "via": [ | ||
| { | ||
| "refs": "$..[?(@.type=='machine-learning-model')].modelProperties.training.datasets[*]" | ||
| } | ||
| ], | ||
| "nativeName": "Dataset Governance", | ||
| "nativeDescription": "The parties accountable for the dataset through its lifecycle: owners, stewards, and custodians.", | ||
| "relevance": "recommended", | ||
| "weight": 0.5, | ||
| "rationale": "Governance names who is accountable for the data, which regulators and downstream users need to trace provenance and responsibility." | ||
| }, | ||
| { | ||
| "expression": "$..[?(@.type=='machine-learning-model')].modelProperties.evaluation", | ||
| "nativeName": "Quantitative Analysis", | ||
| "nativeDescription": "Evaluation results: performance metrics, per-slice measurements, confidence intervals, and supporting graphics.", | ||
| "relevance": "recommended", | ||
| "weight": 0.8, | ||
| "rationale": "Metrics, including slice-level results, substantiate capability claims and surface performance disparities between groups." | ||
| }, | ||
| { | ||
| "expression": "$..[?(@.type=='machine-learning-model')].modelProperties.useCases", | ||
| "nativeName": "Intended Use", | ||
| "nativeDescription": "References to the use cases the model is intended for.", | ||
| "relevance": "required", | ||
| "weight": 0.9, | ||
| "rationale": "Intended use separates in-scope application from misuse; it is the card section most consulted by adopters and assessors." | ||
| }, | ||
| { | ||
| "expression": "$.definitions.useCases[*]", | ||
| "via": [ | ||
| { | ||
| "refs": "$..[?(@.type=='machine-learning-model')].modelProperties.useCases[*]" | ||
| } | ||
| ], | ||
| "nativeName": "Use Case Definitions", | ||
| "nativeDescription": "The use case definitions that the model's intended-use references resolve to.", | ||
| "relevance": "recommended", | ||
| "weight": 0.6, | ||
| "rationale": "The model links to use cases by reference; the definitions carry the actual descriptions a card reader needs." | ||
| }, | ||
| { | ||
| "expression": "$..[?(@.type=='machine-learning-model')].parties[?(@.roles[?(@.role=='end-user')])]", | ||
| "nativeName": "Intended Users", | ||
| "nativeDescription": "The audiences the model is intended to be used by.", | ||
| "relevance": "recommended", | ||
| "weight": 0.5, | ||
| "rationale": "Stating who the model is for frames the expertise assumed of its operators. Expressed through the party model with the end-user role." | ||
| }, | ||
| { | ||
| "expression": "$..[?(@.type=='machine-learning-model')].modelProperties.limitations", | ||
| "nativeName": "Technical Limitations", | ||
| "nativeDescription": "Known technical limitations of the model, including constraints on accuracy, reasoning, scalability, and appropriate use, and relevant performance tradeoffs.", | ||
| "relevance": "required", | ||
| "weight": 0.9, | ||
| "rationale": "Limitations are the card's primary safeguard against use outside the model's competence." | ||
| }, | ||
| { | ||
| "expression": "$.risks.risks[?(@.domains[?(@.type=='ethical')])]", | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I get the feeling Steve may be reworking "risk" as the object includes perhaps too much... The goal is to isolate risks, harms and benefits more effectively so perhaps they can be disassociated from most of the risk object (and optionally tied/bound to risks) and include them in "considerations" (for model design).
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. probably shouldn't be in scope for this PR |
||
| "nativeName": "Ethical Considerations", | ||
| "nativeDescription": "Risks in the ethical domain associated with the model, including affected parties, benefits, harms, and mitigations.", | ||
| "relevance": "required", | ||
| "weight": 0.9, | ||
| "rationale": "Ethical considerations are expressed as entries in the document's risk model rather than as card-local prose, gaining structured likelihood, impact, and response data. Risks reference the components they affect, not the other way round, so this mapping is evaluated over the whole document rather than through a traversal step; tooling may narrow it to risks whose `affects` include the scoped model." | ||
| }, | ||
| { | ||
| "expression": "$.risks.risks[?(@.inherentRisk.impact.categories[?(@=='fairness' || @=='bias')])]", | ||
| "nativeName": "Fairness Assessments", | ||
| "nativeDescription": "Risks whose impact is categorized as fairness or bias, describing groups at risk and observed disparities.", | ||
| "relevance": "recommended", | ||
| "weight": 0.6, | ||
| "rationale": "Fairness assessments identify demographic or group-level performance disparities; slice-level evaluation metrics provide their quantitative backing. Risks reference the components they affect, not the other way round, so this mapping is evaluated over the whole document rather than through a traversal step; tooling may narrow it to risks whose `affects` include the scoped model." | ||
| }, | ||
| { | ||
| "expression": "$..[?(@.type=='machine-learning-model')].modelProperties.environmental", | ||
| "nativeName": "Environmental Considerations", | ||
| "nativeDescription": "Energy consumption and carbon cost of model activities such as training and inference.", | ||
| "relevance": "recommended", | ||
| "weight": 0.5, | ||
| "rationale": "Environmental impact is an established model card section and increasingly a reporting obligation." | ||
| } | ||
| ] | ||
| } | ||
| ] | ||
| } | ||
Uh oh!
There was an error while loading. Please reload this page.