Skip to content

Commit eadc79d

Browse files
authored
fix(skills): add soup_register kind to evidence-pack source mapping (#614)
Extends the evidence-pack manifest schema (1.0.0 -> 1.1.0) to include soup_register as an allowed kind, and documents its collection contract in source-mapping.md. The new kind is the audit-time companion to the soup-inventory skill (issue #601, PR #604), which produces docs/.index/soup.yaml plus an optional human-readable docs/.index/soup.md. Changes: - source-mapping.md: new kind: soup_register section after risk_file, modeled on the risk_file precedent (single-file contract). Source presence check, collection commands, output layout, sha256 strategy (over soup.yaml only), and related clauses (IEC-62304-5.3.3 and IEC-62304-8.1.1) all populated. - manifest-schema.md: add soup_register to the Allowed kind enum and to the Single-file vs. directory-shaped kinds classification (added by PR #612 for risk_file). Bump _meta.schema to 1.1.0 in the schema template and the minimal-manifest example, expand the example to include a soup_register entry, and add a CHANGES table documenting the version bump. - soup-inventory/SKILL.md: replace the three forward references to a future soup_register kind with cross-references to the now-landed source-mapping.md and manifest-schema.md entries. The schema bump is backward-compatible per the doc's own evolution policy: adding a new allowed kind is a minor bump, pre-1.1.0 manifests remain valid, and consumers that ignore unknown kinds continue to work without modification. Closes #610
1 parent 7f4494b commit eadc79d

3 files changed

Lines changed: 65 additions & 8 deletions

File tree

global/skills/_internal/evidence-pack/reference/manifest-schema.md

Lines changed: 34 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ semantics. Auditors and downstream consumers should treat this file as the contr
1313
# evidence/<version>/manifest.yaml
1414
# Generated by /evidence-pack -- do not edit by hand
1515
_meta:
16-
schema: "1.0.0" # Schema version of this document
16+
schema: "1.1.0" # Schema version of this document
1717
generated: "YYYY-MM-DDTHH:MM:SSZ" # ISO 8601 UTC timestamp
1818
generator: "evidence-pack" # Skill name that produced this artifact
1919
version: "<version>" # The release version this pack documents
@@ -82,6 +82,7 @@ The kind value is a closed enum. Adding a new kind requires updating both this f
8282
| `signed_commits` | `evidence/<version>/signed_commits/` | Plain text from `git log --format='%H %G? %s' <prev-tag>..<version>` showing the signature status (`G`/`B`/`U`/`N`/`X`/`Y`/`R`/`E`) of every commit in the release. |
8383
| `research_artifact` | `evidence/<version>/research_artifact/` | Mirror of files under `docs/research/` that document external citations (per the `research` skill output). |
8484
| `risk_file` | `evidence/<version>/risk_file/risk-file.yaml` | Verbatim copy of the single normalized risk file at `docs/.index/risk-file.yaml` produced by the sibling `risk-control` skill. **Single file** contract -- the `risk_file/` subdirectory contains exactly one file, retained for per-kind directory symmetry. |
85+
| `soup_register` | `evidence/<version>/soup_register/soup.yaml` | Verbatim copy of the single normalized SOUP register at `docs/.index/soup.yaml` produced by the sibling `soup-inventory` skill. Optional companion `soup_register/soup.md` collected when `docs/.index/soup.md` exists. **Single file** contract -- the kind's `sha256` is computed over `soup.yaml` alone; the `soup.md` companion is documentation only. |
8586

8687
A kind whose source is genuinely absent in a project (e.g. no `docs/.index/risk-file.yaml`
8788
yet) should appear in the manifest with `status: skipped` and `reason: source_absent` rather
@@ -94,7 +95,7 @@ and must not be inferred from the `output_path`:
9495

9596
| Shape | Kinds | sha256 over |
9697
|-------|-------|-------------|
97-
| Single file | `matrix`, `signed_commits`, `risk_file` | The bytes of the one collected file. |
98+
| Single file | `matrix`, `signed_commits`, `risk_file`, `soup_register` | The bytes of the one collected file. |
9899
| Directory listing | `ci_run_log`, `pr_review`, `research_artifact` | `find <kind>/ -type f \| sort \| xargs sha256sum` (deterministic listing). |
99100

100101
**The `risk_file` kind is single-file**: the collector copies the single normalized
@@ -104,6 +105,16 @@ directory symmetry and contains exactly one file. Future evidence-pack consumers
104105
treat `risk_file` as single-file; promoting it to a directory mirror would be a
105106
backward-incompatible schema change requiring a major `_meta.schema` bump.
106107

108+
**The `soup_register` kind is single-file**: the collector copies the single normalized
109+
`docs/.index/soup.yaml` produced by the sibling `soup-inventory` skill, plus an optional
110+
`docs/.index/soup.md` companion when present. The kind's `sha256` covers `soup.yaml`
111+
alone; the `soup.md` file is collected for human-readable convenience but is not part of
112+
the checksum and its absence does not change the entry's `status`. Future evidence-pack
113+
consumers must treat `soup_register` as single-file; promoting it to a directory mirror
114+
(e.g. shipping per-supplier breakouts as separate files inside `soup_register/`) would
115+
be a backward-incompatible schema change requiring a major `_meta.schema` bump. New SOUP
116+
artifacts beyond `soup.yaml` and `soup.md` should land under a separate `kind`.
117+
107118
### Status Field
108119

109120
The `status` value is set by the collector in Phase 3 and then frozen.
@@ -152,7 +163,7 @@ commits (a project that has not yet wired up `gh` or a risk file):
152163

153164
```yaml
154165
_meta:
155-
schema: "1.0.0"
166+
schema: "1.1.0"
156167
generated: "2026-05-04T12:34:56Z"
157168
generator: "evidence-pack"
158169
version: "v0.1.0"
@@ -161,9 +172,9 @@ _meta:
161172
tool_versions:
162173
git: "git version 2.43.0"
163174
gh: "unavailable"
164-
artifacts: 6
175+
artifacts: 7
165176
collected: 2
166-
skipped: 4
177+
skipped: 5
167178
failed: 0
168179
169180
artifacts:
@@ -231,6 +242,17 @@ artifacts:
231242
- IEC-62304-7.1.1
232243
- IEC-62304-7.2.1
233244
notes: ""
245+
246+
- kind: soup_register
247+
source: "docs/.index/soup.yaml"
248+
collected_at: "2026-05-04T12:34:54Z"
249+
sha256: null
250+
status: skipped
251+
reason: "source_absent"
252+
related_clauses:
253+
- IEC-62304-5.3.3
254+
- IEC-62304-8.1.1
255+
notes: ""
234256
```
235257

236258
## Example: Failed Entry
@@ -287,6 +309,13 @@ The `evidence-pack` skill writes the matching schema version into `_meta.schema`
287309
generation. External tooling that consumes `manifest.yaml` should refuse to parse when the
288310
major does not match the schema this file documents.
289311

312+
### CHANGES
313+
314+
| Schema | Date | Change |
315+
|--------|------|--------|
316+
| `1.0.0` | 2026-04 | Initial release. Allowed kinds: `matrix`, `ci_run_log`, `pr_review`, `signed_commits`, `research_artifact`, `risk_file`. |
317+
| `1.1.0` | 2026-05 | Added allowed kind `soup_register` for the SOUP register produced by the sibling `soup-inventory` skill (`docs/.index/soup.yaml` plus optional `docs/.index/soup.md`). Backward-compatible: pre-1.1.0 manifests remain valid (the new kind only adds an enum value), and consumers that ignore unknown kinds continue to work without modification. |
318+
290319
## Cross-references
291320

292321
- Per-kind collection commands and target subdirectories: `source-mapping.md`

global/skills/_internal/evidence-pack/reference/source-mapping.md

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,33 @@ attempt to mirror a `risk-file/` directory. Future evidence-pack consumers must
138138
those should be introduced under a new `kind` rather than by promoting `risk_file` to a
139139
directory mirror (which would be a backward-incompatible schema change).
140140

141+
## kind: soup_register
142+
143+
Snapshot of the project's SOUP (Software Of Unknown Provenance) register produced by the
144+
sibling `soup-inventory` skill.
145+
146+
| Field | Value |
147+
|-------|-------|
148+
| **Source presence check** | `[[ -f docs/.index/soup.yaml ]]` |
149+
| **Required tools** | None (plain file copy). |
150+
| **Collection command(s)** | `mkdir -p evidence/<version>/soup_register`<br>`cp docs/.index/soup.yaml evidence/<version>/soup_register/soup.yaml`<br>`[[ -f docs/.index/soup.md ]] && cp docs/.index/soup.md evidence/<version>/soup_register/soup.md \|\| true` |
151+
| **Output layout** | Primary file: `evidence/<version>/soup_register/soup.yaml`. Optional companion: `evidence/<version>/soup_register/soup.md` when the source `docs/.index/soup.md` exists. |
152+
| **sha256 strategy** | Single file: `sha256sum evidence/<version>/soup_register/soup.yaml`. The optional `soup.md` companion is documentation only and is not factored into the kind's checksum. |
153+
| **Related clauses** | `IEC-62304-5.3.3`, `IEC-62304-8.1.1` |
154+
155+
The SOUP register is owned by the sibling `soup-inventory` skill (issue #601, PR #604) and
156+
is emitted as a single normalized YAML file at `docs/.index/soup.yaml`, with an optional
157+
human-readable per-supplier report at `docs/.index/soup.md` (produced by
158+
`/soup-inventory report`). The collection contract is **single file**: the canonical
159+
artifact is `soup.yaml` and the kind's `sha256` is computed over that file alone. The
160+
`soup.md` companion is collected when present so the audit pack carries the same
161+
human-readable view the project ships, but its absence does not affect the kind's status
162+
(`collected` when `soup.yaml` was copied successfully) and it is not part of the checksum.
163+
Future evidence-pack consumers must treat `soup_register` as a single-file kind -- if a
164+
project ever needs additional SOUP artifacts beyond the YAML and its Markdown render,
165+
those should be introduced under a new `kind` rather than by promoting `soup_register` to
166+
a directory mirror (which would be a backward-incompatible schema change).
167+
141168
## Atomic Write Pattern
142169

143170
Every collector writes through a temp path, then renames on success:

global/skills/_internal/soup-inventory/SKILL.md

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,8 @@ the regulated-industry track. The skill is the third-party-software counterpart
4444
`risk-control` (which owns the hazard records) and `traceability` (which owns the
4545
requirements-to-evidence matrix): it produces and maintains the per-project SOUP file that
4646
the traceability matrix references via a new `soup_ids[]` field on each requirement row, and
47-
that the `evidence-pack` skill collects under a future `soup_register` kind.
47+
that the `evidence-pack` skill collects under the `soup_register` kind (see
48+
`global/skills/_internal/evidence-pack/reference/source-mapping.md`).
4849

4950
The skill does not invent regulatory content; it provides a structured, validatable home
5051
for the records that IEC 62304 sections 5.3.3 (specify functional and performance
@@ -92,7 +93,7 @@ The skill never reads source code, never runs builds, and never calls out to ext
9293

9394
| Path | Format | Audience |
9495
|------|--------|----------|
95-
| `docs/.index/soup.yaml` | YAML | Single normalized SOUP register. Consumed by `traceability` (via `soup_ids[]`) and `evidence-pack` (via the future `soup_register` kind). Schema: `reference/soup-record-schema.md`. |
96+
| `docs/.index/soup.yaml` | YAML | Single normalized SOUP register. Consumed by `traceability` (via `soup_ids[]`) and `evidence-pack` (via the `soup_register` kind). Schema: `reference/soup-record-schema.md`. |
9697
| `docs/.index/soup.md` | Markdown | Human-readable per-supplier report produced by `report`. Suitable for inclusion in audit-time exports. |
9798

9899
Both files are written atomically: the skill writes to a sibling `*.tmp` file and renames on
@@ -322,7 +323,7 @@ verbatim rather than inventing new mappings.
322323
| Consumer | Use |
323324
|----------|-----|
324325
| `traceability` skill (P0-1) | Reads `soup.yaml` to populate `soup_ids[]` on requirement matrix rows. Bidirectional linking comes for free. |
325-
| `evidence-pack` skill (P1-1) | Will mirror `soup.yaml` (and the per-supplier `soup.md` report when present) under a future `soup_register` kind in the per-release evidence pack. The current `evidence-pack` source-mapping does not yet enumerate this kind; a follow-up issue will add it. |
326+
| `evidence-pack` skill (P1-1) | Mirrors `soup.yaml` (and the per-supplier `soup.md` report when present) under the `soup_register` kind in the per-release evidence pack. See `global/skills/_internal/evidence-pack/reference/source-mapping.md` (kind: `soup_register`) and `manifest-schema.md` (allowed kinds, schema `1.1.0`). |
326327
| `risk-control` skill (P1-2) | Cross-references SOUP records when a hazard's failure mode involves third-party software; the link is recorded as a `verification_refs[]` entry pointing to the relevant `H-NN` id. |
327328
| `traceability-guard` PreToolUse hook (P0-2) | Could be extended to detect when a PR adds or bumps a lockfile entry without updating the SOUP register. |
328329
| External auditor | Reads `soup.yaml` and `soup.md` directly from the repo at any tagged release; consumes them alongside the matrix as the operational SOUP-management record. |

0 commit comments

Comments
 (0)