Theme: post-0.7.0 dogfood-driven follow-ups. The 12-persona dogfood against 0.7.0 surfaced docs-corpus drift, coverage-gate flaws, and CLI asymmetries on cited-source + schema-migrate. All three are fixed here.
-
Stale literals shipped in 0.7.0 docs (#252, closes #247). Tech-writer + DevOps personas independently flagged four embedded- doc literals: quickstart Step 1's
rivet 0.5.0example,rivet docs mcp's hardcodedserverInfo.version: "0.5.0",rivet docs schema/eu-ai-act's wrongrivet init --schema Xflag, and a shipped(TODO)marker inrivet docs schema/dev. Plus 2 bonus drift items the agent caught:v0.5.0example tag in theimpacttopic, andrivet export --gherkin(the actual flag is--format gherkin).All six fixed. To prevent the class of drift from re-shipping,
rivet docs checklearned three new invariants that scan the embedded docs strings (the thingsrivet docs <topic>prints):EmbeddedVersionLiteralsflags anyvX.Y.Z/X.Y.Ztoken that doesn't match the workspace version unless it's inrivet.yaml's newdocs-check.allowed-version-literalsallowlist (used for legitimate non-rivet versions like ASPICE process IDs and the rmcp crate pin).EmbeddedFlagReferencesflags everyrivet <subcmd> --<flag>token in topic bodies whose flag isn't declared on that subcommand in the live clap tree.EmbeddedTodoMarkersflagsTODO/FIXME/XXXmarkers in shipped doc bodies.
Also adds a new
rivet docs docs-checktopic explaining the full invariant set (markdown-side + embedded-doc-side).
-
rivet docs check --coverage --warn-onlymode + tightened rule (#250, closes #248). The 0.7.0--coveragegate markedbatch,query,stamp,lspas covered via parent-mapping even though the parent topic body never mentioned them. Rule 4 (umbrella mapping) now requires the child subcommand's name to appear in the parent topic's body (whole-word, case-insensitive). Result:lspandbatchare now correctly reported as gaps.The default
--coverage(no flag) is now silent-print exit 0,--coverage --warn-onlyprints + emits::warning::GitHub annotations,--coverage --strictexits 1 on any uncovered.--warn-onlyand--strictare mutually exclusive. CI uses--warn-onlyexplicitly so the contract is legible at the call site. -
rivet check sources --strict— read-only audit mode for cited-source drift (#251, closes #249 part 1). Walks every artifact, reports per-artifact verdict (match / drift / missing-hash / stale), exits 1 on any non-match. Read-only — does NOT modify any YAML, even on drift detection. Mutually exclusive with--update. Replaces the "run--update --applythengit diff --exit-code" mutation-and-audit pattern with a clean read-only gate. -
rivet validate --strict-cited-source-stale— promotescited-source-staleInfo diagnostics to Error (#251, closes #249 part 2). Defaults off; current behavior preserved. Enables audit gates that enforce "every cited-source must be re-checked within 30 days."cited-source-stalenow fires for missing, unparseable, OR older-than-30-dayslast-checked(was: only missing). -
rivet schema migrate --list— recipe discovery (#251, closes #249 part 3). Without<target>, prints all available recipes (built-in + project-local underschemas/migrations/) as a text table, or JSON with--format json. Project-local recipes shadow built-ins of the same name. Mutually exclusive with<target>and the action flags.
- Workspace, vscode-rivet, and npm root package versions bumped to 0.8.0. Platform packages stay on the release-npm.yml override path.
- cargo check, cargo clippy --workspace -- -D warnings, cargo fmt --all clean.
- cargo test workspace passes (912 unit tests + integration tests).
rivet docs checkclean against the rivet repo.rivet docs check --coveragereports 46/81 covered (was 48/81; rule 4 tightening correctly surfaceslsp+batchas gaps).rivet check sources --strictround-trips: clean fixture exits 0; off-disk source edit exits 1 with no YAML mutation;--update --applyrestores 0.rivet schema migrate --listenumerates the canneddev-to-aspicerecipe.
Theme: schema migration Phase 2 + docs coverage gate + housekeeping.
The migrate state machine is now the full git-rebase analogue —
conflict markers, --continue, --skip, --edit — and the embedded
docs corpus has a mechanical coverage check to prevent future drift.
Plus four hygiene PRs that had been sitting in the backlog.
-
rivet schema migratePhase 2 — git-rebase-style conflict resolution UX (#242). When--applyhits a conflict, merge-conflict- style markers (<<<<<<</=======/>>>>>>>) are spliced into the affected artifact YAML and the migration pauses. Three new subcommands resolve from there:--continue— verify markers are gone, re-validate the touched artifact, advance to the next conflict or COMPLETE.--skip— drop the current artifact from the migration; restore its pre-migration form from the snapshot, advance.--edit <id>— re-stamp markers on a previously-resolved conflict for re-editing.
New
MigrationState::Conflictstate,current-conflictpointer file wired in,manifest.yamlextended with per-artifactresolutions: pending|resolved|skipped. The diff engine now also emitsFieldValueConflictwhen a source value violates the target field'sallowed-valuesenum (the canonical conflict shape). -
MigrationConflictinvariant inrivet docs check— scansartifacts/**/*.yamlfor unresolved conflict markers. Catches accidental commits with markers still in the YAML; the gate is always-on so a half-resolved migration can't slip into git. -
rivet docs check --coveragesubcommand-coverage gate (#241). Walks the live clap CLI tree, builds every subcommand path (top-level + nested actions), and cross-references each against the embeddedrivet docstopic registry. Default is warn-only;--strictmakes uncovered paths fail the build. JSON output for CI consumption. Wired into thedocs-checkCI job (warn-only initially; flip to--strictonce the documented gaps are filled). Initial inventory: 48/81 paths covered (59%); 33 uncovered across 7 families (variant, baseline, snapshot, runs, pipelines, templates, close-gaps).
-
feat(validate): warn when prose names an artifact id without a typed link (#234, closes #207).rivet validatenow scans every artifact'sdescriptionand string-typed fields for tokens matching\b[A-Z][A-Z0-9]*-[0-9]+\b. When such a mention resolves to an existing artifact and there's no typed link to it,prose-mention-without-typed-linkwarns. Suppressed for self-refs and unresolved IDs; deduplicated per artifact-pair. -
feat(schemas): vv-coverage repo-status type for V&V technique tracking (#232, partial #188). Newvv-coverageschema with therepo-statusartifact type, designed as the source-of-truth shape for the plannedrivet coverage --matrixrendering surface and cross-repo aggregation. -
feat(mutants): canonical cargo-mutants template + docs + schema fields (#229, closes #185). Reusablemutants.toml+ workflow YAML template undertemplates/cargo-mutants/, doc topic, and schema fields for tracking surviving mutants per test layer. -
docs(pre-commit): canonical 21-hook template + tier docs (#222, closes #186). Copy-pasteabletemplates/pre-commit/ .pre-commit-config.yamlanddocs/pre-commit.md.
- Release workflow now idempotent on existing tag (#244). The
Create Releasestep inrelease.ymlpreviously failed with "a release with the same tag name already exists" if the maintainer rangh release createmanually right after pushing the tag — which happened on every release in the v0.5.0 / v0.5.1 / v0.6.0 sequence. Net effect was that those release pages have no binary / VSIX / SHA256 assets attached. The step now detects an existing release and uploads assets viagh release upload --clobber, otherwise creates the release with assets. v0.7.0 ships clean assets out of the box; older releases need manual asset upload if desired.
- Workspace, vscode-rivet, and npm root package versions bumped to 0.7.0. Platform packages stay on the release-npm.yml override path.
- v0.5.0 / v0.5.1 / v0.6.0 release pages have no binary assets.
The Release workflow doesn't have
workflow_dispatch, so re-running on those tags isn't possible without a manualgh release upload. Tracked as a follow-up; v0.7.0 onward is unaffected.
Theme: schema migration + cited-source faithfulness. Two marquee features landing together — both surfaced during the post-0.5.0 fresh-user dogfood (#236, #237).
-
rivet schema migrate <target-preset>— git-rebase-style preset/ version migration with snapshot/abort. Phase 1 ships the diff engine- plan/apply/abort/status/finish. Three change classes (mechanical, decidable-with-policy, conflict). Mechanical-only auto-applied; conflicts bail loudly (Phase 2 will add merge-conflict-style markers
--continue/--skip). Storage layout under.rivet/migrations/ <ts>-<src>-to-<tgt>/with full pre-migration snapshot, manifest, state file. One canned recipe ships:schemas/migrations/dev-to-aspice.yamlcovering type renames (requirement->sw-req,feature->sw-arch-component), link-type renames (satisfies->derives-from), and policy declarations (unmapped-fields: keep-as-orphan). 8 unit tests- 5 integration tests covering apply, abort byte-symmetry, and
roundtrip.
rivet docs schema-migratedocuments the state machine and recipe format. (#238 / issue #236)
-
cited-sourcetyped schema field — first-class affordance for artifacts citing external sources. Field shape:{ uri, kind: file|url|github|oslc|reqif|polarion, sha256, last-checked }. Phase 1 ships thekind: filebackend:rivet validatere-reads cited files, recomputes sha256, emits a newcited-source-driftdiagnostic on mismatch (severity Warning by default, Error with--strict-cited-sources). URI scheme allowlist enforced at validation time to mitigate exfiltration / SSRF surface. Newrivet check sourcessubcommand walks every cited-source and surfaces drift;--updateinteractively refreshes hashes,--update --applybatch-updates. Thedevpreset'srequirementtype opts in first; other presets adopt incrementally via overlay.rivet docs schema-cited-sourcesdocuments per-kind backend behaviour, thelast-checkedsemantics, and the security model. (#239 / issue #237)Phase 2 backends (
url,github,oslc,reqif,polarion) are deferred. Phase 3 LLM-judge layer documented as opt-inSeverity::Infofuture work; not shipped here. The cited paper (arXiv 2604.19459) is explicitly not the motivation — it studies formal-proof faithfulness, not prose-to-prose comparison; RAG-grounding (FActScore, FaithEval) is the right literature for the LLM-judge path if/when it materializes.
- Workspace, vscode-rivet, and npm root package versions bumped to 0.6.0. Platform packages stay on the release-npm.yml override path.
- cargo check, cargo clippy --workspace -- -D warnings, cargo test -p rivet-cli (passes including new migrate + cited-source integration tests),
rivet schema migrate aspice(plan + apply on a freshdevproject) returns PASS,rivet validateon acited-source: { kind: file, ... }fixture catches drift after the underlying file changes,rivet check sources --update --applyrestores PASS state.
Theme: post-0.5.0 first-contact polish. Three fresh-user dogfood passes (plus three parallel scenario-based ones — safety engineer / STPA, compliance lead / Polarion-import, AI integrator / MCP) surfaced two real bugs and one big doc gap. All three are fixed here.
rivet init --preset aspiceseed now validates clean (#233). Two bugs in the shipped aspice preset: thecommonschema registersallocated-towithinverse: allocated-frombut never declaresallocated-fromas a forward token, so the seed'ssw-arch-component -> allocated-from -> sw-reqlink was rejected. And the seed'ssystem-reqhad noderives-fromtarget, so thesys2-derives-from-sys1rule failed on the firstrivet validatepost-init. Now:aspicedeclaresallocated-fromas a forward link-type, and the seed grows astakeholder-reqV-model root with thesystem-req -> derives-from -> stakeholder-reqlink wired up.rivet init --preset aspice && rivet validatenow returnsResult: PASS (0 warnings).
rivet mcp --list-toolsandrivet mcp --probe(#231). Two new flags for MCP discoverability — Scenario-C dogfood found that AI integrators wiring rivet's MCP server into a custom client burned ~30 minutes on JSON-RPC framing and writing throwaway requests just to enumerate the tool catalog.--list-toolswalks the registered tool router and prints the catalog (15 tools today). Default output is a human table;--format jsonemits the JSON-RPCtools/listpayload exactly as the wire server would. Does not start the server.--proberuns the in-process equivalent oftools/call rivet_list(no args) against the current project and prints the decodedresult.content[0].textpayload — same envelope a real MCP client would observe — without spinning up stdio.- Both reuse the same handlers the wire server dispatches to, so output cannot drift from a real session.
rivet docs mcpembedded topic (#231). New ~1400-word doc covering: line-delimited JSON-RPC framing (NOT LSP-style Content-Length), the 3-message handshake (initialize->notifications/initialized->tools/list/tools/call), the full 15-tool catalog with input-schema summaries, theresult.content[0].textenvelope gotcha (tool results arrive as a stringified JSON document, not a structured object), therivet_reload-after-mutation convention, and copy-pasteable smoke-test recipes.
- Quickstart rewrite for fresh-user clarity (#230). Two clean-room
dogfood passes plus three parallel scenario-based passes (safety
engineer / STPA, compliance / Polarion-import / ASPICE overlay,
AI integrator / MCP) surfaced six concrete issues that confuse a
real first-contact user, all fixed here. Highlights:
- New "What is rivet?" preamble (typed YAML + schema + graph + four interfaces; DOORS/Polarion/Jira analogy) so readers don't have to assemble the mental model by osmosis.
- Step 2 now branches on preset choice: for
dev, the seed is a placeholder (write your own in step 3); forstpa/aspice/etc., the seed is a worked example in domain vocabulary — read it, skip step 3, jump to step 4. - Step 3's
rm artifacts/requirements.yamlis gated todevonly so non-devseed files aren't accidentally nuked. - Step 7's Python oracle uses the actual JSON key (
errors, noterror_count); a real broken link now exits 1. - Step 9 replaces the Mythos red-team scaffold reference (out of
scope for first contact) with "add a living document" using
markdown frontmatter +
{{stats}}/{{coverage}}/[[REQ-001]]embeds + an explicitrivet serverestart oracle. - New "Existing-repo bring-up" appendix: explicit
rivet initnon-destructiveness contract, complete copy-pasteable ASPICEsw-reqoverlay (withpolarion_id/polarion_status/asiladditions and the requiredderived-fromlink-field with target-types verbatim fromrivet schema show), and thesw-req -> system-req -> stakeholder-reqstub-parent chain explained. - New "Common gotchas" appendix G.1 - G.7: LSP overlay blindness,
overlay merge field-drop, forward/inverse link-type direction,
doc vs artifact refs,
imported-stubhonesty, lifecycle severity scaling intent,rivet schema showpreset locality. - Wall-time wins (round 3 dogfood vs round 1): STPA bring-up went from 13 min to 36 sec; Polarion -> ASPICE overlay went from 7 min to 3.8 min.
Workspace, vscode-rivet, and npm root package versions bumped to 0.5.1. Platform packages stay on the release-npm.yml override path.
Verified: cargo check, cargo clippy --workspace -- -D warnings,
cargo test -p rivet-cli, rivet init --preset aspice && rivet validate
returns PASS, rivet docs mcp prints the new topic,
rivet mcp --list-tools produces a 15-tool catalog,
rivet mcp --probe returns artifacts.
Theme: oracle-gated agent pipelines + restored formal-method backstops +
mutation testing as a hard signal. The agent-first pillar (CLI + MCP +
LSP) now has a documented oracle-driven workflow (Mythos slop-hunt), an
external-coverage consumer (witness coverage), and a 16-shard mutation
matrix that surfaced and killed ~125 surviving mutants across the core
crate. Verus and Rocq verification jobs are fully restored, the
dashboard's variant scoping is coherent across all eight relevant
handlers, and rivet docs check no longer silently passes on
non-rivet markdown that drifted into a scanned directory.
- README rewrite +
rivet quickstart— new oracle-gated 10-step walk-through (rivet docs quickstartor therivet quickstartalias). Each step has a deterministic oracle command + expected output so an AI agent can follow the doc autonomously. README now leads with the three-pillar synthesis (typed atoms, oracle-gated agents, agent-first form factor) instead of a feature list. - Mythos slop-hunt agent pipeline —
scripts/mythos/{rank,discover,validate,emit}.mdHOWTO.md. Four-prompt audit adapted from Anthropic's red-team scaffold. Hunts dead code, duplicate parsers, and untraceable modules. Excision-primary / trace-interpretive oracle. (#205)
- Agent-pipelines schema block —
agent-pipelines:per-schema declaration of which oracles apply, how to rank gaps, and what closure routing applies. Surfaced throughrivet pipelines list/rivet pipelines show/rivet close-gaps. (#205) - CoverageStore — typed witness-coverage consumer for external
coverage-evidence files. Lets
rivet validateandrivet coverageingest tarpaulin/llvm-cov-style evidence as first-class artifacts with module digests, run metadata, and per-module summaries. (#208) - Variant scoping for 8 dashboard handlers —
?variant=<name>query parameter is now honoured uniformly across/artifacts,/coverage,/stpa,/matrix,/stats,/graph,/source, and/diagnostics. Closes the incoherence flagged in the PR #215 audit. (#223) - Docs warn-or-allowlist —
rivet docs checknow surfaces non-rivet markdown files that drifted into a scanned directory underrivet.yaml: docs:. Default iswarn;rivet.yaml: docs-check.allowlistflips specific paths back to silent. Resolves Task #56 — files like vendor docs no longer break the gate but no longer hide either. (#224) - 10 new Playwright rendering-invariant tests — coverage of the
full route surface, with explicit
.svg-viewerwrap pins, mermaid inline-render assertions, and graph-route timeouts validated. (#215)
- Mutation testing — 16-shard
rivet-corematrix, 30 s timeout — CI now shards the rivet-core mutation run across 16 jobs with a 30 s per-mutant timeout (down from 90 s). The shard reduction surfaced ~125 previously-untested mutants; PR #218 + #221 added ~64 new tests to kill them acrossembed,reqif,validate,commits,coverage_evidence,compliance,convergence,links, andstore. Net effect: mutation run is faster and the kill rate is higher. (#218, #221) - Verus verification fully restored — corrected
vstdlemma paths after upstream rename, replacedmatches!macros withisoperators, fixedlemma_div_multiples_vanishinvocation, added#[trigger]annotations to backlink-symmetry / reachable-in quantifiers, eliminated mid-quantifier in multi-step reachable case, cast nat→int inlemma_div_is_ordered. 15 specs proven. (#212) - Rocq proofs fully restored — restored
Validation.vimport, replaced everyAdmitted.with a real proof. Schema and validation semantics now machine-checked end-to-end. (#210)
- Serve middleware preserves response status —
wrap_full_pagewas unconditionally rewriting downstream 4xx/5xx responses to 200. Status is now preserved through the full-page wrapper so/artifacts/UNKNOWN-999correctly returns HTTP 404, etc. (#213) - Dashboard
/embed/*route mounting — moved underRouter::nestso the embed routes inherit the same middleware stack as the rest of the dashboard (auth, layout-wrap exclusion, CSP). (#218)
- Playwright suite green (384 passed) — closed the remaining 8 dashboard test failures (description-mermaid wrap, graph-render timeout, source-browser cross-reference, doc-linkage reverse index, variant-banner persistence). (#211, #213, #215, #217, #220)
- Graph-route per-test timeout — bumped 30 s → 60 s for slow CI runners; the layout engine occasionally exceeded the old budget on the larger test fixture. (#214)
cargo fmtdrift in mutation-test additions cleaned up. (#219)- CI: Kani PR-smoke wiring, mutation shard config, Verus log upload. (#209)
- +10 Playwright rendering-invariant tests — pin the
.svg-viewerwrap, mermaid inline rendering, and graph-route timeouts. (#215) - +~64 rivet-core unit tests killing surviving mutants across
embed,reqif,validate,commits,coverage_evidence,compliance,convergence,links,store. (#218, #221) - CoverageStore unit + integration tests — round-trip + summary invariants on witness coverage. (#208)
- Workspace version bump to
0.5.0inCargo.toml. Therivet-cli,rivet-core, andetchcrates inherit viaversion.workspace = true. - VS Code extension
vscode-rivet/package.jsonbumped to0.5.0. - npm root package
@pulseengine/rivetbumped to0.5.0. Platform package versions are filled in by therelease-npm.ymlworkflow on tag.
- Variant tooling — six open product questions tracked in
.rivet/mythos/variant-matrix-design.md(matrix emission, t-wise sampling, attribute-schema scope, audit cardinality, CLI ergonomics, dashboard interplay). - Formal-method gaps — three documented gaps in Verus coverage (variant solver completeness, salsa incremental fixpoint, ReqIF round-trip). The larger gale-style differential-testing bar is a follow-up release item.
Three new subcommands complete the variant-scoped CLI surface
(REQ-046). Feature models can now carry typed attributes: per
feature, round-tripped through solve() and emitted into seven
different build systems — the same one variant YAML can configure
Cargo, CMake, Bazel, a C/C++ header, Make, shell env, or structured
JSON without divergent hand-written shims.
-
rivet variant features --format {json,env,cargo,cmake,cpp-header,bazel,make}emits every effective feature plus itsattributes:entries with long, namespaced identifiers (RIVET_FEATURE_*,RIVET_ATTR_*). Every format is loud on failure — a variant that violates a constraint exits non-zero with the violation list, never a partial emission. Non-scalar attribute values (lists/maps) only serialise through--format json; build-system formatters returnError::Schemarather than invent a silent flattening convention. -
rivet variant value FEATURE— shell-friendly single-feature probe with exit codes0(selected),1(unselected),2(unknown feature or variant fails to solve). Designed forif rivet variant value … ; then …. -
rivet variant attr FEATURE KEY— print one attribute value. Scalars print bare; list/map values print as JSON so shells can parse structurally. -
rivet variant explain [FEATURE]— dev/debug UX for "why did my variant pick/skip feature X?". Full audit mode prints every effective feature with its origin (selected/mandatory/implied by <X>/allowed), plus the unselected set and the full constraint list. Single-feature focus mode zooms on one feature and lists every constraint that mentions it.
Feature models gained an attributes: key per feature, parsed as
BTreeMap<String, serde_yaml::Value>. The shipped
examples/variant/feature-model.yaml now carries realistic metadata
(asil-numeric, compliance, locale) so the worked examples in
docs/getting-started.md run against the fixture and produce the
documented output.
Test coverage: 11 unit tests in rivet_core::variant_emit::tests for
per-format rendering, 15 integration tests in
rivet-cli/tests/variant_emit.rs for CLI end-to-end, exit-code
contract, loud-on-failure path, and the realistic-example smoke across
all seven formats.
-
(> (count <scope>) N)now lowers to a newCountCompareexpr variant that evaluates the count against the store once and compares to an integer threshold. Previously the audit documented(count …)as "meant for numeric comparisons" but no lowering existed — you could only use it as a standalone predicate. Every comparison operator (>,<,>=,<=,=,!=) now accepts a(count …)LHS with an integer RHS. -
(matches <field> "<regex>")validates the regex at lower time instead of silently returningfalseat runtime on malformed patterns. Closes the "mysterious empty result" footgun — typing(matches id "[")used to match nothing and cost debug time; now it produces a parse error with the compiler's message. Non-literal patterns (rare; from field interpolation) still use the runtime-lenient path. -
docs/getting-started.mdgains dedicated sections for count comparisons and regex validation, plus a note that dotted accessors likelinks.satisfies.targetare not supported — use the purpose-builtlinked-by/linked-from/linked-to/links-countpredicates.
rivet-delta.yml workflow now pre-renders the summary Mermaid diagram
to SVG and pushes it to an orphan rivet-delta-renders branch, so email
notifications and the GitHub mobile app show the diagram inline instead
of a <mermaid> text block that nothing except the web UI can render.
Classification-priority ordering in scripts/diff-to-markdown.mjs is
also fixed so multi-label changes (breaking + additive → breaking)
pick the most severe.
rivet stamp all --missing-provenancefilter now correctly checks the first-classprovenance:struct field (previously it looked for aprovenanceentry in genericfields:and was therefore a no-op).set_provenanceno longer aborts the whole batch on a single CST-invisible artifact; it warns and skips that one artifact and continues.
Follow-up to the v0.4.2 commitment recorded in DD-058. The full
restriction-lint family is now declared at warn in
[workspace.lints.clippy]; new call sites in any workspace crate that
trip one of these lints will surface in CI. The 5,204 pre-existing
violations across 95 files are grandfathered in via file-scope
#![allow(...)] annotations, each stamped with a SAFETY-REVIEW
rationale tying back to DD-058. See artifacts/v043-artifacts.yaml
(DD-059) for the per-lint disposition and follow-on plan.
Lints now declared workspace-wide (all at warn with per-site opt-in
allow blocks):
unwrap_used,expect_usedindexing_slicing,arithmetic_side_effectsas_conversions,cast_possible_truncation,cast_sign_losswildcard_enum_match_arm,match_wildcard_for_single_variantspanic,todo,unimplemented,dbg_macroprint_stdout,print_stderr
cargo clippy --all-targets --workspace -- -D warnings exits 0.
cargo test --workspace stays green (all 36 test binaries pass).
rivet docs check stays PASS.
Phase 2 (tracked as DD-060) will walk the grandfathered file-scope
allows and either rewrite them to non-lint form or replace them with
per-site #[allow(...)] annotations carrying inline rationales.
This release closes 18 silent-accept findings discovered through dogfooding plus a customer bug-hunt pass. Theme: every place where invalid input used to silently succeed now surfaces a typed error or warning. Most are tiny behavioural changes; the cumulative effect is a much louder pipeline.
- Required-link cardinality silently passed on flow-style YAML —
links: [{type: X, target: Y}]parsed without error but the cardinality counter saw zero, so a "required" link could be entirely absent andrivet validatestill returned PASS. Same hole for the named-field formtargets: [SEC-AS-001]derived from a schema'slink-fields[].name. Both shapes now produce identicalVec<Link>and the cardinality counter sees them. (issue #3) - Schema link-fields referencing undeclared link types were emitted as
Warningfromrivet validate(overall result still PASS) and silently tolerated at schema load. NowErrorwith one diagnostic per(artifact, link-type)pair, plus a newSchema::validate_consistency()for fail-fast load-time checks. (issue #1) {{group:TYPE:FIELD}}two-arg form discarded the second arg, treating the type name as the field — every artifact bucketed into"unset".{{query (...) :limit 10}}colon-prefixed options were silently dropped because the parser only recognisedkey=value. Now rejected with a hint pointing to the correct syntax. Newfields=id,title,asiloption customises columns.{{coverage:typo-rule}} / {{matrix:UnknownType:Y}} / {{diagnostics:warnings}}all rendered blank or all-results when given typo'd arguments. Each now errors with a list of valid values.- Standalone
{{artifact|links|table:…}}on its own line wrapped in<p>producing invalid HTML nesting. Block-level embeds now emit directly. #[serde(deny_unknown_fields)]added to every schema-author struct (SchemaFile,SchemaMetadata,ArtifactTypeDef,FieldDef,LinkFieldDef,LinkTypeDef,TraceabilityRule,ConditionalRule,MistakeGuide,AlternateBacklink) plus the artifact-levelLinkandProvenancestructs. Typo'd YAML keys now error at load time instead of being silently dropped. NewLinkFieldDef.descriptionandTraceabilityRule.alternate_backlinksto surface fields the bundled schemas were already using.- YAML CST parser now handles inline
# commentson mapping lines — the LSP previously emittedexpected mapping key, found Some(Comment)on every CI workflow file. (issue #6b) rivet docs checknow honorsrivet.yamldocs:paths instead of only scanning the top-leveldocs/directory; projects withcrates/*/docsorrivet/docslayouts no longer get silently skipped.
- LSP resolves workspace schemas — was reading from the launching
process's CWD. User-extended schema files referenced via
rivet.yaml: schemas:now load correctly. (issue #6a)
- Artifact detail page lists the documents that
[[ID]]-reference it (reverse index — closes the loop on the existing forward/doc-linkageview). - Mermaid + AADL diagrams on artifact detail and
schema/showpages now wrap in.svg-viewerso they get the same zoom / fullscreen / popout toolbar as graph and doc-linkage views. Parity test indiagram-viewer.spec.tspins the invariant. - Document headings carry stable
id="…"slugs so in-page TOC links and#anchorURLs navigate. (B1) - Variants in the dashboard are now documented in
getting-started.mdandwhat-is-rivet.md. The auto-discovery convention, sidebar entry, header dropdown and/variantsoverview are spelled out.
- External-namespace exemption for
ArtifactIdValidity. Three layers to escape the[A-Z]+-NNN-pattern check when the prose legitimately references external IDs (Jira, Polarion, hazard catalogs):rivet.yaml: docs-check.external-namespaces: [GNV, GNR, HZO, UC]rivet.yaml: docs-check.ignore-patterns: [<regex>]- HTML-comment directives:
<!-- rivet-docs-check: ignore GNV-396 -->or<!-- rivet-docs-check: ignore-line -->.
- AGENTS.md template now ships an
ignore SC-1 REQ-001 FEAT-042directive so a freshrivet init && rivet docs checkdoesn't fail on its own example IDs. (issue #2) AUDIT:marker syntax documented for theArtifactCountsinvariant.conditional-rules:worked example ingetting-started.md.<!-- BEGIN/END rivet-managed -->contract documented forrivet init --agents. Content outside the markers is preserved across regeneration.
rivet stampbatch flags:--type PATTERN(glob or exact type),--changed-since REF(git-aware),--missing-provenance. No morexargsloops to stamp a batch of artifacts. (issue #4)rivet init --agents --force-regennow requires--yesto confirm the destructive overwrite. The flag was previously one accidental trigger away from destroying a hand-written AGENTS.md.rivet embed artifact:X / links:X / table:T:Ferror message now explains why the embed only renders inside markdown documents instead of the cryptic "handled inline" string.
The next planned release will start a workspace-wide clippy lint
escalation aligned with the Safety-Critical Rust Consortium guidelines:
unwrap_used, expect_used, indexing_slicing,
wildcard_enum_match_arm, as_conversions, arithmetic_side_effects,
and print_stdout / print_stderr outside the CLI binary. Each lint
will be enabled at warn first with per-site allow annotations
carrying a // SAFETY-REVIEW: rationale, then escalated to deny once
the backlog is drained. A later release will raise the rivet-core
coverage gate from 40% → 70% and flip mutation testing to a hard gate.
The eight commits in this release already implement the SCRC pattern "no silent acceptance of malformed input" empirically — the lint escalation makes the same discipline mechanical.
rivet variant checksilently passed on cross-tree constraint violations —(implies X (not Y))with both selected returnedOkbecause the solver only propagated bare-feature consequents and never evaluated compound expressions. Added a genericeval_constraintpass after propagation with proper propositional semantics (#156)rivet validate(salsa default mode) silently dropped AADL + external artifacts — non-YAML adapter sources (aadl/reqif/needs-json/wasm) fell through alog::debug!inrun_salsa_validation, so every link into them was a phantom broken-link. Users had to pass--directto get correct results. NewExtraArtifactSetsalsa input +_with_extrasquery variants; default and--directmodes now produce identical diagnostic counts (#157)
yaml_hir.rs: null/~/empty shorthand-link values no longer emit phantomLink { target: "null" }(#168)formats/generic.rs:GenericFilenow rejects unknown top-level keys (artifact:typo → error instead of silentOk(vec![])) (#168)coverage.rs: self-satisfying links (DD-001 → DD-001) no longer inflate coverage (#168)validate.rs+coverage.rs: emptyfrom_types/target_typesonTraceabilityRuleunified to "match any" semantics — was contradictory between the two reports (#168)
- Provenance (
created-by,model,timestamp,reviewed-by,reviewed-timestamp) now round-trips viarivet:*string attributes — was unconditionally dropped (#175) - Non-string
fieldsvalues encoded typed (bool/number/list/mapping) — wasformat!("{:?}", …)garbage (#175) - Tags serialized as JSON array with comma/whitespace safety (#175)
- CREATION-TIME header stamped with ISO 8601 UTC — was hardcoded empty (#175)
DATATYPE-DEFINITION-ENUMERATIONemitted when schema declaresallowed-values:(opt-in viaReqIfAdapter::with_schema) (#175)- Dangling
SPEC-RELATIONtargets rejected withError::Adapter— was silent phantom-link creation (#175)
rivet variant init <name>— scaffoldsfeature-model.yaml+bindings.yamlwith commented starter config (#174)rivet variant check-all --model M --binding B— iterates every declared binding; exits 0 iff all pass (#174)rivet validate --fail-on <error|warning|info>— configurable exit-code gate (#177)rivet coverage --fail-under N— CI gate on overall coverage (#177)rivet query --sexpr "..."— CLI mirror of MCPrivet_query(#180)rivet docs embeds— lists every registered embed token with signature + example (#180)rivet docs check— 8-invariant doc-vs-reality release gate (required CI + release job) (#178)rivet schema list-json/get-json— JSON schemas for CLI outputs (validate-output,stats-output,coverage-output,list-output) (#177)- Serve dashboard: variant selector +
/variantsoverview + per-route filtering —?variant=<name>on/artifacts,/coverage,/stpa,/matrix,/stats. Banner when filter active. (#179) - Embeds:
{{query:(sexpr)}},{{stats:type:NAME}},{{group:FIELD}}(#180) - Mermaid renders inline in artifact descriptions (pulldown-cmark event-mapper) (#180)
- Managed-section markers for
rivet init --agents— AGENTS.md/CLAUDE.md regen preserves content between<!-- BEGIN rivet-managed -->markers;--migrateand--force-regenflags for existing files (#167)
- npm:
@pulseengine/rivetwith per-platformoptionalDependencies(linux x64/arm64, darwin x64/arm64, win32 x64). Publishes on tag withNPM_TOKEN. Enablesnpx @pulseengine/rivet mcpfor Claude Code MCP integration (#166) - VS Code extension: VSIX now attached to every GitHub Release; Marketplace publish wired correctly (previous
release-resultsdependency pointed at a non-existent job in a different workflow — that's why the extension never shipped to Marketplace before) (#163)
- Pre-commit hook: marker discovery (walks up for
rivet.yaml) — survivesrivet.yamlrelocation (#174) FilterErrormessages: semantic notes ("expected s-expression form:(implies A B); got infix") on common user-error shapes (#174)rivet variant solveoutput: distinguishesUserSelected/Mandatory/ImpliedBy(name)/Allowedorigins (#174)- Search URL persistence: Cmd+K overlay now pushes
?cmdk=<q>viahistory.replaceState, reload preserves (#159)
docs/what-is-rivet.md— positioning doc in the v0.1.0 blog cadence (Problem → Answer → Evidence per use-case). README intro rewritten (#172)docs/design/doc-reality-audit.md— one-time register of 28 doc-vs-reality mismatches (#171)docs/design/ai-evidence-trend-research.md— competitive landscape; top-3 parallels (pharaoh, Continue.dev, SpecStory); EU AI Act / ISO/IEC 42001 / safety-standards update drivers (#173)docs/design/ai-safety-cyber-hitl.md— "AI proposes, qualified human owns judgment" frame + 4-point HITL contract + FAQ (#176)docs/design/iso26262-artifact-mapping.md— gap register (32.5% EXACT / 42.5% APPROX / 25% ABSENT) (#164)docs/design/polarion-reqif-fidelity.md— field-by-field fidelity for Polarion REST vs ReqIF paths (#169)docs/design/sexpr-artifact-format.md— Option-A-through-D cost analysis for s-expr as second format (#162)docs/design/cli-gaps-2026-04.md— 5 missing CLI features + ranked backlog (#161)docs/design/release-channels.md— npm/brew/cargo/docker/Marketplace distribution plan (#166)docs/feature-model-schema.md+docs/feature-model-bindings.md— feature-model YAML reference (#174)
- YAML footgun fuzzer: 3 libfuzzer targets +
oracle_smokeharness. 5 empirical silent-accept bugs found on the v0.4.0 corpus before fixes landed (#160) - Docs-check gate now required on every PR + release tag (#178)
rustls-webpki 0.103.12(RUSTSEC-2026-0098 / 2026-0099);thin_vecUAF (RUSTSEC-2026-0103) ignored via deny.toml (transitive viasalsa 0.26.0, no direct use)
- Verification pyramid — STPA-Sec test suite (16 tests), differential YAML parsing (rowan vs serde_yaml), operation-sequence property tests, Kani BMC expanded from 15 to 27 harnesses covering the core public API, Verus/Rocq jobs wired into CI via Bazel (#150)
- Variant / Product-Line Engineering — feature-model schema, constraint solver,
rivet variant check/list/solve, s-expression query language with forall/exists quantifiers and reachable graph traversal - Zola static-site export — multi-project filtered export with
--prefixnamespacing, wiki-link resolution, JSON data files, TOML escaping - Sphinx-needs JSON import adapter — migration path from sphinx-needs projects
- LSP code actions — quick-fix for missing-link diagnostics
- MCP CRUD + integration tests — query, modify, link, unlink, remove
- AI-in-the-loop STPA + security analysis
rivet validate --variant— variant-scoped validation- EU AI Act runtime evidence
- STPA extraction — suffix-based UCA discovery (e.g.
*-ucassections) and nestedcontrol-actionsinside controllers; previously 0 control-action artifacts on real STPA projects, now extracted correctly (#150) rivet-coreunwrap hardening — 12 productionunwrap()sites replaced with safelet Some(_) = _ elsepatterns in validate, matrix, diff, mutate- Zola export — TOML escaping, title fallback, date handling, mermaid block rendering
- Playwright regressions — coverage-view strict-mode violation, control-action title assumptions,
/graphtimeout handling (#151) - Deps — rustls-webpki 0.103.12 (patches RUSTSEC-2026-0098 / -0099) (#151)
- Clippy — junit.rs
collapsible-matchfrom Rust 1.95 (#151) - Tool qualification — STPA, requirements, MCP audit, regex bounds,
export --clean, import verification
- 27 Kani BMC harnesses — up from 15, covering commit parsing, artifact IDs/ranges, trailer parsing, store upsert, diff, validation guards, markdown render, HTML strip
- Differential YAML parser tests — 6 tests comparing the rowan parser against serde_yaml for equivalence
- Proptest operation sequences — 3 tests fuzzing random insert/upsert/validate sequences against store invariants
- Dual-crate mutation testing — rivet-cli now covered alongside rivet-core, 40-minute CI timeout
- Kani job enabled — previously commented out
- Verus + Rocq jobs — added via Bazel (marked
continue-on-error: truepending toolchain stabilization) - CLI mutation testing — added alongside core
- LSP server (
rivet lsp) — language server with diagnostics, hover, go-to-definition, and completion for artifact YAML files; re-validates on file save (#58, #60, #61) - Baseline-scoped validation —
--baseline v0.1.0flag on validate, list, stats, coverage, export scopes to named artifact sets (#58) - STPA-Sec security analysis — 31 adversarial threat artifacts (5 losses, 6 hazards, 6 constraints, 7 UCAs, 7 scenarios) with dashboard section (#45)
- Eclipse SCORE schema — 40+ artifact types mapping the SCORE metamodel for safety-critical automotive/embedded development (#61)
- Self-contained binary — HTMX, Mermaid, and Google Fonts bundled via
include_str!; no CDN dependencies (#45) - Dashboard filter/sort/pagination —
?types=,?q=,?sort=,?dir=,?per_page=,?page=on/artifactsand/stpa(#52) - AADL compound graph layout — nested
aadl-componentcontainers rendered via Etch compound layout engine (#45) - HTML export: STPA + graph pages — static STPA hierarchy and SVG traceability graph in export output (#45)
- Document-to-document references —
[[DOC-ID]]in document bodies resolves to.doc-reflinks (#45) rivet init --agents— generates project-aware AGENTS.md (universal AI agent instruction standard, 25+ tools) (#59)rivet batch— atomic multi-mutation files for bulk artifact operations (#43)rivet add --link— add links inline when creating artifacts (#42)--format jsonon validate and coverage — machine-readable output for all query commands (#43)- Cross-repo fixes —
rivet linkwith externals,--skip-external-validation,rivet sync --local(#45) - Reusable UI components — ViewParams, FilterBar, Pagination, SortableTable extracted to
components.rs(#56) - Startup update check — non-blocking background thread checks GitHub releases once per 24h (#56)
- 8 new ARCH components — phase-3 requirements now have architecture allocation (#56)
- WASM stubs in build.rs —
--features embed-wasmremoved; build.rs generates stubs automatically (#50) - Etch rendering — port-aware layout, orthogonal routing, interactive HTML, SVG edge render order fixes (#37, #53, #55)
- Mermaid
securityLevel: strict— prevents XSS via crafted Mermaid diagrams (#61) - SSC-3: localhost default — dashboard binds to 127.0.0.1 by default, warns on 0.0.0.0 (#52)
- SSC-6: YAML document-size limit — 10 MB limit in generic and STPA adapters prevents DoS (#52)
- CSP
font-src data:— allows base64-embedded fonts without CSP violations (#47) - HTML escaping — wiki-link IDs, source file refs, results view fields all properly escaped (#61)
- WASM graceful fallback — HEAD probe, no console error spam when spar WASM unavailable (#48, #49)
- 7.8x store insert speedup — O(n²)
contains()→ O(1) direct insert (#58) - Regex pre-compilation — conditional validation rules compile regex once, not per-artifact (#58)
- Zero-copy field reads —
Cow<str>forget_field_valueeliminates unnecessary clones (#58) - Cached diagnostics —
page_layout()uses cached results instead of recomputing per page view (#61)
- 235+ Playwright E2E tests across 22 spec files covering all routes (#45, #51, #54, #62)
- Playwright CI job — runs after unit tests, builds release binary, installs Chromium (#45)
- Audit regression tests — 17 tests for security, performance, edge cases, consistency (#62)
- Mutation testing — 0 missed mutants in rivet-core (#63)
- Coverage fixes — 27 new tests for store, schema, model patch coverage (#60)
- 324
// rivet: verifiesmarkers across 22 source files for test scanner (#52)
- Navigation
href="#"eliminated — all 65 occurrences replaced with real paths (#46) /assets/*excluded from layout middleware — HTMX/Mermaid JS served correctly (#47)- Print button —
new URL()replaced with string concat, mermaid.js added to print layout (#51, #57) - UTF-8 string slicing —
&title[..26]→chars().take(26)prevents panic on multi-byte chars (#61) - Serve integration test timeout — 5s → 15s for slow CI runners (#45)
- 0 lifecycle coverage gaps — DD-036–039, FEAT-064–065, TEST-011–015 close all holes
- 3 structural gaps closed — REQ-003 → FEAT-016, REQ-009 → FEAT-014, REQ-022 → DD-039
- 447 artifacts, validate PASS, 0 warnings
- 7 stale branches deleted — clean branch list (main, gh-pages only)
- Pre-commit config — large asset exclusion for mermaid.min.js and fonts.css
Initial release. See git history for details.