From b6e47fd95887fbc0af9f3548d2f2f18bb10fc160 Mon Sep 17 00:00:00 2001 From: Ralf Anton Beier Date: Sun, 24 May 2026 17:46:22 +0200 Subject: [PATCH 1/3] docs(roadmap): 10-persona review synthesis + REQ-093..099 (v0.14.0-track) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit File the 10-persona-review synthesis as the v0.14.0+ roadmap doc and the seven REQs that come out of it. The shape is universal-LIKE / universal-DISLIKE matrices, Carrasco's hybrid flip-conditions, and an end-to-end mapping from each persona finding to a falsifiable REQ. REQs filed (every Acceptance step is shell-testable): - REQ-093 — implement the three FUTURE oracles (asil-decomposition, coverage-threshold, method-table-compliance). Turn ISO 26262 narrative into mechanical checks. - REQ-094 — `rivet release-verify ` reproducible-build + cosign sigstore verification end-to-end. - REQ-095 — `cargo build` invokes `rivet validate` for crates with a `rivet.yaml` — born-compliant at the compile step (Carrasco named this as the biggest MBSE-philosophy win). - REQ-096 — SACM 2.x typed safety-case schema with deductive- sufficiency rules (compliance trace != safety case). - REQ-097 — DO-330 TQP/TOR/TVCP/TCI/TAS as a typed schema, dogfooded by rivet's own qualification dossier. - REQ-098 — independence-of-verification-layers oracle. Refuse product-of-miss-rates claims when shared-code intersection exceeds threshold. The common-mode-failure finding made mechanical. - REQ-099 — `rivet_apply` MCP tool with idempotency keys + atomic transactions + auto-reload + post-state diagnostics. Ports the F2 silent-failure ethos (REQ-082) to mutation. Deliberately NOT filed: a v1.0 readiness gate. Per direction, we see how far we can progress through the v0.14.0+ backlog without pre-committing to a 1.0 milestone; 1.0 ships when the natural state of the work meets Carrasco's flip-condition (b), not when a calendar says so. Implements: REQ-093, REQ-094, REQ-095, REQ-096, REQ-097, REQ-098, REQ-099 Refs: REQ-091, REQ-092 Co-Authored-By: Claude Opus 4.7 --- artifacts/requirements.yaml | 258 +++++++++++++++++++++++ docs/design/10-persona-review-roadmap.md | 224 ++++++++++++++++++++ 2 files changed, 482 insertions(+) create mode 100644 docs/design/10-persona-review-roadmap.md diff --git a/artifacts/requirements.yaml b/artifacts/requirements.yaml index b94b16b..774ee89 100644 --- a/artifacts/requirements.yaml +++ b/artifacts/requirements.yaml @@ -1837,3 +1837,261 @@ artifacts: links: - type: traces-to target: REQ-051 + + - id: REQ-093 + type: requirement + title: "Implement the FUTURE oracles — asil-decomposition, coverage-threshold, method-table-compliance — turn the ISO 26262 narrative into mechanical checks" + status: draft + description: | + The schema declares three oracles today (`asil-decomposition`, + `coverage-threshold`, `method-table-compliance`) but their + evaluators are FUTURE stubs — `rivet validate` parses the + pipeline declaration and never fires. 10-persona review row A1 + (Hess, ISO 26262 assessor): "your schema parses pipelines that + don't fire." Until they fire, the per-ASIL rigour rivet claims + is narrative, not mechanical. + + Acceptance: + - `asil-decomposition` oracle: ISO 26262-9 decomposition + rules implemented and exercised. Fixture: an ASIL-D parent + decomposed into two children must satisfy the allowed + pairs (ASIL-B + ASIL-B, ASIL-A + ASIL-C, …). Non-conforming + pair -> ERROR; conforming pair -> silent. + - `coverage-threshold` oracle: per-rule coverage % computed + against a declared minimum; below-threshold -> ERROR + naming (rule, observed, required). + - `method-table-compliance` oracle: ISO 26262 Part 6 + Tables 9 / 10 / 11 encoded; missing required method at the + declared ASIL -> ERROR. + - Each oracle has at least one passing fixture and one + failing fixture in `rivet-core/tests/`. + - `rivet docs schema/...` no longer renders these as FUTURE. + tags: [oracle, iso-26262, qualification, falsification, persona-review] + fields: + priority: must + category: functional + baseline: v0.14.0-track + links: + - type: derives-from + target: REQ-004 + + - id: REQ-094 + type: requirement + title: "Reproducible-build oracle + sigstore-signed release verification — `rivet release-verify`" + status: draft + description: | + A tool whose output IS compliance evidence needs verifiable + releases. v0.10.x added sigstore-keyless signing of + `SHA256SUMS` via cosign — the production side is done. The + missing leg is the consumer side: `rivet release-verify ` + rebuilds the release artifacts from a fresh checkout, hashes + the output, verifies the sigstore bundle against the GitHub + OIDC identity, and refuses if any step disagrees. 10-persona + row A4 — two of three rivet reviewers (Hess, Whittaker) flagged + release-channel integrity as the blocking gap. + + Acceptance: + - `rivet release-verify v0.13.0` rebuilds, hashes, fetches + the sigstore bundle, runs `cosign verify-blob` with the + documented identity regex, and exits 0 iff every hash + matches and the signature verifies against the workflow's + OIDC identity. + - Tampered `SHA256SUMS`, missing signature, wrong identity, + or non-reproducible build each fail loudly with the named + mismatch. + - A CI job runs `release-verify` on the most-recent tag + periodically and gates merge to `main` if it fails. + - Documented via `rivet docs release-verify`. + tags: [release, sigstore, supply-chain, qualification, persona-review] + fields: + priority: must + category: non-functional + baseline: v0.14.0-track + links: + - type: derives-from + target: REQ-068 + + - id: REQ-095 + type: requirement + title: "`cargo build` invokes `rivet validate` for crates declaring `rivet.yaml` — born-compliant at the compile step" + status: draft + description: | + Today `rivet validate` fires on commit (pre-commit hook + CI). + The MBSE-mandatory principle says the model drives the build, + not sits alongside it. Bringing validation INTO the build + closes the window between "edited an artifact" and "noticed + the artifact is broken": today that window is one commit; + tomorrow it is one `cargo build`. 10-persona row B1; Carrasco + named it as the biggest MBSE-philosophy win and the realisation + of the "born-compliant" framing. + + Acceptance: + - A `build.rs` in `rivet-cli` (or a `cargo` subcommand + wrapper) detects `rivet.yaml` and runs `rivet validate`. + - Non-zero validate -> the build fails. + - Opt-out env var (`RIVET_SKIP_VALIDATE_ON_BUILD=1`) for + bootstrap / circular cases; default ON. + - Build-time validation result is cached by content hash so + incremental builds stay fast. + - Integration test: a project with a deliberately broken + artifact YAML fails `cargo build` with the validate + diagnostic; fixing the artifact unblocks the build. + tags: [mbse, build, cargo, validate, persona-review] + fields: + priority: should + category: functional + baseline: v0.14.0-track + links: + - type: derives-from + target: REQ-004 + + - id: REQ-096 + type: requirement + title: "SACM 2.x typed safety-case schema with deductive-sufficiency mechanisation" + status: draft + description: | + Rivet ships a safety-case schema today but stops at *structural* + traceability — every workproduct has a chain of links — without + enforcing the *deductive sufficiency* obligations a safety case + claims. 10-persona row A2 (Dubois, safety researcher): + "compliance trace ≠ safety case." Promoting the schema to OMG + SACM 2.x's claim / argument / evidence shape + a mandatory + `supported_by` cardinality lets `rivet validate` enforce "every + hazard mitigated, every AoU discharged, every derived + requirement traced to its analysis origin." + + Acceptance: + - `schemas/sacm.yaml` declares `claim`, `argument`, + `evidence` artifact types with the SACM 2.x link + vocabulary (`supported_by`, `in_context_of`, + `decomposed_into`, …). + - Traceability rule: every ASIL-B+ workproduct is reachable + from a `root_claim`-typed claim via `supported_by`. + - Traceability rule: every `hazard` has a `mitigated_by` + path to at least one `safety_requirement`. + - Traceability rule: every `assumption_of_use` has a + matching `discharged_by` link in the consumer's project + (cross-repo via the REQ-085 mechanism). + - Worked example under `examples/safety-case/` carrying a + minimal but non-trivial SACM tree. + tags: [sacm, safety-case, assurance, schema, persona-review] + fields: + priority: should + category: functional + baseline: v0.15.0-track + links: + - type: derives-from + target: REQ-002 + + - id: REQ-097 + type: requirement + title: "DO-330 tool-qualification artifacts (TQP / TOR / TVCP / TCI / TAS) as a typed schema, dogfooded by rivet itself" + status: draft + description: | + 10-persona row A6 (Whittaker, DO-178C/DO-330 reviewer): "rivet's + TCL-2 narrative is honest, but there is no DO-330 *shape* — + TQP / TOR / TVCP / TCI / TAS are absent." A TCL-2 *tool* has + those artifacts in typed form; a TCL-2 *narrative* does not. + Filing them in `schemas/do-178c.yaml` and dogfooding the tool's + own qualification dossier under that schema turns the TQL claim + from "asserted" to "a falsifiable graph state." + + Acceptance: + - `schemas/do-178c.yaml` declares the five artifact types: + `tool_qualification_plan` (TQP), + `tool_operational_requirements` (TOR), + `tool_verification_cases_and_procedures` (TVCP), + `tool_configuration_index` (TCI), + `tool_accomplishment_summary` (TAS). + - Required link cardinalities encoded: + TQP -> TOR(+), TOR -> TVCP(+), TVCP -> TCI(1), + TAS -> TQP(1). + - `artifacts/qualification/` carries rivet's *own* TQP / + TOR / TVCP / TCI / TAS — dogfood demonstrates that the + tool's qualification artifacts validate cleanly under the + tool itself. + - `rivet docs do-178c` topic added with the layering + explanation. + tags: [do-178c, qualification, schema, dogfood, persona-review] + fields: + priority: should + category: functional + baseline: v0.14.0-track + links: + - type: derives-from + target: REQ-004 + + - id: REQ-098 + type: requirement + title: "Independence-of-verification-layers oracle — refuse `product-of-miss-rates` claims when layers share too much code" + status: draft + description: | + The single most-repeated complaint of the 10-persona panel + (row A3, Hess + Whittaker): Kani, Verus, Rocq, proptest, and + `rivet validate` all share the `Artifact` model and the YAML + parser. The "product of miss rates" argument that justifies + claiming "TCL-2 because we have N independent verification + layers" collapses if the shared parser has a bug — common-mode + failure. The oracle: rivet declares each verification layer's + Rust dep graph, walks the intersection, and refuses to claim + "independent layer" when shared-code count exceeds a + configurable threshold. + + Acceptance: + - `rivet validate --check-independence` reads a manifest of + declared verification layers (Kani / Verus / Rocq / + proptest / direct validate / salsa validate) and their + entry-point crates. + - Computes the transitive-dep intersection of any two + declared-as-independent layers. + - Emits ERROR if intersection exceeds the configured + threshold (default: 0 shared *parsing* code; small-N + shared *types* allowed and documented). + - The TCL dossier's independence claim links to the oracle's + last passing run as evidence. + tags: [independence, verification, qualification, oracle, persona-review] + fields: + priority: should + category: non-functional + baseline: v0.14.0-track + links: + - type: derives-from + target: REQ-051 + + - id: REQ-099 + type: requirement + title: "`rivet_apply` MCP tool — idempotency keys + atomic transactions + auto-reload + post-state diagnostics" + status: draft + description: | + 10-persona row A5 / C6 (Krishnamurthy, AI engineer): "MCP catalog + is small + typed + orthogonal — good. Mutation→reload is manual, + no batch, no idempotency = retry pain at scale." An agent fleet + replaying a failed batch today produces duplicates; an agent + without a reload tool sees stale state. `rivet_apply` is a + single mutator tool that takes a JSON-patch + idempotency key, + applies atomically, runs `rivet validate` on the post-state, and + returns both the diff and the diagnostics — so agents don't have + to coordinate three calls per mutation. + + Acceptance: + - `rivet_apply(patch, idempotency_key)` MCP tool: replay with + the same key is a verified no-op (returns the same response + shape as the first call). + - Atomic: failure rolls the artifact back; the YAML file is + either fully-changed or untouched. + - Auto-reload: the MCP server's cached state is invalidated + on apply. + - Response includes the post-apply `rivet validate` + diagnostics — agents see the consequence of the change + without a follow-up call. + - `rivet validate` gains an audit-log check that detects + idempotency-key violations across past applies (REQ-082 + F2 ethos extended to mutation). + tags: [mcp, agent, idempotency, mutation, persona-review] + fields: + priority: must + category: functional + baseline: v0.14.0-track + links: + - type: derives-from + target: FEAT-010 diff --git a/docs/design/10-persona-review-roadmap.md b/docs/design/10-persona-review-roadmap.md new file mode 100644 index 0000000..252307c --- /dev/null +++ b/docs/design/10-persona-review-roadmap.md @@ -0,0 +1,224 @@ +--- +id: DOC-DESIGN-10-PERSONA-ROADMAP +title: 10-persona review of rivet ↔ eclipse-score — roadmap synthesis +type: design-decision +status: current +tags: [design, roadmap, qualification, persona-review, eclipse-score] +--- + +# 10-persona review — roadmap synthesis + +A side-by-side review of rivet and `eclipse-score`, performed by ten +named personas during the sphinx-needs corpus conversion experiment +(2026-05-24). The eclipse-score-fork workspace is the concrete +deliverable the review hung on. This document captures the synthesis +that drives the v0.14.0+ roadmap. Falsifiable-claim items are filed +separately as `REQ-093` … `REQ-100`; this document is the *why*. + +## The ten personas + +| # | Persona | Verdict (one line) | +| --- | ------------------------------------------------ | ------------------ | +| P1 | Dr. Maria Hess — ISO 26262 assessor (eclipse) | Typed graph good; self-attested "valid", unqualified tool, FDR placeholders → findings | +| P2 | Hiroshi Tanaka — OEM architect (eclipse) | Honest metamodel; zero AUTOSAR/ARXML/DOORS = deal-breaker for OEM adoption | +| P3 | Kjell Andersen — CI/DevOps (eclipse) | Three-mode build mature; `-W --keep-going` wrong PR gate, `pull_request_target` + `contents:write` is a security hole | +| P4 | Priya Ramanan — 1st-week contributor (eclipse) | Devcontainer thoughtful; contribute info fragmented, metamodel narrative absent, persistency arch a stub | +| P5 | Prof. Dubois — safety researcher (eclipse) | Typed checkable graph closer to MBSA than DOORS; FDR row 2 "argument intentionally not provided" — compliance trace ≠ safety case | +| P6 | Dr. Maria Hess — same assessor (rivet) | Self-deprecating typed qualification claim earns trust; independence not proved (parsers shared), FUTURE oracles unimplemented, releases unsigned | +| P7 | Col. Whittaker — DO-178C/DO-330 (rivet) | Honest scope, traceability gated; no DO-330 TQP/TOR/TVCP/TCI/TAS — TQL-2 narrative, not TQL-2 tool | +| P8 | Aditi Krishnamurthy — AI engineer (rivet) | MCP catalog small + typed + orthogonal; mutation→reload manual, no batch/idempotency = retry pain at scale | +| P9 | Yusuf El-Masri — 1st-day Rust contributor (rivet) | Doc-comments work, tests real, lint policy principled; 17-lint `#![allow]` copy-paste, `Error` too coarse, 55 top-level modules sprawl | +| P10 | Elena Carrasco — CTO (side-by-side) | Eclipse = consortium brand; rivet = born-compliant + agent-first + falsification discipline. **Hybrid: eclipse as SoR, rivet as oracle layer. Bus factor: ONE.** | + +## Universally liked (cross-stack) + +1. **Typed metamodel as single inspectable source of truth.** Hess / + Tanaka / Dubois / Ramanan / El-Masri. Whether it's eclipse's + `metamodel.yaml` or rivet's `schemas/*.yaml`, ONE file that defines + types + links + rules is load-bearing trust. +2. **Honest scope statements that name what's NOT done.** Hess + explicitly contrasts: eclipse's tool qualification reads like vibes; + rivet's dossier opens with "self-claimed, one Admitted Rocq theorem, + 27 Kani harnesses not 2000" — and earns trust because it admits + gaps. People trust falsification over confidence. +3. **Graph-checking that catches structural mistakes mechanically.** + Hess / Dubois / Whittaker. `QM cannot satisfy ASIL` is a graph + predicate, not a review checklist. +4. **Reproducible build / git-native CM.** Andersen / Tanaka / + Whittaker. YAML/RST in git + deterministic pipeline > DOORS DB + + nightly export. + +## Universally disliked (cross-stack) + +The five recurring complaints — the actual product-improvement signal: + +1. **Tool qualification asserted, not assessed.** Eclipse: `doc_as_code` + is qualified by itself, no TI/TD analysis. Rivet: TCL1 self-claim, + AI-assisted authoring, no independent reviewer per + ISO 26262-2 §6.4.7. Both need external assessor signoff before any + OEM consumes the output as evidence. +2. **Independence of verification layers not proved.** Eclipse: + `graph_checks` share the parser. Rivet: Kani / Verus / Rocq / + proptest all share the `Artifact` model and YAML parser. The + "product of miss rates" argument collapses if the parser has a bug. + → [[REQ-098]] +3. **Release-channel integrity gap.** Eclipse: CI gate, no signed + attestation, no SBOM, no checker-version manifest. Rivet: + `SHA256SUMS` was unsigned until v0.10.x; git tags unsigned. A tool + whose output IS compliance evidence needs signed releases. + → [[REQ-094]] +4. **Cross-tool integration weak.** Eclipse: zero AUTOSAR/ARXML/AADL/ + ReqIF — deal-breaker for OEM adoption. Rivet: no DO-330 shape, + no DOORS bridge yet, MCP write tools out-of-qualification-scope. + → [[REQ-097]] (DO-330), follow-on for OEM bridges. +5. **Bus factor / maintainer base.** Eclipse: Eclipse WG but the + variant attempt was one person and got archived. Rivet: ~372 of 373 + commits are one author. **The single most decisive finding in the + panel.** + +## Rivet-specific friction (the agent-finishable items) + +| Friction | Persona | Severity for | +| ----------------------------------------------------------------------------------------- | ------------- | ----------------------------- | +| Three FUTURE oracles (asil-decomposition / coverage-threshold / method-table-compliance) | Hess | ISO 26262 assessors | +| No DO-330 shape (TQP / TOR / TVCP / TCI / TAS) | Whittaker | Avionics / space | +| MCP: no batch, no idempotency, manual reload after mutation, stringified content | Krishnamurthy | Agent-fleet operators | +| 17-lint `#![allow]` copy-paste, `Error` too coarse, 55 top-level modules | El-Masri | New contributors | +| Commit-trailer enforcement day-7 friction, no tooling support | El-Masri | New contributors | +| Pre-1.0, schema deltas still landing, Verus assumes, Rocq Admitted | Carrasco | 4-year commits | + +## Roadmap, filtered through pulseengine principles + +Every candidate runs through four gates: +- **Falsification over prediction** — does it make a claim mechanically falsifiable? +- **Defense-in-depth** — does it add a check, not a soft-review? +- **MBSE-mandatory** — does it make the model drive the build? +- **Typed compliance** — does it preserve the typed-graph property? + +### Filed as REQs (the falsifiable-claim items) + +| REQ | What | Baseline | Source col | +| -------- | -------------------------------------------------------------------------- | -------------- | ---------- | +| REQ-093 | Implement the 3 FUTURE oracles (asil-decomposition / coverage-threshold / method-table-compliance) | v0.14.0-track | A1 | +| REQ-094 | Reproducible-build oracle + sigstore-signed release verification | v0.14.0-track | A4 | +| REQ-095 | `cargo build` invokes `rivet validate` for crates declaring `rivet.yaml` | v0.14.0-track | B1 | +| REQ-096 | SACM 2.x safety-case schema with deductive-sufficiency mechanisation | v0.15.0-track | A2 | +| REQ-097 | DO-330 tool-qualification artifacts (TQP/TOR/TVCP/TCI/TAS) typed schema | v0.14.0-track | A6 | +| REQ-098 | Independence-of-verification-layers oracle (shared-code-paths gate) | v0.14.0-track | A3 | +| REQ-099 | `rivet_apply` MCP tool — idempotency + atomic + auto-reload + diagnostics | v0.14.0-track | A5 / C6 | + +A v1.0 readiness gate is deliberately **not** filed as a separate REQ. +The decision: see how far we can progress through the v0.14.0+ +backlog without pre-committing to a 1.0 milestone; 1.0 ships when +the natural state of the work meets Carrasco's flip-condition (b), +not when a calendar says so. + +Filed against `artifacts/requirements.yaml` so the dogfooding pattern +holds: REQ → acceptance step → mechanical check on PR. + +### Rejected up-front (don't pass the principle gates) + +- "Add more reviewer-only validation" — soft-oracle. +- "Reduce strict-lint policy to make Rust easier" — weakens + defense-in-depth. +- "Bridge to DOORS as primary path" — DOORS-as-master inverts the + typed-substrate philosophy; bridge as import/export is fine, master + is not. + +### Not filed — design-doc material (B-tier MBSE linkages) + +These are too small for their own REQ but worth doing as PRs in +sequence. Implementation order suggested: + +1. **B3 — Source-comment scanner** (`// rivet: REQ-NNN` per-line + linker). Already specced as [[REQ-092]] in v0.13.0's CHANGELOG; + counts as the eclipse-source-code-linker parity item. +2. **B6 — spar AADL → WIT → rivet typed-artifacts closed loop.** + Already underway per the pulseengine-toolchain memory; nothing to + add here. +3. **B7 — witness MC/DC import.** Wrap with + `rivet import-results --format witness`; closes the witness→rivet + evidence loop the [[req-086-witness-mcdc]] PoC was scaffolding for. +4. **B5 — `rivet validate --since ` as pre-merge git hook.** + Trivial extension of existing baseline machinery. +5. **B4 — `rivet variant ci-config --provider gh-actions`.** Variant + matrix already emits a matrix; generating the full workflow is the + natural extension. +6. **B2 — `rivet variant features --format cargo-features` writes + Cargo.toml feature blocks.** Closes the + "variant-pruning-rust-mcdc" loop end-to-end. + +### Not filed — follow-on engineering work (C-tier maintenance) + +Genuine improvements but they're *tasks*, not *requirements*. Track +as issues / project chores: + +- **C1** 1.0 release — captured by REQ-100. +- **C2** Second committed maintainer org — strategic; see "Eclipse + adoption" below. +- **C3** `rivet contribute new-feature ` scaffolder + Phase-2 + lint migration with a deadline. Day-7 friction directly addressed. +- **C4** `Error` enum: path-aware typed variants, drop `String` + payloads. `thiserror`-mature shape. +- **C5** `rivet commits --suggest-trailers` reads diff, suggests + `Implements:`. One CLI = day-7 friction halved. +- **C7** Structured-content MCP responses when upstream MCP supports + them. Wait for upstream, then switch. +- **C8** `OnceLock` for parser hot regexes. Hygiene fix. +- **C9** Module reorganisation (core/ io/ formats/ validate/). + Post-1.0; high-risk churn pre-1.0. +- **C10** ReqIF / DOORS / AUTOSAR import adapters. Reduces switching + cost; bigger lift, post-1.0. + +## Strategic findings — Carrasco's hybrid verdict + +The CTO did not pick a winner. She picked a hybrid: + +> **Adopt eclipse-score as the system of record. Pilot rivet as the +> agent / oracle layer over it. The fork is the proof this hybrid +> works.** + +**Flip-conditions** (any two trigger rivet-primary): + +- **(a)** A second committed maintainer org appears. +- **(b)** Rivet ships 1.0 with TCL dossier and a signed support SLA. +- **(c)** Eclipse formally adopts rivet (or equivalent typed substrate) + as upstream. + +(a) and (b) are inside our control. (c) is org-strategic and held — +no proactive outreach until (b) lands. + +Concrete implication: the v0.14.0 / v1.0 roadmap is the flip-condition +roadmap. The eclipse-score fork is the proof the bridge works; rivet +doesn't need to win against eclipse — it needs to *be* the typed +substrate eclipse adopts. + +## Highest-leverage sequence + +If executed in this order, every step strictly increases flip-condition +progress without changing direction: + +1. **REQ-091 (rowan fix) + parallel agent's `feat/import-results-sphinx-needs`** — + v0.13.1. Already planned. Closes the silent-grading-hole and ships + the eclipse-score importer that surfaced it. +2. **REQ-093 + REQ-094 + REQ-095** — v0.14.0. The three items that + convert rivet's TCL dossier from "narrative" to "tool" — Carrasco + flip-condition (b) prerequisites. +3. **REQ-097 + REQ-098** — v0.14.0+. DO-330 dossier shape + + independence oracle close Whittaker's findings. +4. **REQ-099** — v0.14.0. Unblocks agent fleets per Krishnamurthy. +5. **C1 + C2** — when the natural state of the v0.14.0 backlog + reaches Carrasco's flip-condition (b). Second-maintainer-org + engagement begins when 1.0 is *visible*, not before. +6. **REQ-096** — v0.15.0+. SACM safety-case schema; promotes rivet + from "traceability infra" to "assurance case infra". + +## What this document does NOT do + +- Pick eclipse-score as the upstream-of-record (we already do, per the + fork architecture). +- Commit to a v1.0 date or a 1.0-readiness REQ. The position: see how + far we can progress without pre-committing the gate. 1.0 ships when + the natural state of the work meets it. +- Promise eclipse adoption — flip-condition (c) is held. Captured here + for visibility, not pursued. From 77fa2a219beac7399de4c2b4e4296582b538be33 Mon Sep 17 00:00:00 2001 From: Ralf Anton Beier Date: Sun, 24 May 2026 18:00:42 +0200 Subject: [PATCH 2/3] =?UTF-8?q?docs(artifacts):=20file=20REQ-100=20?= =?UTF-8?q?=E2=80=94=20externals:=20kind:=20source=20for=20non-rivet=20ups?= =?UTF-8?q?treams?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adds an optional `kind:` field under `externals:` entries (default `rivet`, new value `source`) so a rivet project can declare an external as "raw source, not a rivet project." Today every external is treated as a rivet project; cloning eclipse-score / sphinx-needs / DOORS-export / plain-code upstreams produces 58 WARN lines of missing-`rivet.yaml` noise per sync. Spotted in the eclipse-score importer workflow — generalises to any fork tracking a non-rivet upstream that feeds a converter or a source-linker. ~20 LoC + schema entry; orthogonal to the rest of the v0.14.0+ backlog. Note: the REQ-100 slot was deliberately left free earlier after dropping the v1.0-readiness proposal; this orthogonal request happily reuses the number. Implements: REQ-100 Refs: REQ-051 Co-Authored-By: Claude Opus 4.7 --- artifacts/requirements.yaml | 55 +++++++++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) diff --git a/artifacts/requirements.yaml b/artifacts/requirements.yaml index 774ee89..3a47c06 100644 --- a/artifacts/requirements.yaml +++ b/artifacts/requirements.yaml @@ -2095,3 +2095,58 @@ artifacts: links: - type: derives-from target: FEAT-010 + + - id: REQ-100 + type: requirement + title: "`externals: kind: source` — track non-rivet upstreams (eclipse-score, sphinx-needs, DOORS exports, plain code repos) without the missing-rivet.yaml warning" + status: draft + description: | + Today every external in `rivet.yaml` is assumed to be a rivet + project, so `rivet sync` (and downstream loaders) try to read + the external's `rivet.yaml` and emit a WARN when it is absent. + A converter scenario like the eclipse-score import pulls 20+ + upstream repos that are deliberately not rivet projects — by + design, they ship sphinx-needs / DOORS-exports / plain code, + not `rivet.yaml`. The current behaviour emits 58 WARN lines of + pure noise in that workflow. + + Generalises beyond eclipse-score: any fork tracking a DOORS + export, a sphinx-needs project, or a plain source repo that + feeds a converter or a source-linker wants the same shape. + + Design: + - Add an optional `kind:` field to each entry under + `externals:`. Two enum values: + - `rivet` (default — current behaviour: loads the + external's `rivet.yaml`, may emit + assumption-of-use / discharged-by reconciliation, etc.). + - `source` (NEW — `rivet sync` clones to the same on-disk + location but loaders skip the `rivet.yaml` read attempt; + no WARN; no rivet-project bookkeeping). + - Scope: ~20 LoC in `rivet-core/src` plus the schema entry. + - `rivet validate` rejects an unknown `kind:` value with a + named-enum error (no silent fallback to `rivet`). + + Acceptance: + - Fixture: a `rivet.yaml` declaring `externals: foo: + { git: ..., kind: source }` syncs and validates cleanly, + with ZERO `missing rivet.yaml` warnings for `foo`. + - Fixture: omitting `kind:` defaults to `rivet` and + preserves today's behaviour exactly — a missing + `rivet.yaml` still surfaces (regression test). + - Fixture: an unknown `kind:` value (e.g. `kind: roboms`) + produces an ERROR diagnostic that names both the bad value + and the enum domain. + - Documented under `rivet docs externals`. + + Note: the slot REQ-100 was deliberately left free earlier + after dropping the v1.0-readiness REQ proposal; this + orthogonal request happily reuses the number. + tags: [externals, sync, converter, non-rivet-upstream, ergonomics] + fields: + priority: should + category: functional + baseline: v0.13.x-track + links: + - type: traces-to + target: REQ-051 From 6af726e2f7535dcc896dda6c4739dc98a496c7e8 Mon Sep 17 00:00:00 2001 From: Ralf Anton Beier Date: Sun, 24 May 2026 20:18:41 +0200 Subject: [PATCH 3/3] =?UTF-8?q?docs(artifacts):=20file=20REQ-101=20?= =?UTF-8?q?=E2=80=94=20`rivet=20verify`=20artifact-driven=20verification?= =?UTF-8?q?=20gate=20(meld=20pattern)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Lands the artifact-driven verification-gate pattern that meld already runs (`tools/post_verification_comment.py`, ~50 LoC) as a first-class `rivet verify` subcommand, baselined v0.14.0-track. The gate inverts the usual loop: the artifact list is the worklist, the test is the evidence, and the absence of a matching test is a discrete diagnostic row (MISSING), not silence. Adding REQ-099 to the spec without a matching test now fails CI by absence — same shape as the schema's required-fields gates, but for executable evidence. Per the reuse-binding-patterns guidance, this composes on an existing schema mechanism (a new optional `verification-template` field on `ArtifactTypeDef`) rather than introducing a new directive shape. Runner is shell-injectable via `rivet.yaml` so pytest / nextest / bazel / ctest all work without rivet learning each. Outputs include a meld-parity `--format pr-comment`, JSON for dashboards, and a YAML write-through into the existing `ResultStore` so `rivet results show` surfaces verify results without modification. Explicitly NOT an oracle in `rivet validate`: validate stays read-only over YAML; verify executes tests and belongs in its own command. Implements: REQ-101 Refs: REQ-051, REQ-004 Co-Authored-By: Claude Opus 4.7 --- artifacts/requirements.yaml | 90 +++++++++++++++++++++++++++++++++++++ 1 file changed, 90 insertions(+) diff --git a/artifacts/requirements.yaml b/artifacts/requirements.yaml index 3a47c06..7561a3f 100644 --- a/artifacts/requirements.yaml +++ b/artifacts/requirements.yaml @@ -2150,3 +2150,93 @@ artifacts: links: - type: traces-to target: REQ-051 + + - id: REQ-101 + type: requirement + title: "Artifact-driven verification gate — `rivet verify` matches approved artifacts to convention-named tests" + status: draft + description: | + Land the artifact-driven verification-gate pattern that meld + already runs (`tools/post_verification_comment.py`, ~50 LoC) + as a first-class `rivet verify` subcommand. + + The gate inverts the usual "run tests, check exit code" loop: + the artifact list is the worklist, the test is the evidence, + and the absence of a matching test is a discrete diagnostic + row (MISSING), not silence. Same traceability shape as + REQ-051 (commit trailer demands link) and the schema's + required-fields gates — the model demands a test, and CI + falsifies the obligation mechanically. + + Pattern (per artifact A where A.status = approved and the + schema's `verification-template` is set on A's type): + + glob = expand(template, A.id) # REQ-001 -> test_req_001_* + tests = discover(glob) # via configured runner + if tests == []: bucket(A) = MISSING + elif any(t.failed): bucket(A) = FAILED + else: bucket(A) = PASSED + + Schema extension (composes on existing `ArtifactTypeDef` per + the reuse-binding-patterns guidance, NOT a new directive): + + - id: requirement + verification-template: "test_{id_lower_underscored}_*" + + The field is optional; types without it are excluded from the + gate (e.g. decisions, features that have no executable + evidence). + + Runner is shell-injectable via `rivet.yaml` + (default `cargo test --no-fail-fast`) so pytest / nextest / + bazel / ctest work without rivet learning each. + + Outputs: + - `--format pr-comment` — markdown grouped by bucket with + source-of-truth footer (byte-comparable to meld); + - `--format json` — machine-readable, dashboard-ingestible; + - `--format yaml --out artifacts/results/` — written into the + existing `ResultStore` so `rivet results show` surfaces it + without modification. + + Gate: exit code 1 if any artifact is FAILED or MISSING; 0 + otherwise. + + NOT an oracle in `rivet validate`: validate is read-only over + YAML. `verify` executes tests and belongs in its own command. + + Acceptance: + - `rivet verify --help` lists the subcommand. + - Schema fixture with `verification-template: + "test_{id_lower_underscored}_*"` on the `requirement` + type + one approved REQ-X with a matching passing test + makes `rivet verify` exit 0 and report 1/1 PASSED. + - Removing the test makes `rivet verify` exit 1 with REQ-X + in the MISSING bucket — the absence is a row, not silence. + - Making the test fail makes `rivet verify` exit 1 with + REQ-X in the FAILED bucket. + - Types without `verification-template` (e.g. decisions) are + excluded from the worklist and not counted. + - `rivet verify --format pr-comment` emits markdown with + PASSED / FAILED / MISSING sections + a footer naming the + source-of-truth file(s) and the template — byte-comparable + to meld's reference output on the meld corpus. + - `rivet verify --format yaml --out artifacts/results/` + writes a `ResultStore`-loadable file consumed by + `rivet results show` without modification. + - Runner command is overridable via `rivet.yaml` + (`verify.runner`) — a pytest project sets it once, no + code change. + - Worked example under `examples/verify/` + GitHub Action + snippet under `docs/ci/` wrapping + `rivet verify --format pr-comment | gh pr comment`. + tags: [verification, gate, ci, mbse, traceability, meld-parity, new-capability] + fields: + priority: should + category: functional + baseline: v0.14.0-track + links: + - type: derives-from + target: REQ-051 + - type: traces-to + target: REQ-004