From 62555f82b1a420f816a3eda36653599bb6838730 Mon Sep 17 00:00:00 2001 From: Ralf Anton Beier Date: Tue, 28 Apr 2026 06:44:04 +0200 Subject: [PATCH] =?UTF-8?q?fix(aspice):=20seed=20validates=20clean=20after?= =?UTF-8?q?=20init=20=E2=80=94=20declare=20allocated-from=20+=20add=20stak?= =?UTF-8?q?eholder-req=20parent?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Round-3 fresh-user dogfood (sandbox /tmp/aspice-seed-only) confirmed that `rivet init --preset aspice && rivet validate` ships a seed that fails validation with 2 errors out of the box: ERROR: [SYSREQ-001] link 'derives-from' requires at least 1 target, found 0 ERROR: [SWARCH-001] link type 'allocated-from' is not defined in the schema — declare it in link-types: or remove the link Result: FAIL (2 errors) Two real bugs in the shipped aspice preset: 1. The `common` schema declares `allocated-to` with `inverse: allocated-from`, registering only the forward token `allocated-to`. ASPICE's SWE.2 traceability rule (`swe2-allocated-from-swe1`) uses `allocated-from` as the *forward* direction (sw-arch-component allocates from sw-req), and the seed's SWARCH-001 uses it the same way. The validator correctly rejects the use because no schema registers `allocated-from` as a forward link-type. This is exactly the gotcha-G.3 footgun the quickstart documents. 2. `system-req` requires `derives-from -> [stakeholder-req]` per the ASPICE `sys2-derives-from-sys1` rule. The seed had SYSREQ-001 with no `derives-from`, so the rule fails on the first `rivet validate` post-init. Changes: - `schemas/aspice.yaml`: declare `allocated-from` as a forward link-type in ASPICE's `link-types:` block, with `inverse: allocated-to`, restricted to `source-types: [sw-arch-component]` / `target-types: [sw-req, system-arch-component]`. This matches what the existing `swe2-allocated-from-swe1` traceability rule already requires and what artifact-types' link-fields already reference (lines 97-98, 142-143). Schema is now internally consistent. - `rivet-cli/src/main.rs` (`ASPICE_SAMPLE` const): add a STKHR-001 stakeholder-req as the V-model root, wire SYSREQ-001's `derives-from` to it. The chain STKHR-001 (stakeholder-req) ← derives-from SYSREQ-001 (system-req) ← derives-from SWREQ-001 (sw-req) ← allocated-from SWARCH-001 (sw-arch-component) satisfies all three left-V ASPICE rules (sys2-derives-from-sys1, swe1-derives-from-sys, swe2-allocated-from-swe1). Verified locally: $ rivet init --preset aspice && rivet validate INFO: [SWREQ-001] Every SW requirement should be verified by at least one verification measure INFO: [SYSREQ-001] Every system requirement should be verified by at least one verification measure Result: PASS (0 warnings) Result PASS with 0 errors and 0 warnings. The two remaining INFOs are lifecycle-coverage hints — they suggest the natural next step (authoring sw-verification / sys-verification artifacts) and do not block the validate gate. Implements: REQ-007, REQ-010 Refs: FEAT-001 --- rivet-cli/src/main.rs | 15 +++++++++++++++ schemas/aspice.yaml | 13 +++++++++++++ 2 files changed, 28 insertions(+) diff --git a/rivet-cli/src/main.rs b/rivet-cli/src/main.rs index e911fe6..a20282b 100644 --- a/rivet-cli/src/main.rs +++ b/rivet-cli/src/main.rs @@ -1980,6 +1980,18 @@ artifacts: const ASPICE_SAMPLE: &str = "\ artifacts: + - id: STKHR-001 + type: stakeholder-req + title: Operators need full sensor history for fleet diagnostics + status: draft + description: > + Fleet operators need access to a complete time-series record of + every sensor reading so anomalies discovered post-trip can be + diagnosed against ground-truth data. + fields: + priority: must + source: fleet-operations-stakeholder-doc-v1 + - id: SYSREQ-001 type: system-req title: System shall provide data logging @@ -1991,6 +2003,9 @@ artifacts: priority: must verification-criteria: > Verify that sensor data is recorded at 100Hz under nominal load. + links: + - type: derives-from + target: STKHR-001 - id: SWREQ-001 type: sw-req diff --git a/schemas/aspice.yaml b/schemas/aspice.yaml index 69b86a5..75dfdc2 100644 --- a/schemas/aspice.yaml +++ b/schemas/aspice.yaml @@ -419,6 +419,19 @@ link-types: source-types: [verification-verdict] target-types: [verification-execution] + # `allocated-from` is the forward direction used by ASPICE + # `sw-arch-component` to point at its allocating sw-req. The common + # schema declares the inverse-named pair (`allocated-to` with + # `inverse: allocated-from`) but only registers the forward token + # `allocated-to`. ASPICE swaps the canonical direction for SWE.2, + # so we declare `allocated-from` here as a forward link-type to + # avoid the gotcha-G.3 footgun in the seed. + - name: allocated-from + inverse: allocated-to + description: SW arch component is allocated from a SW requirement (SWE.2) + source-types: [sw-arch-component] + target-types: [sw-req, system-arch-component] + # ────────────────────────────────────────────────────────────────────────── # ASPICE traceability rules #