Skip to content

Commit cf18e7c

Browse files
authored
refactor: migrate to rmcp-based architecture (#95)
* docs: add STPA analysis, migration plan, and implementation spec Rivet project initialized with STPA schema for rmcp migration safety analysis. 58 artifacts covering losses, hazards, constraints, UCAs, and loss scenarios for migrating from full MCP stack to rmcp extensions. Phase 0+1 design spec and implementation plan ready for execution. * feat: add poc workspace for rmcp migration validation * feat(poc): validate Tower auth middleware with rmcp Working PoC proving Tower middleware can intercept rmcp HTTP requests, enforce Bearer auth, and propagate AuthContext into MCP tool handlers via http::request::Parts extensions. * feat(poc): validate MCP Apps UI resources with rmcp Implements PoC 3 proving rmcp 1.3 supports the MCP Apps extension pattern (SEP-1865) for serving interactive HTML via resources and tools. * feat(poc): validate resource router with rmcp ServerHandler Implements a matchit-based ResourceRouter that maps MCP URI templates (file:///, config://) to handler functions, overriding list_resource_templates and read_resource on ServerHandler alongside #[tool_handler] tools. * docs(poc): record rmcp migration PoC results — all 3 pass * refactor: rename mcp-logging to pulseengine-logging Generic structured logging crate — not MCP-specific. Provides credential scrubbing, metrics, alerting, correlation IDs. * refactor: rename mcp-security-middleware to pulseengine-security Generic Axum/Tower security middleware — not MCP-specific. Remove unused mcp-protocol dependency. * feat: add pulseengine-mcp-resources crate — resource router for rmcp URI-template-based resource router built on matchit for rmcp MCP servers. Provides ResourceRouter<S> with scheme-aware URI matching, handler dispatch, and template listing for ServerHandler integration. * feat: add pulseengine-mcp-apps crate — MCP Apps extension for rmcp * docs: add migration guide for rmcp-based crate structure * refactor: rename mcp-auth to pulseengine-auth Generic auth/RBAC/session crate — not MCP-specific. Remove mcp-protocol dependency, rename MCP-prefixed types (McpPermission → Permission, McpPermissionChecker → PermissionChecker). Middleware now operates on generic (method, params) instead of MCP Request. * refactor: rename directories to match package names, remove poc/ mcp-logging/ → pulseengine-logging/ mcp-auth/ → pulseengine-auth/ mcp-security-middleware/ → pulseengine-security/ Remove poc/ directory — validation complete, results in poc/RESULTS.md preserved in git history. * refactor(examples): rewrite hello-world and ultra-simple to use rmcp * refactor(examples): rewrite auth example for rmcp, remove conformance-server * refactor(examples): rewrite resources-demo and ui-enabled-server for rmcp * fix: rustfmt and Dockerfile directory paths after renames * fix: cargo fmt --all * fix: clippy warnings (dead_code, Default impl, format strings)
1 parent b950226 commit cf18e7c

144 files changed

Lines changed: 5241 additions & 1975 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.claude/settings.local.json

Lines changed: 51 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,57 @@
6161
"Bash(npx -y @modelcontextprotocol/conformance list)",
6262
"Bash(target/debug/hello-world:*)",
6363
"Bash(./target/debug/resources-demo:*)",
64-
"Bash(ls:*)"
64+
"Bash(ls:*)",
65+
"Bash(python3 -c \":*)",
66+
"Bash(wc -l /Volumes/Home/git/pulseengine/mcp/mcp-protocol/src/*.rs /Volumes/Home/git/pulseengine/mcp/mcp-server/src/*.rs /Volumes/Home/git/pulseengine/mcp/mcp-transport/src/*.rs)",
67+
"Bash(python3 -m json.tool)",
68+
"Bash(wc -l /Volumes/Home/git/pulseengine/mcp/mcp-*/src/lib.rs)",
69+
"Bash(for crate:*)",
70+
"Bash(do echo:*)",
71+
"Bash(command -v rivet)",
72+
"Bash(rivet --help)",
73+
"Bash(rivet init:*)",
74+
"Bash(rivet stpa:*)",
75+
"Bash(rivet docs:*)",
76+
"Bash(rivet schema:*)",
77+
"Bash(rivet validate:*)",
78+
"Bash(rivet stats:*)",
79+
"Bash(rivet coverage:*)",
80+
"Bash(rivet matrix:*)",
81+
"Bash(rivet list:*)",
82+
"Bash(python3 -c \"import json,sys; [print\\(f[''''name'''']\\) for f in json.loads\\(sys.stdin.read\\(\\)\\)]\")",
83+
"Bash(git commit:*)",
84+
"Bash(rustup toolchain:*)",
85+
"Bash(rustc --version)",
86+
"Bash(pkill -f \"poc-tower-auth\")",
87+
"Bash(echo \"EXIT: $?\")",
88+
"Bash(TRYBUILD=overwrite cargo test -p pulseengine-mcp-macros test_ui_compilation_failures)",
89+
"Bash(TRYBUILD=overwrite cargo test -p pulseengine-mcp-macros --test ui_tests)",
90+
"Bash(TRYBUILD=overwrite cargo test -p pulseengine-mcp-macros --test compilation_and_ui)",
91+
"Bash(git diff:*)",
92+
"Bash(wc -l /Volumes/Home/git/pulseengine/mcp/mcp-auth/src/*.rs /Volumes/Home/git/pulseengine/mcp/mcp-auth/src/**/*.rs)",
93+
"WebFetch(domain:doc.crates.io)",
94+
"WebFetch(domain:blog.rust-lang.org)",
95+
"WebFetch(domain:internals.rust-lang.org)",
96+
"Bash(wc:*)",
97+
"WebFetch(domain:users.rust-lang.org)",
98+
"WebFetch(domain:rustsec.org)",
99+
"Bash(git -C /Volumes/Home/git/pulseengine/mcp/.claude/worktrees/agent-a3118796 log --oneline -5)",
100+
"Bash(git cherry-pick:*)",
101+
"Bash(git checkout:*)",
102+
"Bash(git clean:*)",
103+
"Bash(git branch:*)",
104+
"Bash(for f:*)",
105+
"Read(//Volumes/Home/git/pulseengine/mcp/**)",
106+
"Bash(done)",
107+
"Bash(do sed:*)",
108+
"Bash(git worktree:*)",
109+
"Bash(git mv:*)",
110+
"Bash(git rm:*)",
111+
"Bash(python3 -c \"import sys,json; d=json.load\\(sys.stdin\\); [print\\(p[''''name''''], p[''''version'''']\\) for p in d[''''packages''''] if p[''''name'''']==''''rmcp'''']\")",
112+
"Bash(python3 -c \"import json,sys; d=json.load\\(sys.stdin\\); [print\\(p[''''name''''], p[''''version'''']\\) for p in d[''''packages''''] if p[''''name'''']==''''rmcp'''']\")",
113+
"Bash(git push:*)",
114+
"Bash(gh pr:*)"
65115
],
66116
"deny": []
67117
}

AGENTS.md

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
<!-- Auto-generated by `rivet init --agents`. Re-run to update after artifact changes. -->
2+
# AGENTS.md — Rivet Project Instructions
3+
4+
> This file was generated by `rivet init --agents`. Re-run the command
5+
> any time artifacts change to keep this file current.
6+
7+
## Project Overview
8+
9+
This project uses **Rivet** for SDLC artifact traceability.
10+
- Config: `rivet.yaml`
11+
- Schemas: common, dev, stpa
12+
- Artifacts: 58 across 12 types
13+
- Validation: `rivet validate` (current status: pass)
14+
15+
## Available Commands
16+
17+
| Command | Purpose | Example |
18+
|---------|---------|---------|
19+
| `rivet validate` | Check link integrity, coverage, required fields | `rivet validate --format json` |
20+
| `rivet list` | List artifacts with filters | `rivet list --type requirement --format json` |
21+
| `rivet stats` | Show artifact counts by type | `rivet stats --format json` |
22+
| `rivet add` | Create a new artifact | `rivet add -t requirement --title "..." --link "satisfies:SC-1"` |
23+
| `rivet link` | Add a link between artifacts | `rivet link SOURCE -t satisfies --target TARGET` |
24+
| `rivet serve` | Start the dashboard | `rivet serve --port 3000` |
25+
| `rivet export` | Generate HTML reports | `rivet export --format html --output ./dist` |
26+
| `rivet impact` | Show change impact | `rivet impact --since HEAD~1` |
27+
| `rivet coverage` | Show traceability coverage | `rivet coverage --format json` |
28+
| `rivet diff` | Compare artifact versions | `rivet diff --base path/old --head path/new` |
29+
30+
## Artifact Types
31+
32+
| Type | Count | Description |
33+
|------|------:|-------------|
34+
| `control-action` | 4 | An action issued by a controller to a controlled process or another controller. |
35+
| `controlled-process` | 2 | A process being controlled — the physical or data transformation acted upon by controllers. |
36+
| `controller` | 3 | 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. |
37+
| `controller-constraint` | 7 | A constraint on a controller's behavior derived by inverting a UCA. Specifies what the controller must or must not do. |
38+
| `design-decision` | 3 | An architectural or design decision with rationale |
39+
| `feature` | 6 | A user-visible capability or feature |
40+
| `hazard` | 6 | A system state or set of conditions that, together with worst-case environmental conditions, will lead to a loss. |
41+
| `loss` | 5 | An undesired or unplanned event involving something of value to stakeholders. Losses define what the analysis aims to prevent. |
42+
| `loss-scenario` | 5 | A causal pathway describing how a UCA could occur or how the control action could be improperly executed, leading to a hazard. |
43+
| `requirement` | 6 | A functional or non-functional requirement |
44+
| `system-constraint` | 5 | A condition or behavior that must be satisfied to prevent a hazard. Each constraint is the inversion of a hazard. |
45+
| `uca` | 6 | 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 |
46+
| `sub-hazard` | 0 | A refinement of a hazard into a more specific unsafe condition. |
47+
48+
## Working with Artifacts
49+
50+
### File Structure
51+
- Artifacts are stored as YAML files in: `artifacts`
52+
- Schema definitions: `schemas/` directory
53+
- Documents: (none configured)
54+
55+
### Creating Artifacts
56+
```bash
57+
rivet add -t requirement --title "New requirement" --status draft --link "satisfies:SC-1"
58+
```
59+
60+
### Validating Changes
61+
Always run `rivet validate` after modifying artifact YAML files.
62+
Use `rivet validate --format json` for machine-readable output.
63+
64+
### Link Types
65+
66+
| Link Type | Description | Inverse |
67+
|-----------|-------------|--------|
68+
| `acts-on` | Control action acts on a process or controller | `acted-on-by` |
69+
| `allocated-to` | Source is allocated to the target (e.g. requirement to architecture component) | `allocated-from` |
70+
| `caused-by-uca` | Loss scenario is caused by an unsafe control action | `causes-scenario` |
71+
| `constrained-by` | Source is constrained by the target | `constrains` |
72+
| `constrains-controller` | Constraint applies to a specific controller | `controller-constrained-by` |
73+
| `depends-on` | Source depends on target being completed first | `depended-on-by` |
74+
| `derives-from` | Source is derived from the target | `derived-into` |
75+
| `implements` | Source implements the target | `implemented-by` |
76+
| `inverts-uca` | Controller constraint inverts (is derived from) an UCA | `inverted-by` |
77+
| `issued-by` | Control action or UCA is issued by a controller | `issues` |
78+
| `leads-to-hazard` | UCA or loss scenario leads to a hazard | `hazard-caused-by` |
79+
| `leads-to-loss` | Hazard leads to a specific loss | `loss-caused-by` |
80+
| `mitigates` | Source mitigates or prevents the target | `mitigated-by` |
81+
| `prevents` | Constraint prevents a hazard | `prevented-by` |
82+
| `refines` | Source is a refinement or decomposition of the target | `refined-by` |
83+
| `satisfies` | Source satisfies or fulfils the target | `satisfied-by` |
84+
| `traces-to` | General traceability link between any two artifacts | `traced-from` |
85+
| `verifies` | Source verifies or validates the target | `verified-by` |
86+
87+
## Conventions
88+
89+
- Artifact IDs follow the pattern: PREFIX-NNN (e.g., REQ-001, FEAT-042)
90+
- Use `rivet add` to create artifacts (auto-generates next ID)
91+
- Always include traceability links when creating artifacts
92+
- Run `rivet validate` before committing

CLAUDE.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
# CLAUDE.md
2+
3+
See [AGENTS.md](AGENTS.md) for project instructions.
4+
5+
Additional Claude Code settings:
6+
- Use `rivet validate` to verify changes to artifact YAML files
7+
- Use `rivet list --format json` for machine-readable artifact queries

0 commit comments

Comments
 (0)