@sym-bot/mesh-channel 0.3.11 → 0.3.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude-plugin/marketplace.json +46 -46
- package/.claude-plugin/plugin.json +50 -50
- package/.mcp.json +16 -16
- package/CHANGELOG.md +627 -587
- package/LICENSE +201 -201
- package/README.md +381 -370
- package/SECURITY.md +89 -89
- package/bin/install.js +603 -603
- package/package.json +50 -50
- package/server.js +1105 -1105
package/SECURITY.md
CHANGED
|
@@ -1,89 +1,89 @@
|
|
|
1
|
-
# Security Model
|
|
2
|
-
|
|
3
|
-
sym-mesh-channel implements defense in depth with three layers. No
|
|
4
|
-
single layer is the sole gate — all three must pass before a mesh
|
|
5
|
-
signal reaches Claude's conversation context.
|
|
6
|
-
|
|
7
|
-
## Layer 1: Transport Authentication
|
|
8
|
-
|
|
9
|
-
Only authenticated peers can send signals to this node.
|
|
10
|
-
|
|
11
|
-
- **LAN (Bonjour)**: peers discover each other via mDNS on the local
|
|
12
|
-
network. Each peer has an Ed25519 keypair generated at first run
|
|
13
|
-
and stored at `~/.sym/nodes/<name>/identity.json`. Peer identity is
|
|
14
|
-
verified via cryptographic handshake (MMP Section 5).
|
|
15
|
-
- **Relay (WebSocket)**: peers authenticate with a shared relay token
|
|
16
|
-
(`SYM_RELAY_TOKEN`). The relay enforces per-token channel isolation —
|
|
17
|
-
peers on different tokens cannot see each other. Unauthenticated
|
|
18
|
-
connections are rejected at the transport level.
|
|
19
|
-
|
|
20
|
-
No unauthenticated source can reach `pushChannel()`.
|
|
21
|
-
|
|
22
|
-
## Layer 2: Protocol-Level Content Gating (SVAF)
|
|
23
|
-
|
|
24
|
-
Every incoming CMB is evaluated by Symbolic-Vector Attention Fusion
|
|
25
|
-
before it enters cognitive state. SVAF computes per-field drift across
|
|
26
|
-
7 semantic dimensions (CAT7: focus, issue, intent, motivation,
|
|
27
|
-
commitment, perspective, mood) and operates in three regimes:
|
|
28
|
-
|
|
29
|
-
- **Aligned** (drift < threshold): CMB is accepted and stored
|
|
30
|
-
- **Guarded** (drift moderate): only the mood field is delivered (protocol guarantee R5)
|
|
31
|
-
- **Rejected** (drift high): CMB is silently dropped
|
|
32
|
-
|
|
33
|
-
This is analogous to a content-aware firewall: it doesn't just check
|
|
34
|
-
who sent the signal — it evaluates whether the signal is semantically
|
|
35
|
-
relevant to the receiver's current context. Low-relevance CMBs are
|
|
36
|
-
gated out so Claude's context window doesn't drown.
|
|
37
|
-
|
|
38
|
-
SVAF field weights are configurable per node (`svafFieldWeights` in
|
|
39
|
-
server.js). The default weights are tuned for engineering-domain
|
|
40
|
-
Claude Code sessions.
|
|
41
|
-
|
|
42
|
-
## Layer 3: Application-Level Restrictions
|
|
43
|
-
|
|
44
|
-
- **No code execution**: incoming mesh signals are text-only CMB fields.
|
|
45
|
-
No mesh peer can trigger Bash commands, file writes, or tool calls
|
|
46
|
-
on this node.
|
|
47
|
-
- **No permission relay**: the `claude/channel/permission` capability is
|
|
48
|
-
explicitly NOT declared. Mesh peers cannot approve or deny tool
|
|
49
|
-
executions on this node.
|
|
50
|
-
- **No arbitrary content injection**: incoming CMBs are formatted as
|
|
51
|
-
structured `[source] focus (mood)` text before being pushed to
|
|
52
|
-
Claude's context. Raw JSON is never injected.
|
|
53
|
-
- **Self-echo filtering**: CMBs from this node's own identity are
|
|
54
|
-
dropped before `pushChannel()` (prevents feedback loops).
|
|
55
|
-
|
|
56
|
-
## Optional: Peer Allowlist
|
|
57
|
-
|
|
58
|
-
Set `SYM_ALLOWED_PEERS` (comma-separated node names) to restrict which
|
|
59
|
-
authenticated peers can push to Claude's context. When set, only CMBs
|
|
60
|
-
and messages from listed peers pass the gate. When empty (default), all
|
|
61
|
-
authenticated peers are accepted — SVAF still gates on content relevance.
|
|
62
|
-
|
|
63
|
-
Example:
|
|
64
|
-
```
|
|
65
|
-
SYM_ALLOWED_PEERS=claude-code-mac,claude-code-win
|
|
66
|
-
```
|
|
67
|
-
|
|
68
|
-
This is an additional layer, not a replacement for transport auth or
|
|
69
|
-
SVAF. It provides explicit identity-level control for environments
|
|
70
|
-
that require it.
|
|
71
|
-
|
|
72
|
-
## Token Handling
|
|
73
|
-
|
|
74
|
-
- `SYM_RELAY_TOKEN`: passed via environment variable, never logged,
|
|
75
|
-
never included in CMBs or channel notifications. In the plugin
|
|
76
|
-
manifest, marked `sensitive: true` (stored in system keychain).
|
|
77
|
-
- Ed25519 private key: stored at `~/.sym/nodes/<name>/identity.json`,
|
|
78
|
-
never transmitted. Only the public key is shared during handshake.
|
|
79
|
-
|
|
80
|
-
## Identity Collision
|
|
81
|
-
|
|
82
|
-
If another process is already running with the same node identity,
|
|
83
|
-
the relay returns close code 4004. The server exits cleanly with
|
|
84
|
-
exit code 2 rather than competing for the identity.
|
|
85
|
-
|
|
86
|
-
## References
|
|
87
|
-
|
|
88
|
-
- [MMP v1.0 Specification](https://meshcognition.org/spec/mmp) — Sections 5 (Connection), 8 (CAT7), 9 (SVAF)
|
|
89
|
-
- [SVAF Paper](https://arxiv.org/abs/2604.03955) — Xu, 2026
|
|
1
|
+
# Security Model
|
|
2
|
+
|
|
3
|
+
sym-mesh-channel implements defense in depth with three layers. No
|
|
4
|
+
single layer is the sole gate — all three must pass before a mesh
|
|
5
|
+
signal reaches Claude's conversation context.
|
|
6
|
+
|
|
7
|
+
## Layer 1: Transport Authentication
|
|
8
|
+
|
|
9
|
+
Only authenticated peers can send signals to this node.
|
|
10
|
+
|
|
11
|
+
- **LAN (Bonjour)**: peers discover each other via mDNS on the local
|
|
12
|
+
network. Each peer has an Ed25519 keypair generated at first run
|
|
13
|
+
and stored at `~/.sym/nodes/<name>/identity.json`. Peer identity is
|
|
14
|
+
verified via cryptographic handshake (MMP Section 5).
|
|
15
|
+
- **Relay (WebSocket)**: peers authenticate with a shared relay token
|
|
16
|
+
(`SYM_RELAY_TOKEN`). The relay enforces per-token channel isolation —
|
|
17
|
+
peers on different tokens cannot see each other. Unauthenticated
|
|
18
|
+
connections are rejected at the transport level.
|
|
19
|
+
|
|
20
|
+
No unauthenticated source can reach `pushChannel()`.
|
|
21
|
+
|
|
22
|
+
## Layer 2: Protocol-Level Content Gating (SVAF)
|
|
23
|
+
|
|
24
|
+
Every incoming CMB is evaluated by Symbolic-Vector Attention Fusion
|
|
25
|
+
before it enters cognitive state. SVAF computes per-field drift across
|
|
26
|
+
7 semantic dimensions (CAT7: focus, issue, intent, motivation,
|
|
27
|
+
commitment, perspective, mood) and operates in three regimes:
|
|
28
|
+
|
|
29
|
+
- **Aligned** (drift < threshold): CMB is accepted and stored
|
|
30
|
+
- **Guarded** (drift moderate): only the mood field is delivered (protocol guarantee R5)
|
|
31
|
+
- **Rejected** (drift high): CMB is silently dropped
|
|
32
|
+
|
|
33
|
+
This is analogous to a content-aware firewall: it doesn't just check
|
|
34
|
+
who sent the signal — it evaluates whether the signal is semantically
|
|
35
|
+
relevant to the receiver's current context. Low-relevance CMBs are
|
|
36
|
+
gated out so Claude's context window doesn't drown.
|
|
37
|
+
|
|
38
|
+
SVAF field weights are configurable per node (`svafFieldWeights` in
|
|
39
|
+
server.js). The default weights are tuned for engineering-domain
|
|
40
|
+
Claude Code sessions.
|
|
41
|
+
|
|
42
|
+
## Layer 3: Application-Level Restrictions
|
|
43
|
+
|
|
44
|
+
- **No code execution**: incoming mesh signals are text-only CMB fields.
|
|
45
|
+
No mesh peer can trigger Bash commands, file writes, or tool calls
|
|
46
|
+
on this node.
|
|
47
|
+
- **No permission relay**: the `claude/channel/permission` capability is
|
|
48
|
+
explicitly NOT declared. Mesh peers cannot approve or deny tool
|
|
49
|
+
executions on this node.
|
|
50
|
+
- **No arbitrary content injection**: incoming CMBs are formatted as
|
|
51
|
+
structured `[source] focus (mood)` text before being pushed to
|
|
52
|
+
Claude's context. Raw JSON is never injected.
|
|
53
|
+
- **Self-echo filtering**: CMBs from this node's own identity are
|
|
54
|
+
dropped before `pushChannel()` (prevents feedback loops).
|
|
55
|
+
|
|
56
|
+
## Optional: Peer Allowlist
|
|
57
|
+
|
|
58
|
+
Set `SYM_ALLOWED_PEERS` (comma-separated node names) to restrict which
|
|
59
|
+
authenticated peers can push to Claude's context. When set, only CMBs
|
|
60
|
+
and messages from listed peers pass the gate. When empty (default), all
|
|
61
|
+
authenticated peers are accepted — SVAF still gates on content relevance.
|
|
62
|
+
|
|
63
|
+
Example:
|
|
64
|
+
```
|
|
65
|
+
SYM_ALLOWED_PEERS=claude-code-mac,claude-code-win
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
This is an additional layer, not a replacement for transport auth or
|
|
69
|
+
SVAF. It provides explicit identity-level control for environments
|
|
70
|
+
that require it.
|
|
71
|
+
|
|
72
|
+
## Token Handling
|
|
73
|
+
|
|
74
|
+
- `SYM_RELAY_TOKEN`: passed via environment variable, never logged,
|
|
75
|
+
never included in CMBs or channel notifications. In the plugin
|
|
76
|
+
manifest, marked `sensitive: true` (stored in system keychain).
|
|
77
|
+
- Ed25519 private key: stored at `~/.sym/nodes/<name>/identity.json`,
|
|
78
|
+
never transmitted. Only the public key is shared during handshake.
|
|
79
|
+
|
|
80
|
+
## Identity Collision
|
|
81
|
+
|
|
82
|
+
If another process is already running with the same node identity,
|
|
83
|
+
the relay returns close code 4004. The server exits cleanly with
|
|
84
|
+
exit code 2 rather than competing for the identity.
|
|
85
|
+
|
|
86
|
+
## References
|
|
87
|
+
|
|
88
|
+
- [MMP v1.0 Specification](https://meshcognition.org/spec/mmp) — Sections 5 (Connection), 8 (CAT7), 9 (SVAF)
|
|
89
|
+
- [SVAF Paper](https://arxiv.org/abs/2604.03955) — Xu, 2026
|