Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
440f88b
feat(cli): add comprehensive --format json tests for all commands (#9…
avrabe Apr 6, 2026
e5c1e6a
feat(stpa-sec): add MCP security UCAs, scenario, and constraint
avrabe Apr 6, 2026
aa189b3
feat(export): add EU AI Act Annex IV section to HTML export (#99 Phas…
avrabe Apr 6, 2026
783ab53
feat(mcp): add HTTP transport endpoint on dashboard (#98 Phase 3)
avrabe Apr 6, 2026
0fc82a8
fix(stpa): add constraint-satisfies links and MCP UCAs for 100% bridg…
avrabe Apr 6, 2026
c5e1996
chore: format fixups from cherry-picks
avrabe Apr 7, 2026
1755d72
docs: strengthen commit traceability instructions and add retroactive…
avrabe Apr 7, 2026
c9a0e09
fix(schema): declare missing fields that caused 135 INFO diagnostics
avrabe Apr 7, 2026
5ea28ef
feat: add spar as external dependency with cross-repo artifact sync t…
avrabe Apr 7, 2026
777bd19
fix(cli): unify stats text/JSON paths to prevent count divergence
avrabe Apr 7, 2026
2b3749e
feat(cli): add docs --list flag and LSP integration tests
avrabe Apr 7, 2026
9383bf5
fix: salsa validation path now loads bridge schemas
avrabe Apr 7, 2026
f43c442
fix: correct Claude Code hook format for PostToolUse
avrabe Apr 7, 2026
497f089
feat: s-expression query language with rowan parser and CLI --filter
avrabe Apr 12, 2026
b8091f6
feat: dashboard API ?filter= param + EU AI Act runtime-evidence schema
avrabe Apr 12, 2026
f1f7546
test: proptest logical equivalences for s-expression evaluator (CC-VA…
avrabe Apr 12, 2026
91840a4
feat(mcp): add modify, link, unlink, remove tools + git hook installer
avrabe Apr 12, 2026
3f35be3
feat(db): salsa tracked functions for s-expression filter caching
avrabe Apr 12, 2026
0ba9469
feat: rivet init --hooks + rivet_query MCP tool
avrabe Apr 12, 2026
41cfdf9
chore: fix formatting, clippy lints, and unused imports
avrabe Apr 12, 2026
0d07558
chore: format test files + include provenance auto-stamp artifacts
avrabe Apr 12, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 2 additions & 8 deletions .claude/settings.json
Original file line number Diff line number Diff line change
@@ -1,19 +1,13 @@
{
"hooks": {
"PreCommit": [
{
"type": "command",
"command": "rivet validate"
}
],
"PostToolUse": [
{
"matcher": "Edit|Write",
"if": "Edit(artifacts/**|safety/**)|Write(artifacts/**|safety/**)",
"hooks": [
{
"type": "command",
"command": "bash -c 'FILE=$(cat - | jq -r \".tool_input.file_path // empty\"); [ -n \"$FILE\" ] && rivet stamp all --created-by ai-assisted 2>/dev/null || true'"
"if": "Edit(artifacts/**|safety/**)|Write(artifacts/**|safety/**)",
"command": "rivet stamp all --created-by ai-assisted 2>/dev/null || true"
}
]
}
Expand Down
25 changes: 24 additions & 1 deletion .claude/settings.local.json
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,30 @@
"Bash(MIRIFLAGS=\"-Zmiri-disable-isolation -Zmiri-tree-borrows\" cargo +nightly miri test -p rivet-core --lib -- yaml_cst::tests::parse_actual_hazards_file --nocapture)",
"Bash(cargo generate-lockfile:*)",
"Bash(git rebase:*)",
"Bash(cargo install:*)"
"Bash(cargo install:*)",
"Bash(rivet validate:*)",
"Bash(rivet provenance:*)",
"Bash(rivet stamp:*)",
"Bash(rivet docs:*)",
"Skill(update-config)",
"Bash(bash -c 'rivet stamp all --created-by ai-assisted 2>/dev/null || true')",
"WebFetch(domain:x-as-code.useblocks.com)",
"WebFetch(domain:sphinx-needs.readthedocs.io)",
"WebFetch(domain:sphinx-modeling.readthedocs.io)",
"WebFetch(domain:sphinxcontrib-needs.readthedocs.io)",
"WebFetch(domain:github.com)",
"WebFetch(domain:raw.githubusercontent.com)",
"WebFetch(domain:pypi.org)",
"Bash(curl -sI https://raw.githubusercontent.com/useblocks/sphinx-needs/main/docs/conf.py)",
"Bash(curl -s \"https://api.github.com/repos/useblocks/sphinx-needs/git/trees/main?recursive=1\")",
"Bash(curl -s \"https://api.github.com/repos/useblocks/sphinx-needs/contents/\")",
"Bash(curl -s \"https://api.github.com/repos/useblocks/sphinx-needs/contents/docs\")",
"Bash(curl -s \"https://api.github.com/repos/useblocks/sphinx-needs/contents/docs/directives\")",
"Bash(curl -sI \"https://raw.githubusercontent.com/useblocks/sphinx-needs/main/docs/configuration.rst\")",
"Bash(curl -s \"https://api.github.com/repos/useblocks/sphinx-needs/branches\")",
"Bash(curl -s \"https://api.github.com/repos/useblocks/sphinx-needs/git/refs/heads/master\")",
"Bash(chmod +x:*)",
"Bash(yamllint -d relaxed artifacts/v040-decisions.yaml artifacts/v040-features.yaml safety/stpa/variant-hazards.yaml schemas/eu-ai-act.yaml)"
]
}
}
133 changes: 120 additions & 13 deletions .rivet/agent-context.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,34 @@ Auto-generated by `rivet context` — do not edit.

- **Name:** rivet
- **Version:** 0.1.0
- **Schemas:** common, dev, aadl
- **Sources:** artifacts (generic-yaml)
- **Schemas:** common, dev, aadl, stpa, stpa-sec
- **Sources:** artifacts (generic-yaml), safety/stpa (stpa-yaml), safety/stpa-sec (generic-yaml)
- **Docs:** docs, arch
- **Results:** results

## Artifacts

| Type | Count | Example IDs |
|------|-------|-------------|
| aadl-component | 21 | ARCH-SYS-001, ARCH-SYS-002, ARCH-CORE-001 |
| design-decision | 10 | DD-001, DD-002, DD-003 |
| feature | 30 | FEAT-001, FEAT-002, FEAT-003 |
| requirement | 16 | REQ-001, REQ-002, REQ-003 |
| **Total** | **77** | |
| aadl-component | 29 | ARCH-SYS-001, ARCH-SYS-002, ARCH-CORE-001 |
| controlled-process | 5 | PROC-ARTIFACTS, PROC-LINKGRAPH, PROC-EXTERNAL |
| controller | 8 | CTRL-DEV, CTRL-CLI, CTRL-CORE |
| controller-constraint | 59 | CC-C-1, CC-C-2, CC-C-3 |
| design-decision | 47 | DD-001, DD-002, DD-003 |
| feature | 140 | FEAT-001, FEAT-002, FEAT-003 |
| hazard | 32 | H-1, H-2, H-3 |
| loss | 13 | L-LSP-001, L-LSP-002, L-LSP-003 |
| loss-scenario | 35 | LS-C-1, LS-C-2, LS-C-3 |
| requirement | 40 | REQ-001, REQ-002, REQ-003 |
| sec-constraint | 13 | SSC-IMPL-001, SSC-IMPL-002, SSC-IMPL-003 |
| sec-hazard | 11 | SH-1, SH-2, SH-3 |
| sec-loss | 8 | SL-IMPL-001, SL-IMPL-002, SL-IMPL-003 |
| sec-scenario | 8 | SLS-IMPL-001, SLS-1, SLS-2 |
| sec-uca | 9 | SUCA-CLI-1, SUCA-CLI-2, SUCA-DASH-1 |
| sub-hazard | 12 | H-1.1, H-1.2, H-1.3 |
| system-constraint | 38 | SC-1, SC-2, SC-3 |
| uca | 59 | UCA-C-1, UCA-C-2, UCA-C-3 |
| **Total** | **566** | |

## Schema

Expand All @@ -29,22 +43,89 @@ Auto-generated by `rivet context` — do not edit.
Required fields: category, aadl-package
- **`aadl-flow`** — End-to-end flow with latency bounds
Required fields: flow-kind
- **`aadl-tool`** — An AADL ecosystem tool — captures what it does, what makes it unique, and what capabilities spar could adopt from it.

Required fields: tool-status, category, capabilities
- **`control-action`** — An action issued by a controller to a controlled process or another controller.

Required fields: action
- **`controlled-process`** — A process being controlled — the physical or data transformation acted upon by controllers.

Required fields: (none)
- **`controller`** — A system component (human or automated) responsible for issuing control actions. Each controller has a process model — its internal beliefs about the state of the controlled process.

Required fields: (none)
- **`controller-constraint`** — A constraint on a controller's behavior derived by inverting a UCA. Specifies what the controller must or must not do.

Required fields: constraint
- **`design-decision`** — An architectural or design decision with rationale
Required fields: rationale
- **`feature`** — A user-visible capability or feature
Required fields: (none)
- **`hazard`** — A system state or set of conditions that, together with worst-case environmental conditions, will lead to a loss.

Required fields: (none)
- **`loss`** — An undesired or unplanned event involving something of value to stakeholders. Losses define what the analysis aims to prevent.

Required fields: (none)
- **`loss-scenario`** — A causal pathway describing how a UCA could occur or how the control action could be improperly executed, leading to a hazard.

Required fields: (none)
- **`requirement`** — A functional or non-functional requirement
Required fields: (none)
- **`sec-constraint`** — A security constraint — a condition or behavior required to prevent a security hazard. Each constraint is the security inversion of a hazard.

Required fields: (none)
- **`sec-hazard`** — A security hazard — a system state or condition that, if exploited by an adversary in a worst-case environment, leads to a security loss.

Required fields: cia-impact
- **`sec-loss`** — A security loss — an undesired event involving breach of a CIA property (confidentiality, integrity, or availability). Parallels the STPA 'loss' type but is scoped to adversarial threats.

Required fields: cia-impact
- **`sec-scenario`** — A security loss scenario — a causal pathway (with adversarial causation) describing how a sec-uca could occur or how the control action could be exploited by an adversary to reach a security hazard.

Required fields: (none)
- **`sec-uca`** — A security Unsafe Control Action — a control action that, in a particular adversarial context, leads to a security hazard. Includes an adversarial-causation field explaining how an attacker could introduce or exploit this UCA.

Required fields: uca-type, adversarial-causation
- **`sub-hazard`** — A refinement of a hazard into a more specific unsafe condition.

Required fields: (none)
- **`system-constraint`** — A condition or behavior that must be satisfied to prevent a hazard. Each constraint is the inversion of a hazard.

Required fields: (none)
- **`uca`** — An Unsafe Control Action — a control action that, in a particular context and worst-case environment, leads to a hazard. Four types (provably complete):
1. Not providing the control action leads to a hazard
2. Providing the control action leads to a hazard
3. Providing too early, too late, or in the wrong order
4. Control action stopped too soon or applied too long

Required fields: uca-type

### Link Types

- `acts-on` (inverse: `acted-on-by`)
- `allocated-from` (inverse: `allocated-to`)
- `allocated-to` (inverse: `allocated-from`)
- `caused-by-sec-uca` (inverse: `causes-sec-scenario`)
- `caused-by-uca` (inverse: `causes-scenario`)
- `constrained-by` (inverse: `constrains`)
- `constrains-controller` (inverse: `controller-constrained-by`)
- `constraint-satisfies` (inverse: `satisfied-by-constraint`)
- `contains` (inverse: `contained-by`)
- `depends-on` (inverse: `depended-on-by`)
- `derives-from` (inverse: `derived-into`)
- `implements` (inverse: `implemented-by`)
- `inverts-uca` (inverse: `inverted-by`)
- `issued-by` (inverse: `issues`)
- `leads-to-hazard` (inverse: `hazard-caused-by`)
- `leads-to-loss` (inverse: `loss-caused-by`)
- `leads-to-sec-hazard` (inverse: `sec-hazard-caused-by`)
- `leads-to-sec-loss` (inverse: `sec-loss-caused-by`)
- `mitigates` (inverse: `mitigated-by`)
- `modeled-by` (inverse: `models`)
- `prevents` (inverse: `prevented-by`)
- `prevents-sec-hazard` (inverse: `sec-hazard-prevented-by`)
- `refines` (inverse: `refined-by`)
- `satisfies` (inverse: `satisfied-by`)
- `traces-to` (inverse: `traced-from`)
Expand All @@ -57,24 +138,50 @@ Auto-generated by `rivet context` — do not edit.
| requirement-coverage | requirement | warning | Every requirement should be satisfied by at least one design decision or feature |
| decision-justification | design-decision | error | Every design decision must link to at least one requirement |
| aadl-component-has-allocation | aadl-component | info | AADL component should trace to a requirement or architecture element |
| hazard-has-loss | hazard | error | Every hazard must link to at least one loss |
| constraint-has-hazard | system-constraint | error | Every system constraint must link to at least one hazard |
| uca-has-hazard | uca | error | Every UCA must link to at least one hazard |
| uca-has-controller | uca | error | Every UCA must link to a controller |
| controller-constraint-has-uca | controller-constraint | error | Every controller constraint must link to at least one UCA |
| hazard-has-constraint | hazard | warning | Every hazard should be addressed by at least one system constraint |
| uca-has-controller-constraint | uca | warning | Every UCA should be addressed by at least one controller constraint |
| sec-hazard-has-loss | sec-hazard | error | Every security hazard must link to at least one security loss |
| sec-constraint-has-hazard | sec-constraint | error | Every security constraint must link to at least one security hazard |
| sec-uca-has-hazard | sec-uca | error | Every security UCA must link to at least one security hazard |
| sec-hazard-has-constraint | sec-hazard | warning | Every security hazard should be addressed by at least one security constraint |
| constraint-has-requirement | system-constraint | warning | Every system constraint should be satisfied by at least one requirement |
| controller-constraint-has-requirement | controller-constraint | info | Every controller constraint should be satisfied by at least one requirement |

## Coverage

**Overall: 100.0%**
**Overall: 83.7%**

| Rule | Source Type | Covered | Total | % |
|------|------------|---------|-------|---|
| requirement-coverage | requirement | 16 | 16 | 100.0% |
| decision-justification | design-decision | 10 | 10 | 100.0% |
| aadl-component-has-allocation | aadl-component | 21 | 21 | 100.0% |
| requirement-coverage | requirement | 40 | 40 | 100.0% |
| decision-justification | design-decision | 47 | 47 | 100.0% |
| aadl-component-has-allocation | aadl-component | 29 | 29 | 100.0% |
| hazard-has-loss | hazard | 32 | 32 | 100.0% |
| constraint-has-hazard | system-constraint | 38 | 38 | 100.0% |
| uca-has-hazard | uca | 59 | 59 | 100.0% |
| uca-has-controller | uca | 59 | 59 | 100.0% |
| controller-constraint-has-uca | controller-constraint | 59 | 59 | 100.0% |
| hazard-has-constraint | hazard | 32 | 32 | 100.0% |
| uca-has-controller-constraint | uca | 59 | 59 | 100.0% |
| sec-hazard-has-loss | sec-hazard | 11 | 11 | 100.0% |
| sec-constraint-has-hazard | sec-constraint | 13 | 13 | 100.0% |
| sec-uca-has-hazard | sec-uca | 9 | 9 | 100.0% |
| sec-hazard-has-constraint | sec-hazard | 11 | 11 | 100.0% |
| constraint-has-requirement | system-constraint | 0 | 38 | 0.0% |
| controller-constraint-has-requirement | controller-constraint | 0 | 59 | 0.0% |

## Validation

0 errors, 0 warnings
0 errors, 38 warnings

## Documents

4 documents loaded
6 documents loaded

## Commands

Expand Down
3 changes: 3 additions & 0 deletions .rivet/provenance-pending.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"marks": []
}
79 changes: 70 additions & 9 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -108,15 +108,76 @@ Use `rivet validate --format json` for machine-readable output.

## Commit Traceability

This project enforces commit-to-artifact traceability.
This project enforces commit-to-artifact traceability. Every non-exempt
commit that touches code in `rivet-core/src/` or `rivet-cli/src/` MUST
include at least one artifact trailer in the commit message body.

Required git trailers:
- `Fixes` -> maps to link type `fixes`
- `Implements` -> maps to link type `implements`
- `Refs` -> maps to link type `traces-to`
- `Satisfies` -> maps to link type `satisfies`
- `Verifies` -> maps to link type `verifies`
### Required Git Trailers

Exempt artifact types (no trailer required): `chore`, `style`, `ci`, `docs`, `build`
Add one or more of these trailers to the **last paragraph** of the commit
message body (after a blank line, before any Co-Authored-By):

To skip traceability for a commit, add: `Trace: skip`
| Trailer | Link Type | When to Use |
|---------|-----------|-------------|
| `Implements: REQ-NNN` | implements | New feature that fulfils a requirement or feature artifact |
| `Fixes: REQ-NNN` | fixes | Bug fix or correction related to an artifact |
| `Verifies: REQ-NNN` | verifies | Test or verification that validates an artifact |
| `Satisfies: SC-NNN` | satisfies | Implementation that satisfies a system constraint |
| `Refs: FEAT-NNN` | traces-to | General reference when the commit relates to but does not fully implement an artifact |

Multiple trailers are encouraged. Comma-separate IDs for the same trailer type:
```
Implements: REQ-028, REQ-029
Refs: #91
```

### Exempt Commits

These conventional-commit types do NOT require trailers: `chore`, `style`,
`ci`, `docs`, `build`.

To explicitly skip traceability for any other commit, add: `Trace: skip`

### Choosing the Right Artifacts

- **New parser/extraction feature** -> `Implements: REQ-028` (lossless CST) or `REQ-029` (incremental validation)
- **Schema addition** -> `Implements: REQ-010` (schema-driven validation)
- **CLI command** -> `Implements: REQ-007` (CLI and serve pattern)
- **STPA-related** -> `Implements: REQ-002` (STPA artifact support)
- **Validation fix** -> `Fixes: REQ-004` (validation engine)
- **Dashboard/serve** -> `Refs: FEAT-001` or relevant FEAT-NNN
- **MCP server** -> `Refs: FEAT-010, REQ-022`
- **Test addition** -> `Verifies: REQ-NNN` for the requirement being tested

### Retroactive Traceability Map

The following major commits predate strict trailer enforcement. This table
documents their artifact relationships for audit purposes (these cannot be
added as trailers without rewriting git history):

| Commit | PR | Summary | Artifacts |
|--------|----|---------|-----------|
| `8321f8bb` | #114 | Rowan-based lossless YAML CST parser (Phase 1) | Implements REQ-028 |
| `fd99574e` | #119 | Rowan HIR extraction (Phase 2) + MCP tools | Implements REQ-028, REQ-029; Refs FEAT-010 |
| `e4f398ec` | #120 | Schema-driven extraction from rowan CST (Phase 3) | Implements REQ-028, REQ-010 |
| `bd0d729a` | #121 | Salsa integration (Phase 5) + dogfood tracking | Implements REQ-029 |
| `4e2aa4ab` | #122 | Doc spans + round-trip equivalence tests | Verifies REQ-028, REQ-034 |
| `29b735bf` | #123 | Phase 6 rowan migration + issue fixes | Implements REQ-028, REQ-029; Fixes REQ-002, REQ-004 |
| `6f781be1` | #124 | Edge case hardening + STPA + MCP tests | Fixes REQ-004; Verifies FEAT-010 |
| `2b7acd41` | #118 | `rivet schema validate` command | Implements REQ-010; Refs #93 |
| `28402ebe` | #117 | ISO/PAS 8800 AI safety + SOTIF schemas | Implements REQ-010 |
| `ffeff760` | #115 | Domain schemas (IEC 61508, IEC 62304, DO-178C, EN 50128) | Implements REQ-010 |
| `2c9fb62b` | #112 | yaml-section and shorthand-links in schema | Implements REQ-010 |
| `aba9c5f3` | #111 | STPA adapter handles arbitrary filenames | Fixes REQ-002 |
| `43830b9b` | #109 | GSN safety cases + STPA-for-AI schemas | Implements REQ-010 |
| `9a5011e2` | #108 | Convergence tracking, rivet get, MCP server | Implements FEAT-010, REQ-007 |
| `2f54fabc` | #101 | Schema/LSP fixes, EU AI Act, salsa, STPA | Implements REQ-010, REQ-029 |
| `0661926d` | #97 | Release delta in export + CI snapshot | Implements REQ-035 |
| `c5ff64c8` | #96 | Embed phases 2+5 (diagnostics, matrix, snapshots) | Implements REQ-033 |
| `cc4cc1c1` | #94 | oEmbed provider and Grafana JSON API | Implements FEAT-001 |
| `adcf0bc1` | #28 | Phase 3 (30+ features, 402 tests, formal verification) | Implements REQ-004, REQ-012 |

### Current Coverage

Run `rivet commits` to see current commit-to-artifact traceability status.
Target: 100% of non-exempt commits in traced paths should have trailers.
36 changes: 34 additions & 2 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,43 @@

See [AGENTS.md](AGENTS.md) for project instructions.

Additional Claude Code settings:
## Validation and Queries
- Use `rivet validate` to verify changes to artifact YAML files
- Use `rivet list --format json` for machine-readable artifact queries
- Commit messages require artifact trailers (Implements/Fixes/Verifies/Satisfies/Refs)
- A Claude Code pre-commit hook runs `rivet validate` before each commit
(configured in `.claude/settings.json`)

## Commit Traceability (MANDATORY)
Every commit that touches files in `rivet-core/src/` or `rivet-cli/src/`
MUST include artifact trailers. This is the single most important convention
in this project. Without trailers, commits become "orphans" that break
traceability coverage.

Add trailers in the commit message body (after a blank line):
```
Implements: REQ-028, REQ-029
Fixes: REQ-004
Verifies: REQ-010
Refs: FEAT-001
```

Quick reference for common work:
- Parser/CST changes -> `Implements: REQ-028`
- Incremental/salsa changes -> `Implements: REQ-029`
- Validation changes -> `Implements: REQ-004` or `Fixes: REQ-004`
- Schema changes -> `Implements: REQ-010`
- CLI commands -> `Implements: REQ-007`
- Dashboard/serve -> `Refs: FEAT-001`
- MCP server -> `Refs: FEAT-010`
- STPA artifacts -> `Implements: REQ-002`
- Test additions -> `Verifies: REQ-NNN` (the requirement being tested)

Exempt types (no trailer needed): chore, style, ci, docs, build.
To skip explicitly: add `Trace: skip` trailer.

See AGENTS.md "Commit Traceability" section for the full trailer reference
and retroactive traceability map.

## AI Provenance
- AI provenance is auto-stamped via PostToolUse hook when artifact files are edited
- When manually stamping, include model: `rivet stamp <ID> --created-by ai-assisted --model claude-opus-4-6`
Loading
Loading