Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
23160a4
feat(etch): type_shapes provider for custom SVG node shapes
Mar 22, 2026
6e44bbd
feat(validate): draft-aware severity for traceability rules
Mar 22, 2026
3082d90
refactor: extract all view render functions from serve/views.rs
Mar 23, 2026
56577a5
feat(vscode): add all views to tree + wire remaining render routes
Mar 23, 2026
df37ca8
ci: add VS Code Marketplace publishing to release workflow
Mar 23, 2026
d3776dd
feat(cli): add rivet export --html for static site generation
Mar 27, 2026
b11f9ea
feat: add test report lifecycle artifacts (REQ-040, FEAT-071, FEAT-072)
Mar 27, 2026
1ce76c2
fix(vscode): auto-detect rivet.yaml location in workspace
Mar 27, 2026
daec3d5
feat(vscode): artifact search with live LSP query
Mar 27, 2026
b1e71a4
docs: update AGENTS.md for v0.3.0 architecture
Mar 27, 2026
ec25d33
test(playwright): add E2E tests for documents, help, coverage, tracea…
Mar 27, 2026
2b2a92f
test+feat: 310 Playwright tests, artifact search, AGENTS.md update
Mar 27, 2026
fd4ed6b
feat(graph): custom SVG shapes per artifact type via etch type_shapes
Mar 27, 2026
3efaa3e
feat(help): enhanced schema detail with fields, links, Mermaid diagram
Mar 27, 2026
b105e12
test(playwright): schema detail, graph shapes, help linkage tests
Mar 27, 2026
33eeea8
fix(vscode): source line navigation + auto-refresh on save
Mar 27, 2026
2f537ca
test(vscode): functional extension tests — LSP, WebView, tree view
Mar 27, 2026
dff3021
fix(lsp): clear stale diagnostics when issues are resolved
Mar 27, 2026
d72a216
style: fix cargo fmt + clippy (&String → &str)
Mar 28, 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
58 changes: 57 additions & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,56 @@ jobs:
env:
DISPLAY: ':99.0'

# ── Build VS Code VSIX (release tags only) ───────────────────────────
build-vsix:
name: Build VS Code Extension VSIX
runs-on: ubuntu-latest
if: startsWith(github.ref, 'refs/tags/v')
steps:
- uses: actions/checkout@v6
- uses: actions/setup-node@v4
with:
node-version: '22'
- name: Install extension dependencies
working-directory: vscode-rivet
run: npm ci
- name: Compile extension
working-directory: vscode-rivet
run: npm run compile
- name: Package VSIX
working-directory: vscode-rivet
run: npx @vscode/vsce package --no-dependencies
- uses: actions/upload-artifact@v4
with:
name: vsix
path: vscode-rivet/*.vsix

# ── Publish VS Code Extension to Marketplace (release tags only) ─────
publish-vsix:
name: Publish to VS Code Marketplace
needs: [build-vsix, release-results]
runs-on: ubuntu-latest
if: startsWith(github.ref, 'refs/tags/v')
steps:
- uses: actions/download-artifact@v4
with:
name: vsix
path: vsix
- uses: actions/setup-node@v4
with:
node-version: '22'
- name: Publish to Marketplace
# Requires VSCE_PAT secret in GitHub repo settings.
# See: https://code.visualstudio.com/api/working-with-extensions/publishing-extension
run: |
if [ -n "$VSCE_PAT" ]; then
npx @vscode/vsce publish --packagePath vsix/*.vsix
else
echo "VSCE_PAT not set, skipping marketplace publish"
fi
env:
VSCE_PAT: ${{ secrets.VSCE_PAT }}

# ── Security audits ──────────────────────────────────────────────────
audit:
name: Security Audit (RustSec)
Expand Down Expand Up @@ -324,7 +374,7 @@ jobs:
release-results:
name: Publish Test Results on Release
if: startsWith(github.ref, 'refs/tags/v')
needs: [test, coverage, miri, proptest, playwright]
needs: [test, coverage, miri, proptest, playwright, build-vsix]
runs-on: ubuntu-latest
permissions:
contents: write
Expand All @@ -348,6 +398,11 @@ jobs:
uses: actions/attest-build-provenance@v2
with:
subject-path: target/release/rivet
- name: Download VSIX artifact
uses: actions/download-artifact@v4
with:
name: vsix
path: vsix
- name: Package results
run: |
VERSION="${GITHUB_REF#refs/tags/}"
Expand All @@ -366,3 +421,4 @@ jobs:
files: |
release-results-*.tar.gz
target/release/rivet
vsix/*.vsix
166 changes: 166 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,166 @@
<!-- Auto-generated by `rivet init --agents`. Re-run to update after artifact changes. -->
# AGENTS.md — Rivet Project Instructions

> This file was generated by `rivet init --agents`. Re-run the command
> any time artifacts change to keep this file current.

## Project Overview

This project uses **Rivet** for SDLC artifact traceability.
- Config: `rivet.yaml`
- Schemas: common, dev, aadl, stpa, stpa-sec
- Artifacts: 492 across 19 types
- Validation: `rivet validate` (current status: pass)

## Available Commands

| Command | Purpose | Example |
|---------|---------|---------|
| `rivet validate` | Check link integrity, coverage, required fields | `rivet validate --format json` |
| `rivet list` | List artifacts with filters | `rivet list --type requirement --format json` |
| `rivet stats` | Show artifact counts by type | `rivet stats --format json` |
| `rivet add` | Create a new artifact | `rivet add -t requirement --title "..." --link "satisfies:SC-1"` |
| `rivet link` | Add a link between artifacts | `rivet link SOURCE -t satisfies --target TARGET` |
| `rivet serve` | Start the dashboard | `rivet serve --port 3000` |
| `rivet export --html` | Generate static HTML site | `rivet export --format html --output ./dist` |
| `rivet lsp` | Start the language server (LSP over stdio) | `rivet lsp` |
| `rivet impact` | Show change impact | `rivet impact --since HEAD~1` |
| `rivet coverage` | Show traceability coverage | `rivet coverage --format json` |
| `rivet diff` | Compare artifact versions | `rivet diff --base path/old --head path/new` |

## Artifact Types

| Type | Count | Description |
|------|------:|-------------|
| `aadl-component` | 29 | AADL component type or implementation imported from spar |
| `control-action` | 18 | An action issued by a controller to a controlled process or another controller. |
| `controlled-process` | 5 | A process being controlled — the physical or data transformation acted upon by controllers. |
| `controller` | 7 | A system component (human or automated) responsible for issuing control actions. Each controller has a process model — its internal beliefs about the state of the controlled process. |
| `controller-constraint` | 59 | A constraint on a controller's behavior derived by inverting a UCA. Specifies what the controller must or must not do. |
| `design-decision` | 41 | An architectural or design decision with rationale |
| `feature` | 107 | A user-visible capability or feature |
| `hazard` | 20 | A system state or set of conditions that, together with worst-case environmental conditions, will lead to a loss. |
| `loss` | 6 | An undesired or unplanned event involving something of value to stakeholders. Losses define what the analysis aims to prevent. |
| `loss-scenario` | 34 | A causal pathway describing how a UCA could occur or how the control action could be improperly executed, leading to a hazard. |
| `requirement` | 40 | A functional or non-functional requirement |
| `sec-constraint` | 7 | A security constraint — a condition or behavior required to prevent a security hazard. Each constraint is the security inversion of a hazard. |
| `sec-hazard` | 7 | A security hazard — a system state or condition that, if exploited by an adversary in a worst-case environment, leads to a security loss. |
| `sec-loss` | 5 | A security loss — an undesired event involving breach of a CIA property (confidentiality, integrity, or availability). Parallels the STPA 'loss' type but is scoped to adversarial threats. |
| `sec-scenario` | 7 | A security loss scenario — a causal pathway (with adversarial causation) describing how a sec-uca could occur or how the control action could be exploited by an adversary to reach a security hazard. |
| `sec-uca` | 7 | A security Unsafe Control Action — a control action that, in a particular adversarial context, leads to a security hazard. Includes an adversarial-causation field explaining how an attacker could introduce or exploit this UCA. |
| `sub-hazard` | 12 | A refinement of a hazard into a more specific unsafe condition. |
| `system-constraint` | 22 | A condition or behavior that must be satisfied to prevent a hazard. Each constraint is the inversion of a hazard. |
| `uca` | 59 | An Unsafe Control Action — a control action that, in a particular context and worst-case environment, leads to a hazard. Four types (provably complete): 1. Not providing the control action leads to a hazard 2. Providing the control action leads to a hazard 3. Providing too early, too late, or in the wrong order 4. Control action stopped too soon or applied too long |
| `aadl-analysis-result` | 0 | Output of a spar analysis pass |
| `aadl-flow` | 0 | End-to-end flow with latency bounds |
| `aadl-tool` | 0 | An AADL ecosystem tool — captures what it does, what makes it unique, and what capabilities spar could adopt from it. |

## Working with Artifacts

### File Structure
- Artifacts are stored as YAML files in: `artifacts`, `safety/stpa`, `safety/stpa-sec`
- Schema definitions: `schemas/` directory
- Documents: `docs`, `arch`

### Creating Artifacts
```bash
rivet add -t requirement --title "New requirement" --status draft --link "satisfies:SC-1"
```

### Validating Changes
Always run `rivet validate` after modifying artifact YAML files.
Use `rivet validate --format json` for machine-readable output.

### Draft-Aware Validation
Artifacts with `status: draft` receive **info**-level diagnostics (not warnings/errors)
for missing required links. This allows drafts to exist without blocking CI while still
surfacing traceability gaps. Promote to `status: approved` to enforce full link rules.

### Link Types

| Link Type | Description | Inverse |
|-----------|-------------|--------|
| `acts-on` | Control action acts on a process or controller | `acted-on-by` |
| `allocated-to` | Source is allocated to the target (e.g. requirement to architecture component) | `allocated-from` |
| `caused-by-sec-uca` | Security scenario is caused by a security UCA | `causes-sec-scenario` |
| `caused-by-uca` | Loss scenario is caused by an unsafe control action | `causes-scenario` |
| `constrained-by` | Source is constrained by the target | `constrains` |
| `constrains-controller` | Constraint applies to a specific controller | `controller-constrained-by` |
| `depends-on` | Source depends on target being completed first | `depended-on-by` |
| `derives-from` | Source is derived from the target | `derived-into` |
| `implements` | Source implements the target | `implemented-by` |
| `inverts-uca` | Controller constraint inverts (is derived from) an UCA | `inverted-by` |
| `issued-by` | Control action or UCA is issued by a controller | `issues` |
| `leads-to-hazard` | UCA or loss scenario leads to a hazard | `hazard-caused-by` |
| `leads-to-loss` | Hazard leads to a specific loss | `loss-caused-by` |
| `leads-to-sec-hazard` | Sec-UCA or sec-scenario leads to a security hazard | `sec-hazard-caused-by` |
| `leads-to-sec-loss` | Security hazard leads to a security loss | `sec-loss-caused-by` |
| `mitigates` | Source mitigates or prevents the target | `mitigated-by` |
| `modeled-by` | An architecture component is modeled by an AADL component | `models` |
| `prevents` | Constraint prevents a hazard | `prevented-by` |
| `prevents-sec-hazard` | Security constraint prevents a security hazard | `sec-hazard-prevented-by` |
| `refines` | Source is a refinement or decomposition of the target | `refined-by` |
| `satisfies` | Source satisfies or fulfils the target | `satisfied-by` |
| `traces-to` | General traceability link between any two artifacts | `traced-from` |
| `verifies` | Source verifies or validates the target | `verified-by` |

## Architecture Notes

### Render Module (`rivet-cli/src/render/`)
The `render/` module contains 18 extracted view render functions used by both the
axum HTTP server and the LSP server. Modules include:
`artifacts`, `components`, `coverage`, `diff`, `doc_linkage`, `documents`, `externals`,
`graph`, `help`, `helpers`, `matrix`, `results`, `search`, `source`, `stats`, `stpa`,
`styles`, `traceability`, `validate`

The serve layer (`rivet-cli/src/serve/`) is a thin axum wrapper that calls into `render/`.
The LSP server uses the same render functions via custom requests.

### LSP Server (`rivet lsp`)
The language server communicates over stdio and supports:
- Standard LSP: diagnostics, hover, go-to-definition, completion
- Custom requests:
- `rivet/render` — render a named view (page + params) to HTML
- `rivet/treeData` — return tree-view children for a given parent path
- `rivet/css` — return the full CSS bundle
- `rivet/artifactsChanged` — notification sent when artifacts reload

### VS Code Extension
- Creates a **WebviewPanel** (not Simple Browser) for rendered artifact views
- Auto-detects `rivet.yaml` location by searching workspace roots up to 2 levels deep;
falls back to `rivet.workspaceRoot` setting
- Provides a tree view (Documents, Views, Help, Artifact Files)
- Supports artifact Quick Pick search via LSP `rivet/treeData`
- Works correctly over SSH Remote (no port forwarding required)

### HTML Export (`rivet export --html`)
Generates a static HTML site using the shared render module. Output is self-contained
with bundled assets (HTMX, Mermaid, fonts). Use `--output ./dist` to set the output
directory.

### Etch (`etch/`) — Graph Rendering
The `etch` crate provides Sugiyama layout → SVG rendering for artifact graphs.
It supports `type_shapes`: a map from node type to a custom `ShapeProvider` closure
that returns raw SVG element strings. This allows per-artifact-type custom node shapes.

## Conventions

- Artifact IDs follow the pattern: PREFIX-NNN (e.g., REQ-001, FEAT-042)
- Use `rivet add` to create artifacts (auto-generates next ID)
- Always include traceability links when creating artifacts
- Run `rivet validate` before committing

## Commit Traceability

This project enforces commit-to-artifact traceability.

Required git trailers:
- `Fixes` -> maps to link type `fixes`
- `Implements` -> maps to link type `implements`
- `Refs` -> maps to link type `traces-to`
- `Satisfies` -> maps to link type `satisfies`
- `Verifies` -> maps to link type `verifies`

Exempt artifact types (no trailer required): `chore`, `style`, `ci`, `docs`, `build`

To skip traceability for a commit, add: `Trace: skip`
35 changes: 35 additions & 0 deletions artifacts/features.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -1213,6 +1213,41 @@ artifacts:
phase: future
baseline: v0.3.0

- id: FEAT-071
type: feature
title: JUnit XML test result import
status: draft
description: >
CLI command rivet import --format junit that reads JUnit XML test
result files and creates rivet TestRun entries in results/. Maps
JUnit testcase elements to artifact IDs via naming convention or
explicit mapping. Enables CI pipelines to feed test evidence into
rivet's traceability chain.
tags: [testing, import, ci, future]
links:
- type: satisfies
target: REQ-040
fields:
phase: future
baseline: v0.4.0

- id: FEAT-072
type: feature
title: Test report conformance workflow
status: draft
description: >
Automated workflow: CI runs tests, imports results as rivet artifacts,
generates a test report document, creates a PR with the report. Human
reviews and merges. Release includes the report as both a rivet
artifact and a download. Dogfoods rivet's own test evidence tracking.
tags: [testing, ci, workflow, dogfood, future]
links:
- type: satisfies
target: REQ-040
fields:
phase: future
baseline: v0.4.0

- id: FEAT-070
type: feature
title: Draft-aware validation severity
Expand Down
17 changes: 17 additions & 0 deletions artifacts/requirements.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -646,6 +646,23 @@ artifacts:
category: functional
baseline: v0.3.0

- id: REQ-040
type: requirement
title: Test report lifecycle integration
status: draft
description: >
CI test runs produce structured results (JUnit XML) that are imported
into rivet as test result artifacts. The workflow is: run tests, import
results via rivet import --format junit, create a test report artifact
in results/, conformance review, commit report as PR, include in
release. Test evidence becomes part of the traceability chain — rivet
dogfoods its own test tracking.
tags: [testing, ci, dogfood, future]
fields:
priority: should
category: functional
baseline: v0.4.0

- id: REQ-039
type: requirement
title: Draft-aware validation severity
Expand Down
Loading
Loading