From e50ef22e328defe2838639df3c69a0c6c55677c5 Mon Sep 17 00:00:00 2001 From: Ralf Anton Beier Date: Thu, 25 Jun 2026 05:22:47 +0200 Subject: [PATCH] docs: sync documentation with current implementation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bring the prose docs in line with what the v0.18–v0.19 binary actually does. New capabilities were undocumented and several listings had drifted. New things documented: - `rivet sql` — a dedicated "SQL over the artifact store" section in docs/getting-started.md (table schema artifacts/links/fields/provenance, SELECT/WITH reads incl. the V-closure query, and the constrained `UPDATE artifacts SET status/title/description` write slice). Stresses it works with no server and no MCP. Also added to the embedded `rivet docs cli` topic under a new "Query Commands" block. - `rivet verify` — advance implemented -> verified on test evidence (incoming `verifies` link or `// rivet: verifies ` marker); added to getting-started CLI commands and the embedded cli topic. - `rivet coverage` combined V-closure metric (intersection of every applicable rule); documented in getting-started CLI commands. - `rivet query` CLI command; documented in getting-started CLI commands. - `cited-source` is now a `common` base field usable on any artifact type; noted in the embedded schema-cited-sources topic. - `rivet init --vendor-schemas` and `rivet schema presets` / `schema sources` added to the embedded cli topic; presets list extended to the full set. Wrong/old things fixed: - README 30-second demo used a broken `rivet add` invocation (`rivet add requirement -t "..." --asil B` — `requirement` is not a positional, `-t` is `--type`, and there is no `--asil` flag). Corrected to `rivet add -t requirement --title "..."`. - README prebuilt-binary curl URL pinned to v0.16.1 -> v0.19.0. - export formats listed as only reqif/generic-yaml -> reqif, generic-yaml, html, zola, gherkin (getting-started + embedded cli topic). - MCP tool count 15 -> 16 (added `rivet_bundle`) in what-is-rivet, getting-started, and the embedded cli/mcp topics. Confirmed each documented command and query against the built binary; `rivet docs check` PASS (0 violations) and `rivet validate` PASS. Refs: REQ-229, REQ-230 Co-Authored-By: Claude Opus 4.8 --- README.md | 4 +- docs/getting-started.md | 138 ++++++++++++++++++++++++++++++++++++++-- docs/what-is-rivet.md | 8 +-- rivet-cli/src/docs.rs | 41 ++++++++++-- 4 files changed, 175 insertions(+), 16 deletions(-) diff --git a/README.md b/README.md index c066f5f8..70947032 100644 --- a/README.md +++ b/README.md @@ -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-) -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 @@ -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 diff --git a/docs/getting-started.md b/docs/getting-started.md index 40ed1e88..3ba9a3c4 100644 --- a/docs/getting-started.md +++ b/docs/getting-started.md @@ -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 ` +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. @@ -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` @@ -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. @@ -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`. diff --git a/docs/what-is-rivet.md b/docs/what-is-rivet.md index ced52270..9883b417 100644 --- a/docs/what-is-rivet.md +++ b/docs/what-is-rivet.md @@ -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. diff --git a/rivet-cli/src/docs.rs b/rivet-cli/src/docs.rs index fe7c1f82..856757a3 100644 --- a/rivet-cli/src/docs.rs +++ b/rivet-cli/src/docs.rs @@ -535,16 +535,32 @@ rivet validate Validate all artifacts against schemas 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 ``` @@ -566,7 +582,7 @@ rivet mcp --probe Run an in-process tools/call rivet_list smoke 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`) @@ -589,9 +605,11 @@ Phase 2. See `rivet docs schema-cited-sources`. ``` 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) ``` @@ -620,7 +638,14 @@ rivet context Generate .rivet/agent-context.md ``` 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 @@ -2009,7 +2034,7 @@ project. Just enumerates the tool catalog the server would advertise. ``` $ 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. @@ -2572,6 +2597,12 @@ stamps an artifact with a hash-verifiable reference to an external 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.