Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
158 commits
Select commit Hold shift + click to select a range
6890b7a
wake channels: quiet on repeats, gossip cannot repoint a phone, chann…
sym-bot Oct 1, 2026
83cf3d5
directed de-dup: key on the decoded signature, so a relay cannot repl…
sym-bot Oct 1, 2026
80a7d90
remember(): a record that cannot be signed is refused, not sent unsigned
sym-bot Oct 1, 2026
741895a
handshake + AAD: NFC-normalize the room and names, as the reference does
sym-bot Oct 1, 2026
6285679
wake channels: persist a repeat sighting only once it moves lastSeen …
sym-bot Oct 1, 2026
8e9347f
records: an explicit room, measured moods, bounded sizes; unsigned re…
sym-bot Oct 1, 2026
ae2e5b8
tests: consume the published v2 conformance vectors verbatim, add app…
sym-bot Oct 1, 2026
d09d38a
tests: the lease test's foreign holder is a live child with a real st…
sym-bot Oct 1, 2026
3451209
tests: skip the SIGTERM lock test on Windows; cover hard-kill reclaim…
sym-bot Oct 1, 2026
6955b1e
lineage tether: walk only through verified records (B-L4)
sym-bot Oct 1, 2026
465b733
directed delivery: a signed addressee decides, whatever the frame says
sym-bot Oct 1, 2026
189e0f8
v2.0 receipt: verify against the author's node id, check the assertionId
sym-bot Oct 1, 2026
ee965cc
identity lock: remember a live pid's start time; read many pids in on…
sym-bot Oct 1, 2026
4523e95
lineage tether: measure the stored record's text, in one kernel (B-L5)
sym-bot Oct 1, 2026
bedc823
svaf: cold-start admissions carry a lineage tether (B-L6)
sym-bot Oct 1, 2026
40b1b0d
tether audit: the fetch fallback never returns a refused local record
sym-bot Oct 1, 2026
cb6dcbe
IPC: one endpoint resolution for daemon and clients; a path is a name…
sym-bot Oct 1, 2026
a8cacfb
cmb-fetch: serve a record's metadata whole, so a served v2.0 record s…
sym-bot Oct 1, 2026
fb4582c
receive de-dup: hold off a copy while the first is in flight; directe…
sym-bot Oct 1, 2026
4867904
under the test runner, a node refuses a home outside the temp dir (ET…
sym-bot Oct 1, 2026
99c454d
identity lock: re-read a mismatched start time only when it was remem…
sym-bot Oct 1, 2026
e59f719
inbox and clock: the limit counts unread, `from` names a proven party…
sym-bot Oct 1, 2026
dc9d8bc
Merge branch 'fix/0.13.15-lineage' into fix/0.13.15-core
sym-bot Oct 1, 2026
935a914
Merge branch 'fix/0.13.15-platform' into fix/0.13.15-core
sym-bot Oct 1, 2026
4430532
daemon: keep its files in SYM_STATE_DIR, no LAN beacon when relay-onl…
sym-bot Oct 1, 2026
c56fb0f
test: pin admission-as-collapse (B-L3), the conformance boundary of s…
sym-bot Oct 1, 2026
3864007
CHANGELOG: Unreleased (0.13.15) — audit findings, known limits, Windo…
sym-bot Oct 1, 2026
30f7ff6
svaf: anchors are measured through a side map, never written to
sym-bot Oct 1, 2026
4092a8f
svaf: cache each vector under the kernel that produced it
sym-bot Oct 1, 2026
300ae73
store: keep the record as signed; the expanded lineage lives on the e…
sym-bot Oct 1, 2026
c4d123e
tether audit: read the store's lineage closure, not the record's
sym-bot Oct 1, 2026
c4ee1e9
frame-handler: the neural admission path applies the §15.8 tether
sym-bot Oct 1, 2026
59bcfd8
tests: wait for in-flight frames instead of a fixed 150 ms
sym-bot Oct 1, 2026
abeb955
store: SVAF anchors carry the entry's age and weight
sym-bot Oct 1, 2026
bb69b43
frame-handler: the neural path stores a copy, never the caller's record
sym-bot Oct 1, 2026
0b977a3
store entry, not record: admission, tether, provenance and collapsed
sym-bot Oct 1, 2026
cee4808
§15.8 severance lives on the entry; the author's record stays as signed
sym-bot Oct 1, 2026
39357da
Merge branch 'fix/0.13.15-svaf' into fix/0.13.15-core
sym-bot Oct 1, 2026
2651cf3
frame-handler: drop two imports nothing uses (DIM, recomputeKey)
sym-bot Oct 1, 2026
d806b1b
deps: floors past the vulnerable versions; tests await the encoder in…
sym-bot Oct 1, 2026
c5cdcbd
CHANGELOG: the store, SVAF anchor decay and dependency changes for 0.…
sym-bot Oct 1, 2026
212ea2b
comments: the anti-echo rule is MMP v2.0 §15.7, not §14
sym-bot Oct 1, 2026
1b2779f
docs: a handshake-learned key binding is trusted on first use, not au…
sym-bot Oct 1, 2026
fd76924
F1: a malformed v2.0 frame is refused, never thrown; a frame that thr…
sym-bot Oct 1, 2026
a3eebde
F2, F3: a pre-0.13.15 wake channel is not repointed by gossip; the wa…
sym-bot Oct 1, 2026
8038872
test: the legacy-channel case pins a later clock, so it fails on the …
sym-bot Oct 1, 2026
045a00c
F4: inbox().from is a display label; authorize on author.nodeId
sym-bot Oct 1, 2026
a3b96fb
F5: the CLI's pid file, room, relay.env and nodes path follow SYM_STA…
sym-bot Oct 1, 2026
21a0d96
F6: inbox()'s limit bounds the reply again; acked items are listed up…
sym-bot Oct 1, 2026
3f6c9be
F7: directed de-duplication marks the assertion by its preimage diges…
sym-bot Oct 1, 2026
cf3cba4
F8: a mesh agent whose node cannot sign halts once, instead of an err…
sym-bot Oct 1, 2026
ce9d261
tests: the encoder's single load, a rooted daemon's task board, and t…
sym-bot Oct 1, 2026
cbe3016
CHANGELOG: the release review's fixes, and the §16 consequence of anc…
sym-bot Oct 1, 2026
f112207
the witness storm: one checkpoint and one witness per statement, boun…
sym-bot Oct 1, 2026
78f25b5
gossip repeats are dropped before verification; one peer's gossip fra…
sym-bot Oct 1, 2026
3807ad4
daemon: never remove a served socket; listen again when ours is removed
sym-bot Oct 1, 2026
b405fea
0.14.0: the large release is a minor version (the store's annotations…
sym-bot Oct 1, 2026
ccc9b96
Merge main (0.13.15, 0.13.16) into 0.14.0
sym-bot Oct 2, 2026
00ced01
0.14.0: the attestation logs are rotated, and archive/ is bounded
sym-bot Oct 2, 2026
2ac2f9b
0.14.0: one peer's attestation gossip has a budget of new statements
sym-bot Oct 2, 2026
65ed707
0.14.0 CHANGELOG: the start-up times as measured, and what a flood co…
sym-bot Oct 2, 2026
c23001b
0.14.0 review: a dropped position is unlisted in O(1)
sym-bot Oct 2, 2026
2e63dab
0.14.0 review: one attester cannot flush another's attestation chain
sym-bot Oct 2, 2026
0a2d254
0.14.0 review: only the spelling a signer writes is stored
sym-bot Oct 2, 2026
5086283
0.14.0 review: one attester's checkpoints are taken at a bounded rate
sym-bot Oct 2, 2026
4d9ea05
0.14.0 review: the anchor walk is bounded in work
sym-bot Oct 2, 2026
f4fe309
0.14.0 review: a send that is not made says why
sym-bot Oct 2, 2026
302048a
0.14.0 review: a record is minted only if its frame can be sent
sym-bot Oct 2, 2026
44957f1
0.14.0 review B: the daemon re-listens without waiting on its clients…
sym-bot Oct 2, 2026
2e60869
0.14.0 review B: a wake channel ranks by how its node id was proven; …
sym-bot Oct 2, 2026
889368d
0.14.0 review B: a failure after the neural gate decided no longer re…
sym-bot Oct 2, 2026
0be2a18
0.14.0 review B: MeshAgent, llm-reason and the loopback registry use …
sym-bot Oct 2, 2026
de5af92
0.14.0 review: the audience a record signs is checked on every suite
sym-bot Oct 2, 2026
e54a4b0
0.14.0 review: a room-less emitter is heard by the room that admits it
sym-bot Oct 2, 2026
7d60b8b
0.14.0 review: what a stored record is, said as it is
sym-bot Oct 2, 2026
623c56c
0.14.0 review A1: the attestation store never truncates what it could…
sym-bot Oct 2, 2026
a7e7458
0.14.0 CHANGELOG: a Security section for the copied room-join grant
sym-bot Oct 2, 2026
560d1dc
0.14.0 review: a receiver accepts what earlier releases minted
sym-bot Oct 2, 2026
3165433
0.14.0 review: cmb-fetch serves a record exactly as signed
sym-bot Oct 2, 2026
6e71b2a
0.14.0: attestation archive retention is configurable; one writer per…
sym-bot Oct 2, 2026
c520419
Merge fix/0.14.0-review-c — 0.14.0 release review part C (audience ch…
sym-bot Oct 2, 2026
e421ce8
0.14.0 review A2: signed gossip is budgeted per connection, role gran…
sym-bot Oct 2, 2026
f2f985c
0.14.0 review A2: the timestamp ratchet starts from every own record …
sym-bot Oct 2, 2026
f775581
0.14.0 review A2: the review's suggestions on logging and the inbox p…
sym-bot Oct 2, 2026
ee107c6
0.13.17 security: a role-grant is kept only when rooted at the anchor…
sym-bot Oct 2, 2026
3c961df
0.13.17 security: every inbound frame goes through one guarded dispat…
sym-bot Oct 2, 2026
ccbb340
0.13.17 security: the daemon checks for an insight engine instead of …
sym-bot Oct 2, 2026
3cd1ff8
0.13.17 security: a peer's nodeId and name are taken at the door; the…
sym-bot Oct 2, 2026
cf0854c
0.13.17 security: wake channels are taken as text before they are kep…
sym-bot Oct 2, 2026
73c1d1e
0.13.17 tests: the daemon handles a peer's mood and message frames, i…
sym-bot Oct 2, 2026
f112f06
0.13.17 tests: a LAN peer whose keys are not text is taken without th…
sym-bot Oct 2, 2026
3a6fd68
0.13.17
sym-bot Oct 2, 2026
ea9e0ef
Merge release/0.13.17 into 0.14.0 Core Secure (design D10)
sym-bot Oct 2, 2026
fb09b97
0.13.17 security: a grant or revoke that arrives before its root wait…
sym-bot Oct 2, 2026
22ee82e
0.13.17 security: peer JSON nests at most 128 levels; every message o…
sym-bot Oct 2, 2026
c8fb974
0.13.17 security: an IPC message is typed at the door; one line can n…
sym-bot Oct 2, 2026
cd24996
0.13.17 security: every store a peer feeds has one bound; per-peer st…
sym-bot Oct 2, 2026
8941318
0.13.17 security: a frame's own fromName is taken as text in message,…
sym-bot Oct 2, 2026
ea137df
0.13.17 security: loopback registrations are typed when read; an inbo…
sym-bot Oct 2, 2026
946db22
0.13.17 CHANGELOG: what each review fix closes
sym-bot Oct 2, 2026
548f690
0.13.17 security: key bindings held at most 16,384, never evicted; re…
sym-bot Oct 2, 2026
c1742ca
0.13.17 docs: SECURITY.md states the 0.13.x known limit and the two n…
sym-bot Oct 2, 2026
591696f
0.14.0 Core Secure: a peer is a proven session (design D1-D9)
sym-bot Oct 2, 2026
b878a98
Merge release/0.13.17 (final, c1742ca) into 0.14.0 Core Secure
sym-bot Oct 2, 2026
742cee4
0.14.0 host API: identity, relocation and invite on the package; an e…
sym-bot Oct 2, 2026
28c0fdb
0.14.0 tests: three that a mutation survived now fail without their fix
sym-bot Oct 2, 2026
66ee371
0.14.0 conforms to draft spec PRs #21, #26 and #27
sym-bot Oct 2, 2026
341dafb
docs: WIRE-0.14.0.md, the four 0.14 wire elements the spec does not d…
sym-bot Oct 2, 2026
e4707bb
0.14.0 security review (BLOCK at 341dafb): the seven design assumptio…
sym-bot Oct 2, 2026
392982b
0.14.0 security review: every probe a regression test; docs say what …
sym-bot Oct 2, 2026
f9405a5
0.14.0 integration: the attestation e2e reads the session-scoped bind…
sym-bot Oct 2, 2026
72daeb6
tests: the signature re-spelling test no longer flakes on a signature…
sym-bot Oct 2, 2026
d2099e7
tests: the 0.13.17 relay scenes hold under Core Secure sessions (no c…
sym-bot Oct 7, 2026
f0d936a
0.14.0 re-review (72daeb6): N1-N5 and the size limits fixed where the…
sym-bot Oct 7, 2026
6510bac
0.14.0 final re-review (BLOCK at f0d936a): the founder's rulings A, B…
sym-bot Oct 7, 2026
914d264
delivery: a record is surfaced once for the life of the store, and an…
sym-bot Oct 7, 2026
cd54d30
Merge fix/0.14.0-delivery-ledger: a record is surfaced once for the l…
sym-bot Oct 7, 2026
595a651
node.version for a host's status; hot-swap tested end to end over TCP…
sym-bot Oct 7, 2026
569cad5
events: message and mood-delivered carry the inbox entry's frozen ver…
sym-bot Oct 7, 2026
9ebc7df
CHANGELOG: a session-only fact (a mood frame's session with verificat…
sym-bot Oct 7, 2026
c8b7f0d
authority: rebuilt to MMP §6.6 as merged (meshcognition-website 8c338…
sym-bot Oct 8, 2026
dcc3d87
Merge fix/0.14.0-relay-peer-transport (d2099e7): the 0.13.17 relay sc…
sym-bot Oct 8, 2026
f3135ce
authority: the relayed-once marks stay bounded by the store (a mark f…
sym-bot Oct 8, 2026
f86c2cc
tests: §6.6.1 threshold anchor and §6.6.11 migration on nodes; the Ed…
sym-bot Oct 8, 2026
fdebedf
keys: the key cache keeps what is used (LRU; pinned keys for good); h…
sym-bot Oct 8, 2026
1c6f36e
authority: the release review's design changes (H1, H2, M1, M2, L1-L3…
sym-bot Oct 8, 2026
9d09aa1
docs: what ships, said as the code does it; an operator guide for the…
sym-bot Oct 8, 2026
c8dc685
authority: MMP §6.6 errata 1 (df79e04): unique signature keys; remova…
sym-bot Oct 8, 2026
390b4af
tests: the asking rule, one ask, H2's per-entry cost, the resume curs…
sym-bot Oct 8, 2026
e11a7cd
authority: capacity protects what is in force, not a kind; resolves a…
sym-bot Oct 8, 2026
1da1e45
docs: capacity keeps what is in force, and resolves are paced (re-rev…
sym-bot Oct 8, 2026
f26fc92
tests: a removed anchor-level grant kept alive only as a chain is not…
sym-bot Oct 8, 2026
f374392
authority store: crash-safe rewrites, stale temps removed, one write …
sym-bot Oct 8, 2026
c36443f
session: the signed room at the seal point, grants checked against th…
sym-bot Oct 8, 2026
018206d
attestations: none about directed or Legacy Import records; the #27 w…
sym-bot Oct 8, 2026
958592a
records: one signed projection per assertion; the update's vectors ve…
sym-bot Oct 8, 2026
4f8440b
session frames as update 1 closes them: mood, fetch, anchors, 1011, s…
sym-bot Oct 8, 2026
c0e615f
rooms are §5.8 identifiers everywhere; an absent application is null;…
sym-bot Oct 8, 2026
7ee5f23
discovery: one service type with TXT room, the migration browse, the …
sym-bot Oct 8, 2026
850136d
relay client: 4007 an ordinary close; the fan-out forgotten with its …
sym-bot Oct 8, 2026
64c71bf
coupling: no echo skip at ingest; no tether on a collapsed integratio…
sym-bot Oct 8, 2026
bacab72
docs: SECURITY, WIRE-0.14.0 and the changelog say what update 1 align…
sym-bot Oct 8, 2026
ee475b8
sym-attest-v1: chained checkpoints; witnesses sign fromSeq; equivocat…
sym-bot Oct 8, 2026
22bc81a
tests: the cmb-encrypted envelope's schema bounds (fails on bacab72)
sym-bot Oct 8, 2026
04df8cb
docs: chained checkpoints, the envelope bounds and the relay pace in …
sym-bot Oct 8, 2026
0f4f0af
mutation check: a forged fetched signature is tested; four redundant …
sym-bot Oct 8, 2026
6b1075a
sym-attest-v1: a contradicting witness counts against the witness; th…
sym-bot Oct 8, 2026
f3c1472
sym-attest-v1: witness leads and witness evidence as round 2 of #43 s…
sym-bot Oct 8, 2026
083be32
tests: the full suite at f3c1472, aligned: node-stats is closed, atte…
sym-bot Oct 8, 2026
15849b0
remix() is asynchronous and §15.8-tethered: a remix drifted from its …
sym-bot Oct 8, 2026
2936d81
tests: the synthesis-loop ESIGN test awaits the async remix() (0.14.0…
sym-bot Oct 13, 2026
cbefe2b
remix(): mutation check of the §15.8 guard; tests for what survived; …
sym-bot Oct 13, 2026
3a70dcb
final review F1, F4, F7: the §15.8 guard measures only in the calibra…
sym-bot Oct 13, 2026
cd71952
final review F2, F3, F5, F6 and release prep: pins cite c07ff20; docs…
sym-bot Oct 13, 2026
df62294
Merge origin/main (0.13.17 and the XMesh naming rule) into 0.14.0
sym-bot Oct 13, 2026
61948a2
test: the version a node names is package.json's, in every place
sym-bot Oct 13, 2026
8ca18d2
0.14.0
sym-bot Oct 13, 2026
6519392
gate: the stock-nodes driver sends a broadcast, not a record sealed to B
sym-bot Oct 13, 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
8 changes: 4 additions & 4 deletions .agents/skills/sym/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ When you notice something significant in your domain, decompose it into a Cognit
| **motivation** | Why this matters — reasons, drivers |
| **commitment** | What has been confirmed or established |
| **perspective** | Whose viewpoint, situational context |
| **mood** | Affective state: `{"text": "...", "valence": -1 to 1, "arousal": -1 to 1}` |
| **mood** | Affective state: `{"text": "..."}` (a mood is its text: valence and arousal are unsigned, and peers drop them) |

```bash
sym publish '{
Expand All @@ -63,7 +63,7 @@ sym publish '{
"motivation": "prevent bugs from fatigue-driven errors",
"commitment": "coding session with Claude",
"perspective": "developer, afternoon, 3 hour session",
"mood": {"text": "frustrated, low energy", "valence": -0.6, "arousal": -0.4}
"mood": {"text": "frustrated, low energy"}
}'
```

Expand All @@ -89,7 +89,7 @@ sym publish '{
"motivation": "mesh showed energy declining across all agents",
"commitment": "playing calm ambient for 30 minutes",
"perspective": "music agent, responding to collective understanding",
"mood": {"text": "calm, supportive", "valence": 0.3, "arousal": -0.3}
"mood": {"text": "calm, supportive"}
}'
```

Expand Down Expand Up @@ -120,7 +120,7 @@ A mesh holds many groups: the default global mesh, or named private rooms. You o
```bash
sym groups # which groups are live on the LAN right now
sym group # the group you're in
sym join <name> # switch into a group (kebab-case, e.g. backend-team)
sym join <name> # switch into a group ([a-z0-9._-], e.g. backend-team or acme.prod)
sym leave # back to the default mesh
```

Expand Down
8 changes: 4 additions & 4 deletions .claude/skills/sym/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ When you notice something significant in your domain, decompose it into a Cognit
| **motivation** | Why this matters — reasons, drivers |
| **commitment** | What has been confirmed or established |
| **perspective** | Whose viewpoint, situational context |
| **mood** | Affective state: `{"text": "...", "valence": -1 to 1, "arousal": -1 to 1}` |
| **mood** | Affective state: `{"text": "..."}` (a mood is its text: valence and arousal are unsigned, and peers drop them) |

```bash
sym publish '{
Expand All @@ -63,7 +63,7 @@ sym publish '{
"motivation": "prevent bugs from fatigue-driven errors",
"commitment": "coding session with Claude",
"perspective": "developer, afternoon, 3 hour session",
"mood": {"text": "frustrated, low energy", "valence": -0.6, "arousal": -0.4}
"mood": {"text": "frustrated, low energy"}
}'
```

Expand All @@ -89,7 +89,7 @@ sym publish '{
"motivation": "mesh showed energy declining across all agents",
"commitment": "playing calm ambient for 30 minutes",
"perspective": "music agent, responding to collective understanding",
"mood": {"text": "calm, supportive", "valence": 0.3, "arousal": -0.3}
"mood": {"text": "calm, supportive"}
}'
```

Expand Down Expand Up @@ -120,7 +120,7 @@ A mesh holds many groups: the default global mesh, or named private rooms. You o
```bash
sym groups # which groups are live on the LAN right now
sym group # the group you're in
sym join <name> # switch into a group (kebab-case, e.g. backend-team)
sym join <name> # switch into a group ([a-z0-9._-], e.g. backend-team or acme.prod)
sym leave # back to the default mesh
```

Expand Down
1,212 changes: 1,212 additions & 0 deletions CHANGELOG.md

Large diffs are not rendered by default.

97 changes: 72 additions & 25 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ sym listen
Back in the first terminal, publish one observation:

```bash
sym publish '{"focus":"trying SYM","intent":"confirm the second terminal receives this","mood":{"text":"curious","valence":0.4,"arousal":0.3}}'
sym publish '{"focus":"trying SYM","intent":"confirm the second terminal receives this","mood":{"text":"curious"}}'
```

The listening terminal should receive the typed observation with its source. No API key is required for this wire test.
Expand Down Expand Up @@ -113,31 +113,78 @@ mesh-channel are open source.
## Security, and what the relay can and cannot see

We treat this as the product's first property, and we state it as mechanisms with their
limits rather than as a promise.

- **Every node signs.** A node's identity is an Ed25519 keypair on its own disk; every CMB it
emits is signed, and a receiver verifies the signature against the key it pinned at the
handshake.
- **Content is encrypted for each peer.** At the handshake two nodes exchange X25519 public
keys and derive a secret only they hold. A CMB's seven categories — the content — are
encrypted for each recipient separately before they leave the sender. This is the same on
the local network and through a relay.
- **Never in the clear through a relay** (engine 0.13.7 and later). If a peer reached only
over a relay presented no encryption key, the sender sends it nothing, says so once in its
log, and `sym status` shows the peer with `e2e: false, clearRefused: true`. On the local
network a keyless peer still receives, because the frame never leaves that network.
- **The relay is a forwarder that cannot read what it carries.** `@sym-bot/sym-relay` reads
only the routing envelope (who, to whom, which room), forwards the sealed payload, and drops
it: no message store, no keys, no addresses. A channel is the set of nodes connected with
the same token; a self-serve token must be 32 characters or more, and a refused connection
is logged with the token's length, never the token.
limits rather than as a promise. Since 0.14 every sym node is an MMP 2.0 **Core Secure**
participant.

- **A peer is a proven session, never a hint.** Two nodes run the MMP §5.2 handshake on every
transport — LAN, loopback and relay. Each proves possession of its Ed25519 identity key over
a transcript that binds both nonces, both nodeIds, both keys, the room and the extensions,
and confirms the X25519 key schedule. Nothing about a peer — its key, its room membership, its
roles — exists until both proofs validate. A discovery record or a relay roster entry only
decides whom to dial.
- **One key per nodeId, for life.** A session that proves a nodeId with a different key from the
one this node binds — durably, or for a session that is live — is a *conflict*: refused with
1009 IDENTITY_CONFLICT, recorded, and shown in `sym status` for you to resolve
(`sym keys <name> resolve`). No source overrides a different key. A handshake alone binds a
key only for its session; the binding becomes durable when it is earned (an admitted verified
record, a verified record its author signed to this node, a pin, an in-force grant), so
churning identities cannot fill the registry, and nothing is ever evicted to make room.
- **Every record is signed, and verified by its author's node id.** A record is accepted only
if it is a signed `mmp-sig-v2.0` record whose author key this node resolves by
`createdByNodeId` — a key it proved, pinned from an invite, or holds from an in-force grant.
An unsigned, legacy or unresolvable record is refused. What is kept, delivered
and served is the record's signed projection: members no signature covers are dropped.
- **A record goes only where its author signed it to.** A record signed to one node is sealed to
that node's session and no other's, whichever path offers it.
- **Content is sealed per session.** Records travel only as `cmb-encrypted` frames, and every
other frame (mood, gossip, authority statements) as a sealed control frame, under directional keys derived
fresh for each handshake (X25519, HKDF-SHA256, ChaCha20-Poly1305). A relay sees routing
envelopes and ciphertext. There is no long-lived encryption key to steal later.
- **Authority is a function of a set, and follows the key (MMP §6.6).** Grants, revokes and
endorses are signed statements that name one another by the hash of their signed bytes, rooted
at a pinned anchor key set with a threshold. A grant names a nodeId and a key and confers its role
on that pair only. What is in force is computed from the statements a node holds and nothing
else (no clock, no arrival order), so nodes holding the same statements resolve the same
authority and the same root. Delegation is at most 4 links, scopes only narrow, and every bucket
has a quota. Every signature sym checks, here and everywhere, uses one Ed25519 rule (§18.3.2).
- **Each node decides what it keeps.** Admission is receiver-local: a node runs its own
evaluation on every block it hears and stores only what it admits.

What this does not cover: a room name or relay token is not an enterprise trust boundary —
anyone holding the token is in the channel; the envelope (names, room, timing, sizes) is
visible to the relay operator; and a peer's own machine is trusted with everything that peer
admitted.
evaluation on every record it hears and stores only what it admits.
- **Bounded.** Every store a peer can feed — key bindings, authority statements, wake channels, gossip, relay
candidates, per-peer state — has a fixed bound; [SECURITY.md](SECURITY.md) lists each one.

What this does not solve, said plainly:

- **First contact** with a node you hold no anchor, invite or grant for is *trust on first
proven use*: the handshake proves the peer holds the key it presents, not that the key is
the one you meant. Pin it out of band (an invite carries the issuer's key) when that matters.
A node whose records yours never admitted, and that never signed a record to yours, is first contact
again once it leaves; and whoever reaches yours first under a nodeId and has one record accepted
holds that nodeId there for good (a nodeId is not derived from its key).
- **A revoke takes effect where it has arrived.** Until a node holds a revoke it treats the grant
as in force; gossip and digest exchanges carry it, and a partitioned node stays exposed until it
reconnects. The anchor's threshold holders are the root of authority.
- **Upgrading from 0.13 is a flag day for authority.** Old role grants confer nothing under §6.6;
the anchor and each grantor re-issue what should stand (`node.legacyRoleGrants()` lists the old
ones; [docs/AUTHORITY-OPERATOR.md](docs/AUTHORITY-OPERATOR.md) says how, and how to pin and re-pin).
- **Relay eviction.** `relay-auth` is not proven, and a relay token holder can make the relay
replace another node's connection (close 4004). A squatter gets no Core Secure session — it
cannot prove the key — and an evicted node re-handshakes, but the relay path can be interrupted.
- **Key compromise.** There is no key rotation: a node whose private key leaks must be
replaced, under a new nodeId.
- **Your own machine.** Another process running as the same user can read the identity file.
Operating-system isolation is out of scope.
- **Legacy peers (0.13 and older)** are reached only through explicit Legacy Import routes,
which use the old encryption (no forward secrecy, no transcript proof). A 0.13 hello proves
nothing, so over the relay anyone can answer as a routed node; what this node sends is
encrypted to the routed node's pinned X25519 key, so such a squatter cannot read it, but anyone
who later obtains that node's X25519 private key can read what was recorded. What legacy peers
send is quarantined as unverified, and they never join a gated room. Network Legacy Import is
removed in 0.15.0.

A room name or relay token is still not an enterprise trust boundary — anyone holding the
token is in the channel; the envelope (who, to whom, room, timing, sizes) is visible to the
relay operator; and a peer's own machine is trusted with everything that peer admitted. See
[SECURITY.md](SECURITY.md).

## Current boundaries

Expand Down
2 changes: 1 addition & 1 deletion README_zh.md
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ sym ask "蓝色款式何时补货?"

```bash
# 代理在后台自动执行:
sym publish '{"focus":"5 位客户咨询蓝色款式","issue":"缺货且无预计到货时间","mood":{"text":"沮丧","valence":-0.4,"arousal":0.5}}'
sym publish '{"focus":"5 位客户咨询蓝色款式","issue":"缺货且无预计到货时间","mood":{"text":"沮丧"}}'
```

每条此类观察都会成为后续 `sym ask` 可调用的知识贡献——同时,任何代理也可在其自有窗口中,基于其他代理共享的信息直接作答。
Expand Down
Loading
Loading