Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ cargo install --path rivet-cli

# Or grab a prebuilt release binary directly (substitute your platform /
# the current version — assets are named rivet-vX.Y.Z-<target>)
curl -L https://github.com/pulseengine/rivet/releases/download/v0.16.1/rivet-v0.16.1-x86_64-unknown-linux-gnu.tar.gz | tar xz
curl -L https://github.com/pulseengine/rivet/releases/download/v0.19.0/rivet-v0.19.0-x86_64-unknown-linux-gnu.tar.gz | tar xz
```

`npm`/`npx` is the zero-toolchain path — it fetches the same signed
Expand All @@ -87,7 +87,7 @@ mcp` without a Rust install.

```bash
rivet init --preset dev # 1. scaffold rivet.yaml + schemas/ + artifacts/
rivet add requirement -t "DB write returns ack" --asil B # 2. add a typed atom
rivet add -t requirement --title "DB write returns ack" # 2. add a typed atom
rivet validate # 3. oracle: PASS (no diagnostics)
rivet serve --port 3099 # 4. dashboard at http://localhost:3099
rivet docs quickstart # 5. 10-step embedded guide w/ oracles
Expand Down
138 changes: 133 additions & 5 deletions docs/getting-started.md
Original file line number Diff line number Diff line change
Expand Up @@ -446,6 +446,66 @@ Orphan artifacts (no links): 3
REQ-012
```

### `rivet coverage`

Report traceability coverage per rule — for each source type governed by a
traceability rule, the share of artifacts that satisfy it.

```bash
rivet coverage
rivet coverage --format json
rivet coverage --fail-under 80 # non-zero exit if overall < 80%
rivet coverage --tests # test-to-requirement coverage from source markers
```

For every source type governed by more than one rule, the report also prints a
combined **V-closure** figure: the share of artifacts satisfying *every*
applicable rule (e.g. requirements that are BOTH satisfied AND verified). This
intersection is strictly stronger than the per-rule numbers, which hide the gap
when different artifacts miss different rules. `--format json` carries it as a
`closure` array (`closed` / `total` / `open_ids` / `percentage` / `rule_names`).
External-boundary (supplier-delegated) artifacts count as closed, matching the
3-state coverage convention.

### `rivet verify`

Advance a requirement from `implemented` to `verified` when it has verifying
test evidence — an incoming `verifies` link OR a `// rivet: verifies <ID>`
source marker (scanned from `src/` and `tests/`, or extra paths via `--scan`).

```bash
rivet verify REQ-042
rivet verify REQ-042 --scan integration-tests/
```

This is an opt-in, auditable command: it refuses with an actionable message
when there is no evidence, no-ops if the artifact is already `verified`, and
rejects non-`implemented` states. The write reuses the schema-validated
`modify --set-status` path.

### `rivet query`

Run an s-expression filter and print matches. Mirror of the MCP `rivet_query`
tool and the `{{query:(...)}}` document embed — all three share one evaluator,
so their results agree for the same filter. See
[S-Expression Filtering](#s-expression-filtering) for the predicate reference.

```bash
rivet query '(= type "requirement")'
rivet query '(and (= type "requirement") (has-tag "safety"))' --format json
rivet query '(not (linked-from "verifies" _))' --format ids # newline-separated IDs
```

### `rivet sql`

Run SQL over the artifact store — reads and a constrained set of writes — with
no server and no MCP required. See [SQL over the artifact
store](#sql-over-the-artifact-store) for the table schema and examples.

```bash
rivet sql "SELECT id, status FROM artifacts WHERE type='requirement'"
```

### `rivet matrix`

Generate a traceability matrix showing coverage between two artifact types.
Expand Down Expand Up @@ -494,9 +554,16 @@ Export all project artifacts to a specified format.
```bash
rivet export --format reqif --output artifacts.reqif
rivet export --format generic-yaml # stdout
rivet export --format html --output ./dist # static dashboard
rivet export --format zola --output ./site # Zola content tree
rivet export --format gherkin --output ./features # .feature files
```

Supported formats: `reqif` (ReqIF 1.2 XML), `generic-yaml`.
Supported formats: `reqif` (ReqIF 1.2 XML), `generic-yaml`, `html` (static
dashboard; `--single-page`, `--theme dark|light`, `--offline`), `zola` (a Zola
content tree), and `gherkin` (`.feature` files). The `html`, `zola`, and
`snapshot`/`embed` exporters share the dashboard renderer and are gated behind
the `serve` cargo feature (present in the default build).

### `rivet serve`

Expand Down Expand Up @@ -863,6 +930,66 @@ on links, use the purpose-built predicates (`linked-by`, `linked-from`,

---

## SQL over the artifact store

`rivet sql` projects the artifact store into an in-memory SQLite database and
runs SQL against it — **no server and no MCP required**. The projection is
rebuilt per invocation, so results are never stale. SQL gives you JOINs and
aggregations the s-expression filter cannot express; reach for it when a
question spans relationships between artifacts.

Four virtual tables are projected:

| Table | Columns |
|--------------|--------------------------------------------------------------------------|
| `artifacts` | `id`, `type`, `title`, `description`, `status`, `fields_json` |
| `links` | `source`, `link_type`, `target`, `external` |
| `fields` | `artifact_id`, `key`, `value` (EAV — one row per field, for JOINs) |
| `provenance` | `artifact_id`, `created_by`, `model`, `session_id`, `timestamp`, `reviewed_by` |

Output is `table` (default), `json` (one object per row, keyed by column), or
`csv`.

### Reads — SELECT / WITH

```bash
# Count artifacts by type
rivet sql "SELECT type, COUNT(*) AS n FROM artifacts GROUP BY type ORDER BY n DESC"

# The V-closure gap: implemented requirements with no incoming `verifies` link
rivet sql "SELECT id FROM artifacts
WHERE type='requirement' AND status='implemented'
AND id NOT IN (SELECT target FROM links WHERE link_type='verifies')"

# Join artifacts to their links
rivet sql "SELECT a.id, l.link_type, l.target
FROM artifacts a JOIN links l ON l.source = a.id
WHERE a.type='requirement'" --format json

# Provenance rollup
rivet sql "SELECT created_by, COUNT(*) FROM provenance GROUP BY created_by"
```

### Writes — UPDATE

A constrained write slice routes through rivet's validated mutation path:
`UPDATE artifacts SET {status|title|description}` only. Every change is
schema-validated (status enums, reserved keys) *before* any file is touched, so
an invalid value aborts the whole statement — never a silent partial write —
and the safe YAML editor preserves sibling fields. `INSERT`, `DELETE`, and
writes to `fields` or `links` are refused with a clear message (use the
dedicated `add` / `link` / `modify` commands for those).

```bash
# Promote a requirement once it has verifying evidence
rivet sql "UPDATE artifacts SET status='verified' WHERE id='REQ-042'"
```

A no-op write (the value already matches) reports `0 artifacts changed` and
touches nothing.

---

## Variant Management (Product Line Engineering)

Manage product variants with feature models, constraint solving, and artifact scoping.
Expand Down Expand Up @@ -1155,15 +1282,16 @@ The importer:

## MCP Server (AI Agent Integration)

Rivet exposes 15 tools via the Model Context Protocol:
Rivet exposes 16 tools via the Model Context Protocol:

```bash
rivet mcp # stdio transport
```

Tools: `rivet_validate`, `rivet_list`, `rivet_get`, `rivet_stats`, `rivet_coverage`,
`rivet_schema`, `rivet_embed`, `rivet_snapshot_capture`, `rivet_add`, `rivet_query`,
`rivet_modify`, `rivet_link`, `rivet_unlink`, `rivet_remove`, `rivet_reload`.
Tools: `rivet_validate`, `rivet_list`, `rivet_get`, `rivet_bundle`, `rivet_stats`,
`rivet_coverage`, `rivet_schema`, `rivet_embed`, `rivet_snapshot_capture`,
`rivet_add`, `rivet_query`, `rivet_modify`, `rivet_link`, `rivet_unlink`,
`rivet_remove`, `rivet_reload`.

All mutations are audit-logged to `.rivet/mcp-audit.jsonl`.

Expand Down
8 changes: 4 additions & 4 deletions docs/what-is-rivet.md
Original file line number Diff line number Diff line change
Expand Up @@ -193,10 +193,10 @@ reviews*.
- **Question.** Can my AI agent read the trace graph and propose
mutations that rivet server-side-validates before I accept them?
- **Artifacts.** All of them, through MCP.
- **AI does.** Calls 15 MCP tools: `rivet_list`, `rivet_get`,
`rivet_query`, `rivet_stats`, `rivet_coverage`, `rivet_schema`,
`rivet_embed`, `rivet_add`, `rivet_modify`, `rivet_link`,
`rivet_unlink`, `rivet_remove`, `rivet_validate`,
- **AI does.** Calls 16 MCP tools: `rivet_list`, `rivet_get`,
`rivet_bundle`, `rivet_query`, `rivet_stats`, `rivet_coverage`,
`rivet_schema`, `rivet_embed`, `rivet_add`, `rivet_modify`,
`rivet_link`, `rivet_unlink`, `rivet_remove`, `rivet_validate`,
`rivet_snapshot_capture`, `rivet_reload`.
- **Human reviews.** The MCP audit log (`rivet mcp` writes every
mutation call as JSONL to the project directory) plus the git diff.
Expand Down
41 changes: 36 additions & 5 deletions rivet-cli/src/docs.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
//! `rivet docs` — built-in searchable documentation.
//!
//! All documentation is embedded in the binary. Topics are searchable
Expand Down Expand Up @@ -535,16 +535,32 @@
rivet list [-t TYPE] List artifacts (filter by type/status)
rivet get ID Show a single artifact by ID (text/json/yaml)
rivet stats Summary statistics and orphan detection
rivet coverage Traceability coverage report
rivet coverage Traceability coverage report (incl. combined V-closure)
rivet verify ID Advance implemented -> verified on test evidence
rivet matrix --from X --to Y Traceability matrix between types
rivet diff Compare artifact versions
rivet export -f FORMAT Export to reqif, generic-yaml, or html
rivet export -f FORMAT Export to reqif, generic-yaml, html, zola, or gherkin
rivet serve [-P PORT] Start HTMX dashboard (default: 3000)
rivet commits [--since N] Commit-artifact traceability analysis
rivet commit-msg-check F Validate commit message trailers (hook)
rivet impact --since REF Change impact analysis (transitive)
```

## Query Commands

```
rivet query SEXPR Run an s-expression filter (mirrors rivet_query)
rivet sql "SELECT ..." SQL over the artifact store — no server/MCP needed
rivet sql "UPDATE artifacts SET status=... WHERE ..." Validated write slice
```

`rivet sql` projects the store into in-memory SQLite (tables `artifacts`,
`links`, `fields`, `provenance`) so JOINs and aggregations the s-expression
filter can't express become one query. Reads are `SELECT`/`WITH`; the write
slice is `UPDATE artifacts SET {status|title|description}` only, validated
before any file is touched. See `rivet docs cli` examples in
`docs/getting-started.md`.

## Embed and Snapshot Commands

```
Expand All @@ -566,7 +582,7 @@

Exposes rivet tools to AI agents via the Model Context Protocol.
The server uses stdio transport and only binds to the local process.
See `rivet docs mcp` for the wire format, the 15-tool catalog, and the
See `rivet docs mcp` for the wire format, the 16-tool catalog, and the
3-message handshake.

## Oracle Subcommands (`rivet check`)
Expand All @@ -589,9 +605,11 @@

```
rivet schema list List all artifact types
rivet schema presets List declarable built-in schema presets (no project needed)
rivet schema show TYPE Show type details with example YAML
rivet schema links List all link types with inverses
rivet schema rules List all traceability rules
rivet schema sources Show where each active schema resolves (on-disk vs embedded)
rivet schema migrate TGT Plan + apply preset migration with snapshot
(see rivet docs schema-migrate)
```
Expand Down Expand Up @@ -620,7 +638,14 @@
```

Available presets: `dev`, `aspice`, `stpa`, `stpa-ai`, `cybersecurity`,
`aadl`, `eu-ai-act`, `safety-case`.
`aadl`, `eu-ai-act`, `safety-case`, `do-178c`, `en-50128`, `iec-61508`,
`iec-62304`, `iso-pas-8800`, `sotif`. Run `rivet schema presets` for the live
list with versions and type counts.

Init also accepts `--vendor-schemas` to write the resolved built-in schemas
(plus auto-discovered bridges) on-disk into `schemas/`, pinning a project's
validation against rivet upgrades. The loader prefers on-disk schemas over the
embedded copies, so a vendored set is immune to release-to-release rule drift.

## Mutation Commands

Expand Down Expand Up @@ -2009,7 +2034,7 @@

```
$ rivet mcp --list-tools
rivet MCP server — 15 registered tools
rivet MCP server — 16 registered tools

rivet_add
Add a new artifact to the project via CST mutation. Call rivet_reload after.
Expand Down Expand Up @@ -2572,6 +2597,12 @@
source. Run `rivet validate` to detect drift; run `rivet check sources
--update` to refresh the stamps.

It is a `common` base field, so **any** artifact type can carry it without
tripping `unknown-field` — including verification artifacts (`sw-req`,
`unit`, `sys-verification`), which is exactly where a tamper-evident citation
on the requirement→test→evidence chain is wanted. The drift checker discovers
the field by name, so it runs on those types too.

Phase 1 (current) implements the `kind: file` backend only. Remote kinds
(`url`, `github`, `oslc`, `reqif`, `polarion`) are recognised by the
schema and round-trip cleanly, but their backends ship in Phase 2.
Expand Down
Loading