From b903b64da91a4bb93a3e6ea65332aaac03aca2e7 Mon Sep 17 00:00:00 2001 From: Ralf Anton Beier Date: Mon, 27 Apr 2026 22:45:38 +0200 Subject: [PATCH 1/3] docs(quickstart): rewrite for fresh-user clarity, drop self-references MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Two clean-room dogfood passes (round 1 + round 2 fresh-user agents, both ignoring CLAUDE.md / memory / rivet source) surfaced six concrete issues in the embedded quickstart: 1. No "What is rivet?" preamble — readers assembled the mental model by osmosis from example commands. 2. Step 9 referenced Mythos red-team scaffold ("if you cloned the rivet repo") — out of scope for first-contact, confused readers. 3. Step 1 install said `cargo install --path rivet-cli` without noting that requires a clone of the rivet repo. 4. Step 2's goal claimed `init` scaffolds `schemas/` (it doesn't) and didn't mention the seed `artifacts/requirements.yaml` that collides with step 3's REQ-001. 5. Step 7's Python oracle used `error_count` key (vacuously true); actual JSON key is `errors` — a real broken link wasn't caught. 6. Existing-repo overlay snippet elided "all other base fields" with a placeholder, setting up the very G.2 trap it warned about. Changes: - Add 6-line "What is rivet?" preamble (typed YAML + schema + graph + four interfaces; DOORS/Polarion/Jira analogy). - Step 1: explicit "from a clone of the rivet repo" caveat on `cargo install --path`; npm + binary-release alternatives. - Step 2: drop schemas/ from goal sentence; add preset glossary (dev, aspice, stpa, eu-ai-act, safety-case); mention the seed. - Step 3: prepend `rm artifacts/requirements.yaml` to clear seed. - Step 7: fix Python oracle key (`error_count` → `errors`). - Step 9: replace Mythos with "Add a living document" walking markdown frontmatter + `{{stats}}` / `{{coverage}}` / `[[ID]]` embeds; explicit `rivet serve` restart since step 8 killed it. - Step 10: drop deep-audience acronyms (Kani/Verus/Rocq) from the docs list; gloss MCP and LSP one-liner each. - New Existing-repo bring-up appendix: pick preset, curate ~5 artifacts per layer, dump base type with `rivet schema show`, write a complete copy-pasteable overlay (extends `requirement` from dev preset with `polarion_id`, all base fields and link-fields explicitly listed — no "..." placeholders). - New Common gotchas appendix G.1–G.7: LSP overlay blindness, overlay merge field-drop, forward/inverse link types, doc vs artifact refs, imported-stub honesty, lifecycle severity intent, schema-show preset locality. Net: 251 → 535 lines. The oracle-gated 10-step rhythm is preserved; new material is in two appendices that readers opt into. Verified: round-2 fresh-user dogfood ran all 10 oracles green and confirmed the broken-link demo (changing target REQ-001 → REQ-999 makes the step-7 oracle exit 1 with a real error). Implements: REQ-007 Refs: FEAT-001 --- rivet-cli/src/quickstart.md | 347 ++++++++++++++++++++++++++++++++---- 1 file changed, 316 insertions(+), 31 deletions(-) diff --git a/rivet-cli/src/quickstart.md b/rivet-cli/src/quickstart.md index ee581e0..b474f49 100644 --- a/rivet-cli/src/quickstart.md +++ b/rivet-cli/src/quickstart.md @@ -1,12 +1,25 @@ # Quickstart — 10 oracle-gated steps +**What is rivet?** It's a CLI that stores engineering artifacts +(requirements, features, decisions, hazards…) as typed YAML, validates +them and the typed links between them against a pluggable schema, and +exposes the resulting graph through a CLI, an HTTP dashboard, an LSP, +and an MCP server. Picture a Git-friendly, file-based replacement for +DOORS / Polarion / Jira where the artifact model is text and the +validator is `make`-fast. This walkthrough takes about 15 minutes. + Each step has a **goal**, the **commands** to run, and an **oracle**: a deterministic command + expected output that proves the step succeeded. Copy-paste each block top-to-bottom; an AI agent can follow this end-to-end without supervision because every step is mechanically checkable. -> The walk-through assumes a fresh empty directory. Substitute paths as -> needed; the oracles still hold. +> **Two ways to use this guide:** +> +> - **Greenfield** (recommended for first contact): work in a fresh empty +> directory. Steps 1–10 run cleanly with no prior setup. +> - **Existing repo**: skip the `mkdir` in step 2, `cd` into your project +> root, and read the *Existing-repo bring-up* appendix at the end before +> committing to a schema preset. --- @@ -15,10 +28,14 @@ without supervision because every step is mechanically checkable. **Goal**: get the `rivet` binary on your PATH. ```bash +# from a clone of the rivet repo: cargo install --path rivet-cli -# or: npm install -g @pulseengine/rivet -# or: download a release tarball from -# https://github.com/pulseengine/rivet/releases + +# or via npm (no source checkout needed): +npm install -g @pulseengine/rivet + +# or download a binary release from: +# https://github.com/pulseengine/rivet/releases ``` **Oracle**: @@ -34,22 +51,34 @@ means the binary is not on PATH. ## 2. Initialise an empty project -**Goal**: scaffold `rivet.yaml` + `schemas/` + `artifacts/` + `docs/`. +**Goal**: scaffold `rivet.yaml`, `artifacts/`, and `docs/`, with one +seed artifact file as a placeholder example. ```bash mkdir my-project && cd my-project rivet init --preset dev ``` +For an existing repo: skip `mkdir`, `cd` into your repo root, and pick +the preset that fits the domain: + +- `dev` — lightweight `requirement` / `design-decision` / `feature` (good for first contact) +- `aspice` — automotive V-model SW process (Polarion/DOORS shape) +- `stpa` — Systems-Theoretic Process Analysis safety +- `eu-ai-act` — EU AI Act Annex IV conformity +- `safety-case` — GSN safety arguments + +`rivet docs schemas-overview` lists every shipped preset. + **Oracle**: ```bash test -f rivet.yaml && test -d artifacts && test -d docs && echo OK ``` -Expected: `OK`. The `dev` preset wires the lightweight `requirement` / -`design-decision` / `feature` types so you can validate without committing -to a full ASPICE or STPA shape on day one. +Expected: `OK`. `init` creates a seed `artifacts/requirements.yaml` +with placeholder REQ-001 + FEAT-001 — a worked example you can inspect +(`cat artifacts/requirements.yaml`) and then delete in step 3. --- @@ -58,6 +87,10 @@ to a full ASPICE or STPA shape on day one. **Goal**: write one valid requirement. ```bash +# Replace the seed with your own clean slate. The seed REQ-001 collides +# with what we're about to write — delete it. +rm artifacts/requirements.yaml + cat > artifacts/sample.yaml <<'EOF' artifacts: - id: REQ-001 @@ -78,6 +111,10 @@ rivet list --type requirement --format json | grep -q '"id": "REQ-001"' && echo Expected: `OK`. The artifact is now in the typed store and queryable. +> If you're importing from another system (Polarion, Jira, DOORS), +> preserve the source IDs as custom fields — see the +> *Existing-repo bring-up* appendix. + --- ## 4. Validate — no diagnostics @@ -146,8 +183,8 @@ rivet list --format json \ && echo OK ``` -Expected: `OK`. Both artifacts are present, the link target resolves, and -validation still passes. +Expected: `OK`. Both artifacts are present, the link target resolves, +and validation still passes. --- @@ -165,7 +202,7 @@ rivet validate rivet validate --format json \ | python3 -c "import json,sys; d=json.load(sys.stdin); \ assert d['result']=='PASS', d; \ - assert d.get('error_count',0)==0, d; print('OK')" + assert d.get('errors',0)==0, d; print('OK')" ``` Expected: `OK`. If you change `target: REQ-001` to a typo like @@ -199,31 +236,51 @@ global search. --- -## 9. (Optional) Run the slop-hunt agent pipeline +## 9. Add a living document -**Goal**: try the four-prompt agent-driven audit on a rivet-managed repo. +**Goal**: see how markdown documents with rivet embeds resolve. ```bash -ls scripts/mythos/ # if you cloned the rivet repo +cat > docs/coverage.md <<'EOF' +--- +id: DOC-COVERAGE +title: Verification coverage report +type: report +--- + +# Coverage + +{{stats}} + +{{coverage}} + +The async pipeline [[FEAT-001]] satisfies the latency contract +[[REQ-001]]. +EOF ``` -The four prompts (`rank.md`, `discover.md`, `validate.md`, `emit.md`) are -designed to run inside a Claude Code session against any rivet-managed -project. The HOWTO walks through the workflow: +**Oracle**: ```bash -rivet docs --grep mythos +rivet validate --format json | grep -q '"result": "PASS"' && echo OK ``` -**Oracle** (when run inside a Claude Code session): +Expected: `OK`. Restart the dashboard (step 8 killed it): ```bash -test -f .rivet/mythos/ranking.json && echo OK +rivet serve --port 3099 & +SERVE_PID=$! +sleep 1 +curl -fsS -o /dev/null -w "%{http_code}\n" http://localhost:3099/documents/DOC-COVERAGE +# expect: 200 +kill "$SERVE_PID" ``` -Expected: `OK` — the rank step writes `ranking.json` with one entry per -source file, scored 1–5 for slop likelihood. See -`scripts/mythos/HOWTO.md` for the full pipeline. +Open `http://localhost:3099/documents/DOC-COVERAGE` in a browser and +the document viewer renders the embeds with live stats + coverage; the +`[[REQ-001]]` references become clickable links. + +For the full embed catalog: `rivet docs embed-syntax`. --- @@ -232,19 +289,247 @@ source file, scored 1–5 for slop likelihood. See ```bash rivet docs # list every embedded topic rivet docs cli # CLI command reference -rivet docs schema/stpa # STPA schema deep-dive +rivet docs schemas-overview # all built-in presets rivet docs schema/aspice # ASPICE 4.0 V-model schema +rivet docs schema/stpa # STPA hazard analysis rivet docs commit-traceability # git-trailer rules for compliance -rivet docs formal-verification # Kani / Verus / Rocq strategy rivet docs cross-repo # multi-repo linking -rivet mcp # start the MCP server for AI agents -rivet lsp # start the LSP server for editors ``` +The same artifact graph is also reachable from agents and editors: + +- **MCP server** — `rivet mcp` exposes typed-graph queries to AI agents + via Model Context Protocol. Claude Code calls it natively. +- **LSP server** — `rivet lsp` is the Language Server for editor + integrations (jump-to-artifact, hover, diagnostics in YAML files). + For the larger picture — three-pillar synthesis, why agents need typed schemas and oracle gates together — read [*Three patterns colliding*](https://pulseengine.eu/blog/three-patterns-colliding/). -For the per-situation playbook (compliance lineage, ASPICE, STPA-Sec, -EU AI Act) read `docs/what-is-rivet.md` in this repo or -`rivet docs schemas-overview` from any rivet install. +--- + +## Appendix: Existing-repo bring-up + +Steps 1–10 work cleanly on a fresh directory. To bring rivet into an +existing project (a real codebase with real source-of-truth docs), the +flow is the same but with three additions. + +### Pick the closest built-in preset + +`rivet docs schemas-overview` lists every shipped preset. Pick the one +nearest to your existing document model — ASPICE for V-model SW +projects, STPA-Sec for safety/security analysis, `eu-ai-act` for +EU AI Act conformity, etc. You can always add a per-repo overlay on +top. + +### Curate, don't bulk-import + +The seed file is just an example. Replace it with ~5 hand-picked +artifacts per layer drawn from your existing docs. Use **verbatim +titles** so you can grep them back to the source. + +> **Hard rule:** never bulk-extract on the first pass. The point of the +> first import is to discover where your real document model maps +> cleanly onto the rivet schema and where it does not. Bulk import +> hides both. + +Preserve provenance: + +```yaml +- id: SRS-001 # rivet-native ID + type: sw-req + title: Unidirectional periodic data delivery # verbatim from source + fields: + polarion_id: CMWD-66890 # source-of-truth pointer + polarion_status: approved +``` + +### Add a project-local schema overlay + +The base preset will not know your custom fields. To extend a base +type, you redeclare it in an overlay listing **every base field and +every base link-field, plus your additions**. Forgetting to repeat +them silently drops them — that's gotcha G.2. + +#### Step 1: Dump the base type + +```bash +rivet schema show requirement +rivet schema links # all link types and their inverses +``` + +> **Caveat (gotcha G.7):** `rivet schema show ` only works for +> types in your *currently-loaded* schema. If you're planning an +> overlay over `aspice` from a `dev` project, the command will error +> with `Unknown artifact type`. Workaround: temporarily change +> `rivet.yaml`'s `schemas:` to include the target preset, run +> `rivet schema show`, then switch back. + +#### Step 2: Write the overlay + +Add `schemas/my-project-overlay.yaml`. The example below extends the +`requirement` type from the `dev` preset with a `polarion_id` field — +this is **complete and copy-pasteable from the project you built in +steps 1–10**. Note how every base field (`priority`, `category`, +`baseline`, `upstream-ref`) and every link-field (`satisfies`, +`derives-from`) is repeated verbatim: + +```yaml +schema: + name: my-project-overlay + version: "0.1.0" + extends: [common, dev] + +artifact-types: + - name: requirement # MUST match base type name + description: Requirement with Polarion provenance + fields: # MUST list ALL base fields + additions + - name: priority + type: string + required: false + allowed-values: [must, should, could, wont] + - name: category + type: string + required: false + allowed-values: [functional, non-functional, constraint, interface] + - name: baseline + type: string + required: false + - name: upstream-ref + type: string + required: false + - name: polarion_id # the addition + type: string + required: false + link-fields: # MUST list ALL base link-fields + - name: satisfies + link-type: satisfies + target-types: [any] + required: false + cardinality: zero-or-many + - name: derives-from + link-type: derives-from + target-types: [any] + required: false + cardinality: zero-or-many +``` + +For larger presets like `aspice`, the same pattern applies: extend the +shipped `sw-req` / `sys-req` types, but the field/link-field lists are +longer. Always start by dumping the base with `rivet schema show`. + +#### Step 3: Register the overlay + +Edit `rivet.yaml`: + +```yaml +project: + name: my-project + schemas: + - common + - dev + - my-project-overlay # bare name, no path, no .yaml +``` + +#### Step 4: Verify + +```bash +rivet validate +rivet schema show requirement # should now show polarion_id in Fields +``` + +If `polarion_id` appears in the Fields list, your overlay is wired in. +Add `polarion_id: ` under `fields:` on any requirement +artifact and re-validate to confirm. + +--- + +## Appendix: Common gotchas + +These are the rough edges most people hit on a first real bring-up. +None block you, but knowing them up-front saves time. + +### G.1 The editor LSP doesn't see overlay types + +When you use a project-local schema overlay, your YAML editor will flag +`unknown artifact type 'sw-req'` and similar errors. Trust +`rivet validate` (the CLI loads the overlay); ignore the LSP +diagnostics for overlaid types until LSP overlay support lands. + +### G.2 Schema overlays merge by name and silently drop unlisted fields + +Rivet has no `field-extensions:` syntax. To add a field to an existing +type, you redeclare the type in your overlay. **You must list every +field and every `link-fields:` entry the base type had**, plus your +additions. Forgetting to repeat the link-fields will make validation +fail with `link type 'X' is not defined in the schema` on artifacts +that worked yesterday. + +### G.3 Forward and inverse link-types are independent + +The `common` schema declares some link types only in their inverse +direction (e.g. `allocated-to` registered with `inverse: allocated-from`). +If your overlay uses `allocated-from` as the *forward* direction (as +ASPICE `sw-arch-component` does), declare it explicitly: + +```yaml +link-types: + - name: allocated-from + inverse: allocated-to + description: Forward allocation used by ASPICE arch components +``` + +### G.4 Document refs vs artifact refs + +In `docs/*.md`, the double-bracket form like `[[REQ-001]]` resolves to +an artifact and becomes a clickable link. Pointing it at a *document* +ID produces a "document references X which does not exist" warning — +documents are not artifacts. Use plain markdown links between docs: + +```markdown +See the [SRS](srs.md) for requirements. +``` + +### G.5 Be honest about stubs + +When you import an artifact whose real content lives elsewhere, mark +it explicitly: + +```yaml +- id: SYSREQ-001 + status: imported-stub + description: | + NOTE: Stub. The real content lives in upstream system document XYZ + which is not yet imported into this rivet project. +``` + +The `imported-stub` status raises a WARN (not an INFO) so reviewers see +at a glance which artifacts are placeholders. Faking content defeats +the point of the typed model. + +### G.6 Lifecycle severity scaling is intentional + +`swe1-has-verification` (and similar lifecycle rules) fire: +- **WARN** for `status: approved` or `imported-stub` +- **INFO** for `status: draft` + +This is by design — approved artifacts without verification deserve +more attention than drafts. Don't "fix" the warnings by downgrading +status. + +### G.7 `rivet schema show ` only sees loaded types + +`rivet schema show` introspects the schema the *current project* is +configured with (per `rivet.yaml`). Asking it about a type the project +doesn't load returns `Unknown artifact type`, even if that type exists +in another shipped preset. To plan an overlay over a different preset: + +1. Temporarily set `rivet.yaml`'s `schemas:` to include the target + preset (e.g. `aspice`). +2. Run `rivet schema show ` to dump fields and link-fields. +3. Restore `rivet.yaml` and write the overlay using what you dumped. + +Or use a scratch project (`mkdir /tmp/dump-aspice && cd $_ && rivet +init --preset aspice && rivet schema show sw-req`) and copy from +there. From 5fcc4a22a7f6cb78eb346cc029feeb729f9d04dd Mon Sep 17 00:00:00 2001 From: Ralf Anton Beier Date: Tue, 28 Apr 2026 05:51:27 +0200 Subject: [PATCH 2/3] docs(quickstart): preset-branch step 2/3, ASPICE overlay example, init contract MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Three parallel scenario-based fresh-user dogfood agents (STPA safety, Polarion-import compliance, MCP integrator) all reached their goals but surfaced four cross-cutting issues: 1. Step 2 oracle didn't tell non-`dev` users their seed file IS a worked example (e.g. `artifacts/safety.yaml` for `stpa` ships a complete loss/hazard/uca chain). Non-`dev` users either deleted it following step 3's `rm`, or didn't realize they could skip steps 3+6 entirely. 2. Step 3's `rm artifacts/requirements.yaml` is correct for `dev` but actively wrong for non-`dev` presets — it nukes their pre-built domain example. 3. Existing-repo appendix's overlay example is `dev`-flavored. ASPICE `sw-req` has a *required* `derives-from` link to system-req/arch — a category difference, not just a quantity difference. Hand-waving "the same pattern applies, lists are longer" sets up the very G.2 trap the appendix warns against. Compliance leads importing from Polarion are the primary audience for this section. 4. No written promise of `rivet init` non-destructiveness on a non-empty repo. A real Polarion-import lead won't run a foreign CLI on 10k files without that contract in writing. Changes: - Step 2: add a callout distinguishing `dev` (seed is placeholder, follow steps 3+6 to write your own) from non-`dev` presets (seed is a worked example in domain vocabulary, read it and skip to step 4). Pointer to `rivet docs schema/` for the type catalogue. Tip about `rivet schema show ` errors as a free schema dump. - Step 3: gate the seed `rm` with "`dev` preset only" callout; point non-`dev` readers to step 4. - Existing-repo appendix: add "What `rivet init` touches in a non-empty repo" section stating the non-destructiveness contract explicitly (rivet.yaml + artifacts/ + docs/ + one seed file; nothing else). - Existing-repo appendix: add a complete copy-pasteable ASPICE overlay (sw-req extended with polarion_id / polarion_status / asil, listing all base fields and the required `derived-from` link-field with target-types and cardinality verbatim from `rivet schema show sw-req`). - Existing-repo appendix: document the stub-parent tradeoff — curating one `sw-req` from a Polarion export forces a parent stub on `system-req`. Pattern: `status: imported-stub` (WARN via G.5) rather than faking content. Verified: - Scenario A (STPA) reached PASS in 13min on prior version; the step-2 callout would have collapsed the scenario's "I didn't know the seed was the tutorial" wall-clock. - Scenario B (Polarion → ASPICE) reached PASS in 7min with an ASPICE overlay matching the new appendix snippet (modulo formatting); the worked example replaces the hand-wave. - `rivet schema show sw-req` from a fresh `aspice` project on rivet 0.4.3 confirms the field/link-field shape used in the overlay matches the binary 1:1. Implements: REQ-007 Refs: FEAT-001 --- rivet-cli/src/quickstart.md | 106 +++++++++++++++++++++++++++++++++--- 1 file changed, 98 insertions(+), 8 deletions(-) diff --git a/rivet-cli/src/quickstart.md b/rivet-cli/src/quickstart.md index b474f49..1fe42da 100644 --- a/rivet-cli/src/quickstart.md +++ b/rivet-cli/src/quickstart.md @@ -76,19 +76,39 @@ the preset that fits the domain: test -f rivet.yaml && test -d artifacts && test -d docs && echo OK ``` -Expected: `OK`. `init` creates a seed `artifacts/requirements.yaml` -with placeholder REQ-001 + FEAT-001 — a worked example you can inspect -(`cat artifacts/requirements.yaml`) and then delete in step 3. +Expected: `OK`. + +> **If you picked a non-`dev` preset** (e.g. `stpa`, `aspice`, +> `eu-ai-act`, `safety-case`): your seed file is a **complete worked +> example in your domain's vocabulary**, not a placeholder. For `stpa` +> it's `artifacts/safety.yaml` with `loss`, `hazard`, and `uca` +> artifacts already linked correctly. **Read your seed first** +> (`cat artifacts/*.yaml`) and run `rivet docs schema/` +> for the full type catalogue. Then **skip to step 4** — your seed +> already covers what steps 3 and 6 demonstrate. Steps 5 and 7–10 +> work the same regardless of preset (substitute artifact IDs). +> +> **If you're using the `dev` preset** (the rest of this walkthrough +> assumes this): the seed `artifacts/requirements.yaml` has a +> placeholder REQ-001 + FEAT-001. Read it for reference, then continue +> with step 3 to write your own. + +Tip: `rivet schema show ` errors with a list of all valid +types in the loaded schema — treat it as a free schema dump. --- ## 3. Add a typed artifact +> **`dev` preset only.** If you used `stpa`/`aspice`/`eu-ai-act`/ +> `safety-case`, your seed is already a working artifact set — skip +> ahead to step 4 to validate it. + **Goal**: write one valid requirement. ```bash -# Replace the seed with your own clean slate. The seed REQ-001 collides -# with what we're about to write — delete it. +# Replace the dev-preset seed with your own clean slate. Its REQ-001 +# collides with what we're about to write — delete it. rm artifacts/requirements.yaml cat > artifacts/sample.yaml <<'EOF' @@ -315,6 +335,16 @@ Steps 1–10 work cleanly on a fresh directory. To bring rivet into an existing project (a real codebase with real source-of-truth docs), the flow is the same but with three additions. +### What `rivet init` touches in a non-empty repo + +Before you run `rivet init` against a real repo with thousands of +files, the contract: **`init` creates `rivet.yaml`, `artifacts/`, +`docs/`, and a single seed artifact file inside `artifacts/`. It does +not touch any other directory.** Your `src/`, `specs/`, `docs/` (if it +already exists — `init` skips it), `.git/`, and any other tree are +untouched. The seed is the only thing you'll want to delete or replace +when you start curating real artifacts. + ### Pick the closest built-in preset `rivet docs schemas-overview` lists every shipped preset. Pick the one @@ -415,9 +445,69 @@ artifact-types: cardinality: zero-or-many ``` -For larger presets like `aspice`, the same pattern applies: extend the -shipped `sw-req` / `sys-req` types, but the field/link-field lists are -longer. Always start by dumping the base with `rivet schema show`. +#### ASPICE worked overlay (real-world Polarion-import case) + +For an ASPICE bring-up, the same pattern applies but `sw-req`'s shape +is genuinely different — it has a **required** `derived-from` link +restricted to `[system-req, system-arch-component]`. Skipping the +link-field redeclaration trips G.2 *and* `swe1-derives-from-sys` at +the same time. Complete copy-pasteable overlay: + +```yaml +schema: + name: legacy-repo-overlay + version: "0.1.0" + extends: [common, aspice] + +artifact-types: + - name: sw-req # MUST match base type name + description: ASPICE sw-req with Polarion provenance + fields: # base + additions; list ALL + - name: req-type + type: string + required: false + allowed-values: [functional, performance, interface, constraint, safety] + - name: priority + type: string + required: false + - name: verification-criteria + type: text + required: false + - name: polarion_id # the addition + type: string + required: false + - name: polarion_status # the addition + type: string + required: false + - name: asil # the addition + type: string + required: false + allowed-values: [QM, A, B, C, D] + link-fields: # MUST repeat — required link! + - name: derived-from + link-type: derives-from + target-types: [system-req, system-arch-component] + required: true + cardinality: one-or-many +``` + +**Stub-parent tradeoff** (hits everyone importing one SW req from +Polarion): ASPICE's `sw-req` *requires* a `derives-from` link to a +`system-req` or `system-arch-component`. If you curate a single +`sw-req` from a Polarion export, you must also curate a parent stub: + +```yaml +- id: SYSREQ-PRODUCER + type: system-req + title: Producer subsystem (imported stub) + status: imported-stub # WARN, not INFO — visible in review + description: | + NOTE: Stub. Real content lives in upstream system document XYZ + not yet imported into rivet. +``` + +The `imported-stub` status raises a WARN per gotcha G.5 so reviewers +see at a glance which artifacts are placeholders. #### Step 3: Register the overlay From a479949f41211bfccfbbfa07c21e07cd5d67ebd0 Mon Sep 17 00:00:00 2001 From: Ralf Anton Beier Date: Tue, 28 Apr 2026 06:36:31 +0200 Subject: [PATCH 3/3] =?UTF-8?q?docs(quickstart):=20document=20the=20sw-req?= =?UTF-8?q?=20=E2=86=92=20system-req=20=E2=86=92=20stakeholder-req=20stub?= =?UTF-8?q?=20chain?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Round-3 fresh-user dogfood (sandbox /tmp/legacy-repo-3) verified the 4-of-5 round-2 fixes landed cleanly, but caught one partial-impact gap: the existing-repo appendix's stub-parent tradeoff section documents the sw-req → system-req hop but not the transitive system-req → stakeholder-req requirement. Result: when a compliance lead curates one sw-req from a Polarion export, they add a system-req stub (per the appendix), validate, and hit a *second* error: `[SYSREQ-PRODUCER] link 'derives-from' requires at least 1 target` because system-req's own ASPICE rule requires a derives-from to a stakeholder-req. They have to add a second stub they didn't expect. Changes: - Stub-parent tradeoff section now spells the full two-hop chain (stakeholder-req → system-req → sw-req) with both stubs in YAML, showing the system-req stub's `derives-from: STKHR-*` link explicitly. - Pointer to `rivet schema show ` to discover further required derives-from chains for any other base type. - Cross-reference to gotcha G.3 (forward vs inverse link-type direction) inline next to the overlay, since the same `aspice` schema's `allocated-from` is registered only as an inverse and the seed itself trips this — readers writing similar links into their own arch components will hit the same error. Verified: round-3 dogfood reached PASS in 3.8min (vs 7min round 1, 5min round 2). All 5 step-2/3 + appendix fixes verified in place via explicit grep checks before the dogfood walked the doc. Separate finding (NOT fixed in this PR — needs a binary patch): `rivet init --preset aspice && rivet validate` ships a seed that fails validation with 2 errors (SYSREQ-001 missing derives-from target; SWARCH-001 uses undeclared `allocated-from` link). Filed separately. Implements: REQ-007 Refs: FEAT-001 --- rivet-cli/src/quickstart.md | 31 +++++++++++++++++++++++++------ 1 file changed, 25 insertions(+), 6 deletions(-) diff --git a/rivet-cli/src/quickstart.md b/rivet-cli/src/quickstart.md index 1fe42da..09e7721 100644 --- a/rivet-cli/src/quickstart.md +++ b/rivet-cli/src/quickstart.md @@ -493,21 +493,40 @@ artifact-types: **Stub-parent tradeoff** (hits everyone importing one SW req from Polarion): ASPICE's `sw-req` *requires* a `derives-from` link to a -`system-req` or `system-arch-component`. If you curate a single -`sw-req` from a Polarion export, you must also curate a parent stub: +`system-req` or `system-arch-component`. And `system-req` itself +*requires* a `derives-from` link to a `stakeholder-req`. So curating +one `sw-req` cascades into a two-stub chain: ```yaml +- id: STKHR-PRODUCER + type: stakeholder-req + title: Producer subsystem stakeholder need (imported stub) + status: imported-stub # WARN per G.5 — visible in review + description: | + NOTE: Stub. Real content lives in upstream stakeholder document + not yet imported into rivet. + - id: SYSREQ-PRODUCER type: system-req title: Producer subsystem (imported stub) - status: imported-stub # WARN, not INFO — visible in review + status: imported-stub description: | - NOTE: Stub. Real content lives in upstream system document XYZ - not yet imported into rivet. + NOTE: Stub. Real content lives in upstream system document XYZ. + links: + - type: derives-from + target: STKHR-PRODUCER # the chain bottoms out here ``` The `imported-stub` status raises a WARN per gotcha G.5 so reviewers -see at a glance which artifacts are placeholders. +see at a glance which artifacts are placeholders. Run +`rivet schema show ` for any base type to see the full chain +of required `derives-from` links. + +> **Note**: link-type direction matters here. The overlay above uses +> `derives-from` (forward direction). The `aspice` schema also has +> `allocated-from`/`allocated-to` and similar pairs where the inverse +> direction is the canonical one — see gotcha G.3 if you see +> `link type 'allocated-from' is not defined in the schema` errors. #### Step 3: Register the overlay