Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
f5956fd
data-model: first version
Silvanoc Mar 13, 2026
a84150b
linkml-openapigen: fixes and improvements over upstream
Silvanoc Mar 23, 2026
3c8ab85
openapi-validation: add tool to validate openapi generation
Silvanoc Jul 15, 2026
c526c48
tests: add (in)valid examples for data-model validation
Silvanoc Jul 18, 2026
bf3093c
tools: generate artifacts from data-model
Silvanoc Mar 13, 2026
5bad94b
docs: diffs pre data-model
Silvanoc Jul 17, 2026
d8e9ebf
docs: add ai agents help
Silvanoc May 13, 2026
e0b9095
deps: add and update
Silvanoc Jul 17, 2026
880b9fc
ci: update workflows
Silvanoc May 13, 2026
0411b78
validation tool - improve output
Silvanoc Jul 20, 2026
4bde9e0
validation tool - add option to show single schema
Silvanoc Jul 20, 2026
797d398
validation tool - add option to dump compared yaml
Silvanoc Jul 20, 2026
f6c8e14
style: openapigen format
Silvanoc Jul 20, 2026
208364d
openapigen: accept further properties
Silvanoc Jul 20, 2026
7795a10
openapigen: workaround linkml issue 3611
Silvanoc Jul 21, 2026
0d5321c
data-model: remove references specification pages
Silvanoc Jul 21, 2026
db8cb62
refactor: new folder structure
Silvanoc Jul 27, 2026
3461539
feat: support nullable required slots
Silvanoc Jul 28, 2026
82fc958
docs: describe how to generate the openapi yaml
Silvanoc Jul 28, 2026
6ff19dc
generated: class diagrams
Silvanoc Jul 18, 2026
3e9c83f
docs: describe how to compare the openapi
Silvanoc Jul 28, 2026
71f6932
fix: get openapi v3.1.0 working
Silvanoc Jul 29, 2026
b2bfe23
update generated openapi
Silvanoc Jul 31, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .githooks/pre-push
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ do

# Check test examples
set -e
doc-generation/check-examples.bash
data-model/tools/check-examples.bash
set +e

fi
Expand Down
25 changes: 15 additions & 10 deletions .github/workflows/pages.yml
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ jobs:

- name: Run tests
run: |
doc-generation/check-examples.bash
tools/check-examples.bash

documents:
needs:
Expand Down Expand Up @@ -90,17 +90,18 @@ jobs:
- name: Install dependencies
run: poetry install --no-interaction --all-extras

- name: Generate MarkDown documentation
- name: Generate all artifacts
run: |
doc-generation/generate-documentation.bash
tools/generate-all.bash

- name: Share generated documentation with later jobs
- name: Share generated artifacts with later jobs
uses: actions/upload-artifact@v4
with:
name: generated-documentation
name: generated-artifacts
path: |
system-design/specification/applications/application-description.md
system-design/specification/margo-management-interface/desired-state.md
docs/specification/applications/application-description.md
docs/specification/margo-management-interface/desired-state.md
system-design/specification/margo-management-interface/workload-management-api-1.0.0.yaml

pages:
needs:
Expand Down Expand Up @@ -135,11 +136,15 @@ jobs:
- name: Install the project dependencies
run: poetry install

- name: Get generated documentation from previous jobs
- name: Get generated artifacts from previous jobs
uses: actions/download-artifact@v4
with:
name: generated-documentation
path: system-design/specification
name: generated-artifacts
path: docs/specification

- name: Generate merged documentation tree
run: |
tools/generate-docs.bash

- name: Build Pages
run: poetry run -- mkdocs build
Expand Down
7 changes: 3 additions & 4 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,7 @@ myenv
.python-version

# Ignore the generated files:
system-design/specification/margo-management-interface/desired-state.md
system-design/specification/applications/application-description.md
src/specification/applications/docs
src/specification/margo-management-interface/docs
build
docs/specification/margo-management-interface/desired-state.md
docs/specification/applications/application-description.md
*.code-workspace
336 changes: 336 additions & 0 deletions AGENTS.md

Large diffs are not rendered by default.

26 changes: 21 additions & 5 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -138,13 +138,13 @@ Once the required tools have been installed as documented in the [Preparation](#
As mentioned in a previous section, as of now only some of the resources are being specified in LinkML and are being used to generate the MarkDown documents.
Steps 1. and 2. only apply to those documents.

Currently two Bash scripts are being provided the directory `doc-generation` to simplify steps 1. and 2.
Currently several Bash scripts are being provided in the directory `tools` to simplify steps 1. and 2.

The input for the generation of the MarkDown documents is provided in the directory `[src](./src/)`.
The input for the generation of the MarkDown documents is provided in the directory [model](./model/).

#### Validate input for MarkDown Generation

The script [check-examples.bash](./doc-generation/check-examples.bash) checks:
The script [check-examples.bash](./tools/check-examples.bash) checks:

- the validity of the LinkML resource definitions (AKA schemas), and
- the validity of provided examples and counter-examples according the resource definitions
Expand All @@ -153,9 +153,25 @@ The script [check-examples.bash](./doc-generation/check-examples.bash) checks:

#### Generate MarkDown Documents

The script [generate-documentation.bash](./doc-generation/generate-documentation.bash) generates MarkDown documents for the resources specified in LinkML format.
The script [generate-docs.bash](./tools/generate-docs.bash) generates MarkDown documents for the resources specified in LinkML format.

The LinkML specification documents can be found in the directory [src](./src/) and the resulting MarkDown documents are integrated with the other MarkDown documents in the directory [system-design](./system-design/).
The LinkML specification documents can be found in the directory [model](./model/) and the resulting MarkDown documents are integrated with the other MarkDown documents in the directory [docs](./docs/).

#### Generate OpenAPI YAML Documents

The script [generate-openapi.bash](./tools/generate-openapi.bash) generates the OpenAPI v3.0.3 specification YAML file for the Workload Management API.

It uses the custom generator [openapigen.py](./tools/openapigen.py) which composes a user-provided OpenAPI template (containing API header, paths/endpoints, and security schemes) with JSON Schema components generated from the LinkML data model. Only schemas referenced by the template's endpoints (and their transitive dependencies) are included.

The generation:

1. Reads the aggregate data model [`model/margo-data-model.linkml.yaml`](./model/margo-data-model.linkml.yaml) as the LinkML source.
2. Reads the OpenAPI template [`tools/templates/openapi/workload-management-api-1.0.0.openapi.yaml`](./tools/templates/openapi/workload-management-api-1.0.0.openapi.yaml) which defines the API endpoints, request/response structures, and security schemes.
3. Generates JSON Schema definitions for all referenced classes and injects them under `components/schemas` in the template.
4. Writes the output to `build/artifacts/openapi/workload-management-api-1.0.0.openapi.yaml`.
5. Copies the result into the tracked location `system-design/specification/margo-management-interface/workload-management-api-1.0.0.yaml` for version control. `generate-docs.bash` copies it from there into `build/site/` for MkDocs.

When adding new API endpoints, edit the OpenAPI template to add the corresponding `paths` entries referencing the relevant `$ref: "#/components/schemas/<ClassName>"` schemas.

#### Generate HTML Documents

Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes
56 changes: 56 additions & 0 deletions docs/assets/svg-pan-zoom-init.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
/**
* Initialize svg-pan-zoom on containers marked with data-svg-pan-zoom.
* Each container should have a data-svg-src attribute pointing to the SVG file.
* The SVG is fetched, inlined into the DOM, and then svg-pan-zoom is attached.
*/
document.addEventListener("DOMContentLoaded", function () {
var containers = document.querySelectorAll("[data-svg-pan-zoom]");
containers.forEach(function (container) {
var svgSrc = container.getAttribute("data-svg-src");
if (!svgSrc) return;

fetch(svgSrc)
.then(function (response) { return response.text(); })
.then(function (svgText) {
// Parse the SVG and insert it into the container
var parser = new DOMParser();
var svgDoc = parser.parseFromString(svgText, "image/svg+xml");
var svgEl = svgDoc.documentElement;

// Make the SVG fill the container
svgEl.setAttribute("width", "100%");
svgEl.setAttribute("height", "100%");
svgEl.style.width = "100%";
svgEl.style.height = "100%";

container.appendChild(svgEl);

// Initialize svg-pan-zoom
var panZoomInstance = svgPanZoom(svgEl, {
zoomEnabled: true,
controlIconsEnabled: true,
fit: true,
center: true,
minZoom: 0.25,
maxZoom: 20,
zoomScaleSensitivity: 0.3
});

// Handle resize
window.addEventListener("resize", function () {
panZoomInstance.resize();
panZoomInstance.fit();
panZoomInstance.center();
});
})
.catch(function (err) {
console.error("Failed to load SVG for pan-zoom:", err);
// Fallback: show as a regular image
var img = document.createElement("img");
img.src = svgSrc;
img.alt = container.getAttribute("data-svg-alt") || "SVG diagram";
img.style.width = "100%";
container.appendChild(img);
});
});
});
3 changes: 3 additions & 0 deletions docs/assets/svg-pan-zoom.min.js

Large diffs are not rendered by default.

File renamed without changes.
26 changes: 26 additions & 0 deletions docs/css/margo.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
[data-md-color-scheme="margo"] {
--md-primary-fg-color: hsla(218, 99%, 28%, 1);
--md-footer-bg-color: hsla(218, 99%, 28%, 1);
}

/* SVG pan-zoom container */
.svg-pan-zoom-container {
width: 100%;
height: 600px;
border: 1px solid var(--md-default-fg-color--lightest, #e0e0e0);
border-radius: 4px;
background: var(--md-default-bg-color, #fff);
position: relative;
overflow: hidden;
}

.svg-pan-zoom-container svg {
display: block;
}

.svg-pan-zoom-hint {
font-size: 0.75rem;
color: var(--md-default-fg-color--light, #999);
margin-top: 0.25rem;
font-style: italic;
}
File renamed without changes.
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# Deployment Status API

While applying a new desired state, the device's management client MUST provide the Workload Fleet Manager service with an indication of the current workload deployment status. This is done by calling the Device API's `deployment status` endpoint.

- Requests to this endpoint MUST be authenticated using the HTTP Message Signature method as defined in the [Payload Security](../margo-management-interface/api-requirements-and-security.md#payload-security-method) section.

> Note: This assumes consistent connection to the WFM, we will address intermittent or extended disconnection scenarios in the future.

## Route and HTTP Methods

```https
POST /api/v1/clients/{clientId}/deployments/{deploymentId}/status
```

### Route Parameters

|Parameter | Type | Required? | Description|
|----------|------|-----------|------------|
| {clientId} | string | Y | The unique identifier of the (device) client registered with the WFM during onboarding. |
| {deploymentId} | string | Y | The UUID of the `ApplicationDeployment` YAML being reported.

### Response Codes

| Code | Description |
|------|-------------|
| 200 OK | The deployment status was added, or updated, successfully. |
| 400 Bad Request | Missing or invalid content-digest header. Ensure the SHA256 hash of the base64-encoded payload is included. |
| 401 Unauthorized | Signature verification failed. Ensure you are signing with the correct X.509 private key. |
| 403 Forbidden | Client certificate is not trusted or has been revoked. |
| 422 Unprocessable Content | Request body includes a semantic error. |


## Request Body

[DeploymentStatus](./deployment status.md) document describing the status of an application deployment.

Loading