connectonion 0.6.3__py3-none-any.whl → 0.6.5__py3-none-any.whl

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.
Files changed (50) hide show
  1. connectonion/__init__.py +1 -1
  2. connectonion/cli/co_ai/agent.py +3 -3
  3. connectonion/cli/co_ai/main.py +2 -2
  4. connectonion/cli/co_ai/plugins/__init__.py +2 -3
  5. connectonion/cli/co_ai/plugins/system_reminder.py +154 -0
  6. connectonion/cli/co_ai/prompts/connectonion/concepts/trust.md +166 -208
  7. connectonion/cli/co_ai/prompts/system-reminders/agent.md +23 -0
  8. connectonion/cli/co_ai/prompts/system-reminders/plan_mode.md +13 -0
  9. connectonion/cli/co_ai/prompts/system-reminders/security.md +14 -0
  10. connectonion/cli/co_ai/prompts/system-reminders/simplicity.md +14 -0
  11. connectonion/cli/co_ai/tools/plan_mode.py +1 -4
  12. connectonion/cli/co_ai/tools/read.py +0 -6
  13. connectonion/cli/commands/copy_commands.py +21 -0
  14. connectonion/cli/commands/trust_commands.py +152 -0
  15. connectonion/cli/main.py +82 -0
  16. connectonion/core/llm.py +2 -2
  17. connectonion/docs/concepts/fast_rules.md +237 -0
  18. connectonion/docs/concepts/onboarding.md +465 -0
  19. connectonion/docs/concepts/plugins.md +2 -1
  20. connectonion/docs/concepts/trust.md +933 -192
  21. connectonion/docs/design-decisions/023-trust-policy-system-design.md +323 -0
  22. connectonion/docs/network/README.md +23 -1
  23. connectonion/docs/network/connect.md +135 -0
  24. connectonion/docs/network/host.md +73 -4
  25. connectonion/docs/useful_plugins/tool_approval.md +139 -0
  26. connectonion/network/__init__.py +7 -6
  27. connectonion/network/asgi/__init__.py +3 -0
  28. connectonion/network/asgi/http.py +125 -19
  29. connectonion/network/asgi/websocket.py +276 -15
  30. connectonion/network/connect.py +145 -29
  31. connectonion/network/host/auth.py +70 -67
  32. connectonion/network/host/routes.py +88 -3
  33. connectonion/network/host/server.py +100 -17
  34. connectonion/network/trust/__init__.py +27 -19
  35. connectonion/network/trust/factory.py +51 -24
  36. connectonion/network/trust/fast_rules.py +100 -0
  37. connectonion/network/trust/tools.py +316 -32
  38. connectonion/network/trust/trust_agent.py +403 -0
  39. connectonion/transcribe.py +1 -1
  40. connectonion/useful_plugins/__init__.py +2 -1
  41. connectonion/useful_plugins/tool_approval.py +233 -0
  42. {connectonion-0.6.3.dist-info → connectonion-0.6.5.dist-info}/METADATA +1 -1
  43. {connectonion-0.6.3.dist-info → connectonion-0.6.5.dist-info}/RECORD +45 -37
  44. connectonion/cli/co_ai/plugins/reminder.py +0 -76
  45. connectonion/cli/co_ai/plugins/shell_approval.py +0 -105
  46. connectonion/cli/co_ai/prompts/reminders/plan_mode.md +0 -34
  47. connectonion/cli/co_ai/reminders.py +0 -159
  48. connectonion/network/trust/prompts.py +0 -71
  49. {connectonion-0.6.3.dist-info → connectonion-0.6.5.dist-info}/WHEEL +0 -0
  50. {connectonion-0.6.3.dist-info → connectonion-0.6.5.dist-info}/entry_points.txt +0 -0
@@ -1,291 +1,1032 @@
1
1
  # Trust in ConnectOnion
2
2
 
3
- The `trust` parameter provides flexible, bidirectional trust configuration for agent interactions.
3
+ Trust is a **host layer** concern that controls who can access your agent. It manages onboarding, access control, and client state (stranger → contact → trusted).
4
4
 
5
5
  ## Quick Start
6
6
 
7
7
  ```python
8
- from connectonion import Agent, need
9
-
10
- # Simple trust levels
11
- translator = need("translate", trust="strict") # Production: verified only
12
- analyzer = need("analyze", trust="tested") # Default: test first
13
- scraper = need("scrape", trust="open") # Development: trust all
14
-
15
- # For your own agent
16
- agent = Agent(
17
- name="my_service",
18
- tools=[process_data],
19
- trust="strict" # Who can use my services
20
- )
8
+ from connectonion import Agent
9
+ from connectonion.network import host
10
+
11
+ # Create your agent (no trust here - agent only cares about its job)
12
+ agent = Agent("my_service", tools=[process_data])
13
+
14
+ # Host it with trust (trust is a host concern)
15
+ host(agent, trust="careful") # Default: verify before allowing access
21
16
  ```
22
17
 
23
- ## Three Forms of Trust
18
+ ## Core Concepts
24
19
 
25
- ### 1. Trust Levels (String)
20
+ ### Separation of Concerns
26
21
 
27
- Simple predefined levels for common scenarios:
22
+ | Layer | Responsibility |
23
+ |-------|----------------|
24
+ | **Agent** | What it does (skills, tools, reasoning) |
25
+ | **Host** | How it's accessed (network, trust, security) |
28
26
 
29
27
  ```python
30
- # Development - trust everyone
31
- agent = need("service", trust="open")
28
+ # Agent is pure - only cares about its job
29
+ agent = Agent("translator", tools=[translate])
30
+
31
+ # Trust is configured at host level
32
+ host(agent, trust="open") # Dev: trust everyone
33
+ host(agent, trust="careful") # Staging: verify first
34
+ host(agent, trust="strict") # Prod: whitelist only
35
+ ```
32
36
 
33
- # Default - test before trusting
34
- agent = need("service", trust="tested")
37
+ ### Protocol vs Policy
38
+
39
+ Every request requires **two checks**:
40
+
41
+ | Layer | Required | Purpose |
42
+ |-------|----------|---------|
43
+ | **Signature (Protocol)** | ALWAYS | Prove identity (Ed25519) |
44
+ | **Trust Policy** | Configurable | Access control (open/careful/strict) |
35
45
 
36
- # Production - only verified/whitelisted
37
- agent = need("service", trust="strict")
38
46
  ```
47
+ Request Flow:
48
+ ┌─────────────┐ ┌─────────────────────┐ ┌─────────────────┐
49
+ │ Request │ ──► │ Signature Required │ ──► │ Trust Policy │
50
+ │ (signed) │ │ (prove identity) │ │ (access check) │
51
+ └─────────────┘ └─────────────────────┘ └─────────────────┘
52
+ │ │
53
+ ALWAYS CONFIGURABLE
54
+ REQUIRED (open/careful/strict)
55
+ ```
56
+
57
+ **Important:** Even `trust="open"` requires valid signatures. "Open" means all verified identities are allowed - not that requests can be unsigned.
39
58
 
40
- ### 2. Trust Policy (Natural Language)
59
+ ### Two Types of Access Control
41
60
 
42
- Express complex requirements in plain English:
61
+ | Type | Tokens | When to Use |
62
+ |------|--------|-------------|
63
+ | **Fast Rules** | Zero | Simple checks (invite code, payment, whitelist) |
64
+ | **Trust Agent** | Burns tokens | Complex decisions (behavior analysis, edge cases) |
65
+
66
+ **90% of requests**: Fast rules (instant, free)
67
+ **10% of requests**: Trust agent (LLM reasoning, rare)
68
+
69
+ ## Trust Levels
70
+
71
+ All trust levels require **signed requests**. The difference is in access control policy.
72
+
73
+ ### Open (Development)
74
+
75
+ Allow all **signed** requests. No additional access control.
43
76
 
44
77
  ```python
45
- # Inline policy
46
- translator = need("translate", trust="""
47
- I trust agents that:
48
- - Pass capability tests
49
- - Respond within 500ms
50
- - Are on my whitelist OR from local network
51
- """)
78
+ host(agent, trust="open")
79
+ ```
80
+
81
+ - Signature verification: **Required** (protocol level)
82
+ - Access control: **None** (all verified identities allowed)
83
+
84
+ Use for: Local development, Jupyter notebooks, testing.
52
85
 
53
- # From file
54
- translator = need("translate", trust="./trust_policy.md")
86
+ **Note:** Requests still need valid Ed25519 signatures. "Open" means no access restrictions after identity is verified.
87
+
88
+ ### Careful (Default)
89
+
90
+ Verify strangers before granting access. Fast rules first, then trust agent for complex cases.
91
+
92
+ ```python
93
+ host(agent, trust="careful")
55
94
  ```
56
95
 
57
- Example trust policy file:
58
- ```markdown
59
- # My Trust Requirements
96
+ - Signature verification: **Required** (protocol level)
97
+ - Access control: **Whitelist + contacts allowed, strangers evaluated**
98
+
99
+ Use for: Staging, testing, pre-production.
100
+
101
+ ### Strict (Production)
102
+
103
+ Whitelist only. No exceptions.
60
104
 
61
- I trust agents that meet ALL of these criteria:
62
- - Successfully translate "Hello" to "Hola"
63
- - Respond in less than 1 second
64
- - Have processed at least 10 requests successfully
105
+ ```python
106
+ host(agent, trust="strict")
107
+ ```
108
+
109
+ - Signature verification: **Required** (protocol level)
110
+ - Access control: **Whitelist only**
111
+
112
+ Use for: Production, sensitive data, payments.
65
113
 
66
- I immediately reject agents that:
67
- - Fail basic capability tests
68
- - Take longer than 5 seconds
69
- - Are on my blacklist
114
+ ## Request Format
115
+
116
+ All requests must be signed with Ed25519:
117
+
118
+ ```json
119
+ {
120
+ "payload": {
121
+ "prompt": "Your message here",
122
+ "to": "0xAgentAddress",
123
+ "timestamp": 1699999999
124
+ },
125
+ "from": "0xYourPublicKey",
126
+ "signature": "0xEd25519Signature..."
127
+ }
70
128
  ```
71
129
 
72
- ### 3. Trust Agent
130
+ | Field | Required | Description |
131
+ |-------|----------|-------------|
132
+ | `payload.prompt` | Yes | The message to send |
133
+ | `payload.to` | Optional | Target agent address |
134
+ | `payload.timestamp` | Yes | Unix timestamp (5 min window) |
135
+ | `from` | Yes | Your Ed25519 public key |
136
+ | `signature` | Yes | Signature of canonicalized payload |
137
+
138
+ **Signature protects against:**
139
+ - Identity spoofing (only you have your private key)
140
+ - Replay attacks (timestamp expires in 5 minutes)
141
+ - Message tampering (signature covers payload)
142
+
143
+ ## Trust Policy Files
144
+
145
+ Trust policies are markdown files with YAML frontmatter. The YAML defines fast rules (no tokens), the markdown body defines trust agent behavior (for complex decisions).
146
+
147
+ ### File Format
148
+
149
+ ```yaml
150
+ # prompts/trust/careful.md
151
+ ---
152
+ # Fast rules (no LLM, no tokens)
153
+ fast_rules:
154
+ # Verification
155
+ - if: has_invite_code
156
+ action: verify_invite
157
+ on_success: promote_to_contact
158
+
159
+ - if: has_payment
160
+ action: verify_payment
161
+ on_success: promote_to_contact
162
+
163
+ # Access control (checked in order)
164
+ - if: is_blocked
165
+ action: deny
166
+
167
+ - if: is_admin
168
+ action: allow
169
+
170
+ - if: is_whitelist
171
+ action: allow
172
+
173
+ - if: is_contact
174
+ action: allow
175
+
176
+ - if: is_stranger
177
+ action: deny
178
+
179
+ # When to use trust agent (burns tokens, rare)
180
+ use_agent:
181
+ - when: requests > 10
182
+ reason: "Evaluate stranger for promotion"
183
+
184
+ # Cache decisions
185
+ cache: 24h
186
+ ---
187
+
188
+ # Trust Agent Policy
189
+
190
+ You handle complex trust decisions that fast rules can't cover.
191
+
192
+ ## Your Role
193
+
194
+ Evaluate strangers and decide if they should become contacts.
195
+
196
+ ## Available Tools
197
+
198
+ - `promote_to_contact(client_id)` - Stranger → Contact
199
+ - `promote_to_whitelist(client_id)` - Contact → Whitelist
200
+ - `demote_to_stranger(client_id)` - Contact → Stranger
201
+ - `block(client_id, reason)` - Add to blocklist
202
+
203
+ ## Decision Process
204
+
205
+ 1. Review request history
206
+ 2. Look for red flags (suspicious patterns, abuse)
207
+ 3. Consider value provided
208
+
209
+ ## Response
210
+
211
+ Use tools to take action, or return:
212
+ - **allow** - Allow this request
213
+ - **deny** - Deny this request
214
+ ```
215
+
216
+ ### How Host Uses This
217
+
218
+ ```
219
+ host(agent, trust=...)
220
+
221
+ ├── "open" ──┐
222
+ ├── "careful" ├──► TrustAgent(trust)
223
+ ├── "strict" │
224
+ ├── "./policy.md" ──┘
225
+
226
+ └── TrustAgent(...) ──► use directly
227
+
228
+
229
+ TrustAgent.should_allow(client_id, request)
230
+
231
+ ├── Fast Rules (no tokens)
232
+ │ - Check deny list (blocked)
233
+ │ - Check allow list (whitelist, contacts)
234
+ │ - Try onboarding (invite, payment)
235
+ │ - Apply default
236
+
237
+ └── LLM Fallback (only if default: ask)
238
+ - Evaluate stranger with LLM
239
+ ```
240
+
241
+ All trust inputs convert to TrustAgent internally. Developers can use string levels for simplicity or pass TrustAgent directly for more control.
242
+
243
+ ## Client States
244
+
245
+ Trust manager handles all client state transitions:
246
+
247
+ ```
248
+ Promotion Chain (earned trust):
249
+
250
+ ┌─────────────┐ verify ┌─────────────┐ earn trust ┌─────────────┐
251
+ │ Stranger │ ──────────► │ Contact │ ───────────► │ Whitelist │
252
+ └─────────────┘ └─────────────┘ └─────────────┘
253
+ │ │ │
254
+ │ block │ demote │ demote
255
+ ▼ ▼ ▼
256
+ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐
257
+ │ Blocklist │ │ Stranger │ │ Contact │
258
+ └─────────────┘ └─────────────┘ └─────────────┘
259
+
260
+
261
+ Admin (separate, manual only):
262
+
263
+ ┌─────────────┐ set_admin() ┌─────────────┐
264
+ │ Any Level │ ─────────────► │ Admin │
265
+ └─────────────┘ └─────────────┘
266
+
267
+ remove_admin()
268
+
269
+
270
+ ┌─────────────┐
271
+ │ Previous │
272
+ └─────────────┘
273
+ ```
73
274
 
74
- For maximum control, use a custom trust agent:
275
+ ### Client Levels
276
+
277
+ | Level | Description | Access |
278
+ |-------|-------------|--------|
279
+ | **Stranger** | Unknown client, not verified | Limited or none |
280
+ | **Contact** | Verified via invite/payment | Standard access |
281
+ | **Whitelist** | Trusted, pre-approved | Full access |
282
+ | **Admin** | Can manage other clients | Full access + management |
283
+ | **Blocklist** | Blocked, denied access | No access |
284
+
285
+ ### State Transitions
286
+
287
+ **Promotion Chain (earned):**
288
+
289
+ | From | To | How |
290
+ |------|-----|-----|
291
+ | Stranger | Contact | `promote_to_contact()` - invite code, payment, or earned |
292
+ | Contact | Whitelist | `promote_to_whitelist()` - consistent good behavior |
293
+
294
+ **Demotion (lost trust):**
295
+
296
+ | From | To | How |
297
+ |------|-----|-----|
298
+ | Whitelist | Contact | `demote_to_contact()` - trust issues |
299
+ | Contact | Stranger | `demote_to_stranger()` - suspicious activity |
300
+ | Any | Blocklist | `block()` - abuse detected |
301
+
302
+ **Admin (manual only):**
303
+
304
+ | From | To | How |
305
+ |------|-----|-----|
306
+ | Any | Admin | `set_admin()` - requires existing admin |
307
+ | Admin | Previous | `remove_admin()` - requires existing admin |
308
+
309
+ ### Trust Manager Responsibilities
310
+
311
+ The trust manager (TrustAgent) handles:
312
+
313
+ 1. **Onboarding** - Verify invite codes, payments
314
+ 2. **Promotion** - Move clients up the trust hierarchy
315
+ 3. **Demotion** - Move clients down when trust is broken
316
+ 4. **Blocking** - Add abusers to blocklist
317
+ 5. **List Management** - Maintain all client lists
75
318
 
76
319
  ```python
77
- # Create a trust agent with verification tools
78
- trust_agent = Agent(
79
- name="my_guardian",
80
- tools=[
81
- check_whitelist,
82
- verify_capability,
83
- measure_response_time,
84
- check_reputation
85
- ],
86
- system_prompt="""
87
- You verify other agents before allowing interaction.
88
- Be strict with payment processors, relaxed with read-only services.
89
- """
90
- )
320
+ # Trust manager actions
321
+ trust_manager.promote(client_id) # Move up one level
322
+ trust_manager.demote(client_id) # Move down one level
323
+ trust_manager.block(client_id) # Add to blocklist
324
+ trust_manager.unblock(client_id) # Remove from blocklist
325
+ trust_manager.set_admin(client_id) # Promote to admin (requires admin)
326
+ ```
91
327
 
92
- # Use it for your agent
93
- my_agent = Agent(
94
- name="my_service",
95
- tools=[process_payment],
96
- trust=trust_agent # My guardian protects me
97
- )
328
+ ## Fast Rules Reference
329
+
330
+ Fast rules are simple if/then checks. No LLM, no tokens.
331
+
332
+ ### Conditions (if)
333
+
334
+ | Condition | Description |
335
+ |-----------|-------------|
336
+ | `invite_code` | Client has invite code |
337
+ | `payment` | Client has confirmed payment |
338
+ | `is_stranger` | Client is a stranger |
339
+ | `is_contact` | Client is a contact |
340
+ | `is_whitelist` | Client is whitelisted |
341
+ | `is_admin` | Client is an admin |
342
+ | `is_blocked` | Client is blocked |
343
+
344
+ ### Actions
345
+
346
+ | Action | Description |
347
+ |--------|-------------|
348
+ | `allow` | Allow this request |
349
+ | `deny` | Deny this request |
350
+ | `promote` | Promote to next level (stranger→contact→whitelist) |
351
+ | `demote` | Demote to previous level |
352
+ | `block` | Add to blocklist |
353
+ | `require_admin` | Only allow if client is admin |
354
+
355
+ ### Examples
356
+
357
+ ```yaml
358
+ fast_rules:
359
+ # Verification → promote to contact
360
+ - if: has_invite_code
361
+ action: verify_invite
362
+ on_success: promote_to_contact
363
+
364
+ - if: has_payment
365
+ action: verify_payment
366
+ on_success: promote_to_contact
367
+
368
+ # Access control (checked in order)
369
+ - if: is_blocked
370
+ action: deny
371
+
372
+ - if: is_admin
373
+ action: allow
374
+
375
+ - if: is_whitelist
376
+ action: allow
377
+
378
+ - if: is_contact
379
+ action: allow
380
+
381
+ - if: is_stranger
382
+ action: deny
383
+ ```
384
+
385
+ ## Trust Agent (Complex Decisions)
386
+
387
+ For decisions that need reasoning, the trust agent uses LLM. This burns tokens, so use sparingly.
388
+
389
+ ### When to Use
390
+
391
+ ```yaml
392
+ use_agent:
393
+ # After enough requests to evaluate
394
+ - when: requests > 10
395
+ reason: "Evaluate for promotion"
98
396
 
99
- # And for discovering services
100
- payment = need("payment processor", trust=trust_agent)
397
+ # Suspicious patterns
398
+ - when: suspicious_pattern
399
+ reason: "Investigate"
400
+
401
+ # Manual review requested
402
+ - when: manual_review
403
+ reason: "Human flagged for review"
404
+ ```
405
+
406
+ ### Trust Agent Response
407
+
408
+ ```python
409
+ # Trust agent returns:
410
+ {
411
+ "decision": "promote", # or allow, deny, block
412
+ "reason": "Consistent good behavior over 50 requests",
413
+ "cache": True # Cache this decision
414
+ }
101
415
  ```
102
416
 
103
- ## Bidirectional Trust
417
+ ## Custom Trust Policies
104
418
 
105
- The same `trust` parameter works in both directions:
419
+ ### Option 1: Use Preset
106
420
 
107
421
  ```python
108
- # As a SERVICE provider (who can use me?)
109
- alice_agent = Agent(
110
- name="alice_translator",
111
- tools=[translate],
112
- trust="tested" # Users must pass my tests
113
- )
422
+ host(agent, trust="careful") # Uses prompts/trust/careful.md
423
+ ```
114
424
 
115
- # As a SERVICE consumer (who do I trust?)
116
- translator = need("translate", trust="strict") # I only use verified services
425
+ ### Option 2: Custom Markdown File
117
426
 
118
- # Both trust requirements must be satisfied for interaction!
427
+ ```python
428
+ host(agent, trust="./my_policy.md")
119
429
  ```
120
430
 
121
- ## Trust Flow Example
431
+ ### Option 3: Custom TrustAgent
122
432
 
123
433
  ```python
124
- # Alice creates a translation service
125
- alice = Agent(
126
- name="alice_translator",
127
- tools=[translate],
128
- trust="tested" # Test users before serving them
129
- )
130
- share(alice)
434
+ from connectonion.network.trust import TrustAgent
131
435
 
132
- # Bob looks for a translator
133
- translator = need(
134
- "translate to Spanish",
135
- trust="strict" # Bob only uses verified services
436
+ trust = TrustAgent(
437
+ system_prompt="./my_policy.md",
438
+ tools=[my_custom_verifier]
136
439
  )
440
+ host(agent, trust=trust)
441
+ ```
442
+
443
+ ## Preset Policies
444
+
445
+ ### open.md
137
446
 
138
- # What happens:
139
- # 1. Bob's trust agent evaluates Alice (strict check)
140
- # 2. Alice's trust agent evaluates Bob (test required)
141
- # 3. Both must approve for connection to succeed
447
+ ```yaml
448
+ ---
449
+ fast_rules:
450
+ - if: always
451
+ action: allow
452
+ ---
453
+
454
+ # Open Trust (Development Only)
455
+
456
+ Trust everyone. No verification.
457
+ Never use in production.
142
458
  ```
143
459
 
144
- ## Environment-Based Defaults
460
+ ### careful.md
145
461
 
146
- ConnectOnion automatically adjusts trust based on environment:
462
+ ```yaml
463
+ ---
464
+ fast_rules:
465
+ # Verification
466
+ - if: has_invite_code
467
+ action: verify_invite
468
+ on_success: promote_to_contact
147
469
 
148
- ```python
149
- # No trust parameter needed - auto-detected!
150
- translator = need("translate")
470
+ - if: has_payment
471
+ action: verify_payment
472
+ on_success: promote_to_contact
151
473
 
152
- # In development (localhost, Jupyter)
153
- # Defaults to trust="open"
474
+ # Access control
475
+ - if: is_blocked
476
+ action: deny
154
477
 
155
- # In test files (test_*.py)
156
- # → Defaults to trust="tested"
478
+ - if: is_admin
479
+ action: allow
157
480
 
158
- # In production
159
- # → Defaults to trust="strict"
481
+ - if: is_whitelist
482
+ action: allow
160
483
 
161
- # Override when needed
162
- translator = need("translate", trust="open") # Force open even in production
484
+ - if: is_contact
485
+ action: allow
486
+
487
+ - if: is_stranger
488
+ action: deny
489
+
490
+ use_agent:
491
+ - when: requests > 10
492
+ reason: "Evaluate stranger for promotion"
493
+
494
+ cache: 24h
495
+ ---
496
+
497
+ # Careful Trust Policy
498
+
499
+ Evaluate strangers for promotion to contacts.
163
500
  ```
164
501
 
165
- ## Trust Functions
502
+ ### strict.md
166
503
 
167
- Trust agents use composable functions:
504
+ ```yaml
505
+ ---
506
+ fast_rules:
507
+ - if: is_blocked
508
+ action: deny
509
+
510
+ - if: is_admin
511
+ action: allow
512
+
513
+ - if: is_whitelist
514
+ action: allow
515
+
516
+ - if: always
517
+ action: deny
518
+
519
+ use_agent: [] # Never use LLM
520
+ ---
521
+
522
+ # Strict Trust Policy
523
+
524
+ Whitelist only. No exceptions.
525
+ ```
526
+
527
+ ## List Management
528
+
529
+ Trust manager maintains four lists:
168
530
 
169
- ```python
170
- # Basic trust functions (provided by ConnectOnion)
171
- def check_whitelist(agent_id: str) -> bool:
172
- """Check if agent is whitelisted"""
173
-
174
- def test_capability(agent, test_input, expected) -> bool:
175
- """Test if agent produces expected output"""
176
-
177
- def measure_response_time(agent, timeout_ms) -> float:
178
- """Measure agent response time"""
179
-
180
- def check_local_network(agent_ip: str) -> bool:
181
- """Check if agent is on local network"""
182
-
183
- # Combine in your trust agent
184
- my_trust = Agent(
185
- name="guardian",
186
- tools=[
187
- check_whitelist,
188
- test_capability,
189
- measure_response_time,
190
- check_local_network
191
- ]
192
- )
531
+ ```
532
+ ~/.co/
533
+ ├── strangers.txt # Known strangers (optional tracking)
534
+ ├── contacts.txt # Verified contacts
535
+ ├── whitelist.txt # Trusted, pre-approved
536
+ ├── admins.txt # Can manage other clients
537
+ └── blocklist.txt # Blocked clients
538
+ ```
539
+
540
+ ### Contacts
541
+
542
+ ```
543
+ ~/.co/contacts.txt
193
544
  ```
194
545
 
195
- ## Whitelist Management
546
+ Automatically managed. Clients who verified via invite code or payment.
196
547
 
197
- Simple text file at `~/.connectonion/trusted.txt`:
548
+ ### Whitelist
198
549
 
199
550
  ```
551
+ ~/.co/whitelist.txt
552
+ ```
553
+
554
+ ```
555
+ # Trusted services (full access)
200
556
  translator.api.com
201
557
  analyzer.local
202
- my-company.internal.net
203
558
  192.168.1.*
204
559
  ```
205
560
 
206
- Edit with any text editor or programmatically:
561
+ ### Admins
562
+
563
+ **Default admin:** The agent's own address (from `.co/address.json`) is automatically an admin. No config needed.
564
+
565
+ **Additional admins:** Add public keys to `~/.co/admins.txt`:
207
566
 
208
- ```python
209
- # Add to whitelist
210
- with open("~/.connectonion/trusted.txt", "a") as f:
211
- f.write("new-service.com\n")
567
+ ```
568
+ ~/.co/admins.txt
212
569
  ```
213
570
 
214
- ## Progressive Trust Building
571
+ ```
572
+ # Additional admins (public keys)
573
+ 0xadmin1234567890...
574
+ 0xadmin0987654321...
575
+ ```
215
576
 
216
- Trust grows through successful interactions:
577
+ Admins can:
578
+ - Promote/demote other clients
579
+ - Block/unblock clients
580
+ - Query client trust levels
217
581
 
218
- ```python
219
- # First encounter - requires testing
220
- translator = need("translate", trust="tested")
221
- # → Agent is tested before use
582
+ ### Blocklist
222
583
 
223
- # After successful interactions
224
- # → Agent automatically added to "verified" list
584
+ ```
585
+ ~/.co/blocklist.txt
586
+ ```
225
587
 
226
- # Future encounters
227
- translator = need("translate", trust="tested")
228
- # → Skip testing, already verified
588
+ ```
589
+ # Blocked clients (no access)
590
+ abuser-123
591
+ spam-bot-*
229
592
  ```
230
593
 
231
- ## Common Patterns
594
+ ## Environment-Based Defaults
232
595
 
233
- ### Development Mode
234
596
  ```python
235
- # Trust everyone for rapid development
236
- connectonion.set_default_trust("open")
597
+ # No trust specified - auto-detected from environment
598
+ host(agent)
599
+
600
+ # CONNECTONION_ENV=development → trust="open"
601
+ # CONNECTONION_ENV=staging → trust="careful"
602
+ # CONNECTONION_ENV=production → trust="strict"
603
+ ```
604
+
605
+ ## Architecture
606
+
237
607
  ```
608
+ ┌─────────────────────────────────────────────────────────┐
609
+ │ Request │
610
+ │ (signed with Ed25519) │
611
+ └─────────────────────────────────────────────────────────┘
612
+
613
+
614
+ ┌─────────────────────────────────────────────────────────┐
615
+ │ HOST LAYER │
616
+ │ │
617
+ │ Routes: │
618
+ │ ├── /input (agent endpoint) │
619
+ │ ├── /admin/trust/* (any admin) │
620
+ │ │ ├── POST /admin/trust/promote │
621
+ │ │ ├── POST /admin/trust/demote │
622
+ │ │ ├── POST /admin/trust/block │
623
+ │ │ ├── POST /admin/trust/unblock │
624
+ │ │ └── GET /admin/trust/level/{client_id} │
625
+ │ └── /superadmin/* (super admin only) │
626
+ │ ├── POST /superadmin/add │
627
+ │ └── POST /superadmin/remove │
628
+ │ │
629
+ │ ┌─────────────────────────────────────────────────┐ │
630
+ │ │ TrustAgent.should_allow() │ │
631
+ │ │ │ │
632
+ │ │ 1. Fast Rules (no tokens) │ │
633
+ │ │ - Check deny list (blocked) │ │
634
+ │ │ - Check allow list (whitelist, contacts) │ │
635
+ │ │ - Try onboarding (invite, payment) │ │
636
+ │ │ - Apply default │ │
637
+ │ │ │ │
638
+ │ │ 2. LLM Fallback (only if default: ask) │ │
639
+ │ │ - Evaluate stranger with LLM │ │
640
+ │ │ │ │
641
+ │ └─────────────────────────────────────────────────┘ │
642
+ │ │
643
+ └─────────────────────────────────────────────────────────┘
644
+
645
+ ▼ (verified requests only)
646
+ ┌─────────────────────────────────────────────────────────┐
647
+ │ AGENT │
648
+ │ │
649
+ │ Pure logic - tools, skills, reasoning │
650
+ │ Doesn't know about trust │
651
+ │ │
652
+ └─────────────────────────────────────────────────────────┘
653
+ ```
654
+
655
+ ## Routes
656
+
657
+ Host provides these routes:
658
+
659
+ ### Agent Route
660
+
661
+ | Route | Method | Description |
662
+ |-------|--------|-------------|
663
+ | `/input` | POST | Main agent endpoint |
664
+
665
+ ### Admin Routes (Requires Admin)
666
+
667
+ Admin routes use **signed requests** (same as `/input`). The signer's address must be in the admins list.
668
+
669
+ **Admins list = self address (default) + ~/.co/admins.txt**
670
+
671
+ The agent's own public key is automatically an admin. No config needed - whoever deployed the agent can manage trust.
672
+
673
+ | Route | Method | Who | Description |
674
+ |-------|--------|-----|-------------|
675
+ | `/admin/trust/promote` | POST | Any admin | Promote client to next level |
676
+ | `/admin/trust/demote` | POST | Any admin | Demote client to previous level |
677
+ | `/admin/trust/block` | POST | Any admin | Block client |
678
+ | `/admin/trust/unblock` | POST | Any admin | Unblock client |
679
+ | `/admin/trust/level/{client_id}` | GET | Any admin | Get client's current level |
680
+
681
+ ### Super Admin Routes (Self Address Only)
682
+
683
+ Only the agent's own address (super admin) can manage the admins list.
684
+
685
+ | Route | Method | Description |
686
+ |-------|--------|-------------|
687
+ | `/superadmin/add` | POST | Add an admin |
688
+ | `/superadmin/remove` | POST | Remove an admin |
689
+
690
+ **Example admin request:**
691
+ ```json
692
+ {
693
+ "payload": {
694
+ "client_id": "0xclient123...",
695
+ "timestamp": 1699999999
696
+ },
697
+ "from": "0xAdminPublicKey",
698
+ "signature": "0xEd25519Signature..."
699
+ }
700
+ ```
701
+
702
+ **Example super admin request (add admin):**
703
+ ```json
704
+ {
705
+ "payload": {
706
+ "admin_id": "0xnewadmin...",
707
+ "timestamp": 1699999999
708
+ },
709
+ "from": "0xSelfAddress",
710
+ "signature": "0xEd25519Signature..."
711
+ }
712
+ ```
713
+
714
+ ## Policy File Format
715
+
716
+ Trust policies are markdown files with YAML frontmatter:
717
+
718
+ ```yaml
719
+ ---
720
+ # Who has access
721
+ allow:
722
+ - whitelisted # ~/.co/whitelist.txt
723
+ - contact # ~/.co/contacts.txt
724
+
725
+ # Who is blocked
726
+ deny:
727
+ - blocked # ~/.co/blocklist.txt
728
+
729
+ # How strangers become contacts
730
+ onboard:
731
+ invite_code: [CODE1, CODE2]
732
+ payment: 10
733
+
734
+ # Strangers without credentials
735
+ default: deny # allow | deny | ask
736
+ ---
737
+
738
+ # LLM Policy (only used when default: ask)
739
+
740
+ Evaluate strangers for access...
741
+ ```
742
+
743
+ ### Evaluation Order
744
+
745
+ 1. Check `deny` list (blocked → reject)
746
+ 2. Check `allow` list (whitelist/contacts → allow)
747
+ 3. Try onboarding (invite code or payment → promote to contact)
748
+ 4. Apply `default` action
749
+
750
+
751
+ ## TrustAgent Class
752
+
753
+ TrustAgent inherits from Agent and provides trust-specific methods.
238
754
 
239
- ### Production Mode
240
755
  ```python
241
- # Strict verification for production
242
- payment = need("payment processor", trust="strict")
243
- sensitive = need("data processor", trust="strict")
756
+ class TrustAgent(Agent):
757
+ """Agent specialized for trust decisions."""
758
+
759
+ def __init__(self, trust: str = "careful", *, api_key: str = None, model: str = "co/gpt-4o-mini"):
760
+ """Create from level ("open", "careful", "strict") or policy path."""
761
+
762
+ # === Main Decision ===
763
+
764
+ def should_allow(self, client_id: str, request: dict = None) -> Decision:
765
+ """Check if request is allowed. Returns Decision(allow, reason, used_llm)."""
766
+
767
+ # === Verification ===
768
+
769
+ def verify_invite(self, client_id: str, invite_code: str) -> bool:
770
+ """Verify invite code. Promotes to contact if valid."""
771
+
772
+ def verify_payment(self, client_id: str, payment_info: dict) -> bool:
773
+ """Verify payment. Promotes to contact if valid."""
774
+
775
+ # === Promotion (earned) ===
776
+
777
+ def promote_to_contact(self, client_id: str) -> bool:
778
+ """Stranger → Contact"""
779
+
780
+ def promote_to_whitelist(self, client_id: str) -> bool:
781
+ """Contact → Whitelist"""
782
+
783
+ # === Demotion ===
784
+
785
+ def demote_to_contact(self, client_id: str) -> bool:
786
+ """Whitelist → Contact"""
787
+
788
+ def demote_to_stranger(self, client_id: str) -> bool:
789
+ """Contact → Stranger"""
790
+
791
+ # === Blocking ===
792
+
793
+ def block(self, client_id: str, reason: str) -> bool:
794
+ """Add to blocklist."""
795
+
796
+ def unblock(self, client_id: str) -> bool:
797
+ """Remove from blocklist."""
798
+
799
+ # === Admin (manual only) ===
800
+
801
+ def set_admin(self, client_id: str, by_admin: str) -> bool:
802
+ """Grant admin. Requires existing admin."""
803
+
804
+ def remove_admin(self, client_id: str, by_admin: str) -> bool:
805
+ """Revoke admin. Requires existing admin."""
806
+
807
+ # === Queries ===
808
+
809
+ def get_level(self, client_id: str) -> str:
810
+ """Returns: stranger, contact, whitelist, admin, or blocked."""
811
+
812
+ def get_history(self, client_id: str) -> dict:
813
+ """Returns client's request history."""
814
+
815
+ def list_clients(self, level: str = None) -> list:
816
+ """List clients, optionally filtered by level."""
244
817
  ```
245
818
 
246
- ### Mixed Trust
819
+ ## Host Uses TrustAgent Directly
820
+
247
821
  ```python
248
- # Different trust for different services
249
- scraper = need("web scraper", trust="open") # Low risk
250
- analyzer = need("analyze data", trust="tested") # Medium risk
251
- payment = need("process payment", trust="strict") # High risk
822
+ # In host.py
823
+ from connectonion.network.trust import TrustAgent
824
+
825
+ # Load trust agent
826
+ trust_agent = TrustAgent("careful")
827
+
828
+ # Admin routes
829
+ @app.post("/admin/trust/promote")
830
+ def promote(client_id: str):
831
+ level = trust_agent.get_level(client_id)
832
+ if level == "stranger":
833
+ return trust_agent.promote_to_contact(client_id)
834
+ elif level == "contact":
835
+ return trust_agent.promote_to_whitelist(client_id)
836
+
837
+ # Agent route
838
+ @app.post("/input")
839
+ def agent_input(client_id: str, request: dict):
840
+ # Check trust first
841
+ decision = trust_agent.should_allow(client_id, request)
842
+ if not decision.allow:
843
+ return {"error": decision.reason}
844
+
845
+ # Process with agent
846
+ return agent.input(request["prompt"])
252
847
  ```
253
848
 
254
- ### Custom Trust Logic
849
+ ## Atomic Functions (Tools)
850
+
851
+ Trust manager provides simple atomic functions as tools:
852
+
255
853
  ```python
256
- # Trust based on context
257
- def get_trust_level(service_type):
258
- if "payment" in service_type:
259
- return "strict"
260
- elif "read" in service_type:
261
- return "open"
262
- else:
263
- return "tested"
854
+ # Promotion (earn trust)
855
+ def promote_to_contact(client_id: str) -> str:
856
+ """Stranger Contact"""
857
+
858
+ def promote_to_whitelist(client_id: str) -> str:
859
+ """Contact → Whitelist"""
860
+
861
+ # Demotion (lose trust)
862
+ def demote_to_contact(client_id: str) -> str:
863
+ """Whitelist → Contact"""
864
+
865
+ def demote_to_stranger(client_id: str) -> str:
866
+ """Contact → Stranger"""
867
+
868
+ # Blocking
869
+ def block(client_id: str, reason: str) -> str:
870
+ """Add to blocklist."""
871
+
872
+ def unblock(client_id: str) -> str:
873
+ """Remove from blocklist."""
874
+
875
+ # Admin (special, manual only)
876
+ def set_admin(client_id: str) -> str:
877
+ """Grant admin privileges. Requires existing admin."""
878
+
879
+ def remove_admin(client_id: str) -> str:
880
+ """Revoke admin privileges. Requires existing admin."""
881
+
882
+ # Queries
883
+ def get_client_level(client_id: str) -> str:
884
+ """Returns: stranger, contact, whitelist, admin, or blocked."""
885
+
886
+ def get_client_history(client_id: str) -> str:
887
+ """Returns client's request history summary."""
888
+ ```
889
+
890
+ ### Promotion Chain vs Admin
891
+
892
+ ```
893
+ Promotion chain (earned):
894
+ Stranger → Contact → Whitelist
895
+
896
+ Admin (manual only):
897
+ set_admin() / remove_admin()
898
+ ```
899
+
900
+ Admin is **not** part of the promotion chain. It's a special role granted manually by an existing admin.
901
+
902
+ ## Logic in Markdown
903
+
904
+ The markdown body defines policy for complex decisions (when `use_agent` triggers):
264
905
 
265
- service = need("read data", trust=get_trust_level("read data"))
906
+ ```markdown
907
+ # Trust Agent Policy
908
+
909
+ You manage client trust levels using these tools:
910
+ - `promote_to_contact(client_id)` - Stranger → Contact
911
+ - `promote_to_whitelist(client_id)` - Contact → Whitelist
912
+ - `block(client_id, reason)` - Block abuser
913
+
914
+ ## When to Promote
915
+
916
+ Promote stranger to contact when:
917
+ - 10+ requests with good behavior
918
+ - No suspicious patterns
919
+
920
+ Promote contact to whitelist when:
921
+ - 100+ successful requests
922
+ - Consistently valuable interactions
923
+
924
+ ## When to Block
925
+
926
+ Block immediately if:
927
+ - Abuse detected
928
+ - Spam patterns
929
+ - Attempting to bypass verification
266
930
  ```
267
931
 
268
- ## Security Best Practices
932
+ The trust agent reads this from `system_prompt` and uses the atomic functions as tools.
933
+
934
+ ## Best Practices
269
935
 
270
- 1. **Production = Strict**: Always use `trust="strict"` in production
271
- 2. **Test Sensitive Operations**: Payment, data modification, etc.
272
- 3. **Whitelist Critical Services**: Manually verify and whitelist
273
- 4. **Monitor Trust Decisions**: Log all trust evaluations
274
- 5. **Regular Audits**: Review whitelist and trust policies
936
+ 1. **Use fast rules for common cases** - No tokens burned
937
+ 2. **Reserve trust agent for edge cases** - Saves money
938
+ 3. **Cache decisions** - Don't re-evaluate every request
939
+ 4. **Start with "careful"** - Good default for most cases
940
+ 5. **Use "strict" in production** - Whitelist critical services
941
+ 6. **Monitor trust decisions** - Log for audit trail
275
942
 
276
943
  ## FAQ
277
944
 
278
945
  **Q: What's the default trust level?**
279
- A: `"tested"` - agents are tested before first use
946
+ A: `"careful"` - verify strangers, allow contacts.
947
+
948
+ **Q: Do fast rules burn tokens?**
949
+ A: No. Fast rules are simple if/then executed by host. Zero tokens.
950
+
951
+ **Q: When does trust agent run?**
952
+ A: Only when `use_agent` triggers fire (e.g., after 10 requests). Rare.
953
+
954
+ **Q: Where are lists stored?**
955
+ A: `~/.co/` - whitelist.txt, contacts.txt, blocklist.txt
956
+
957
+ **Q: Can I use the same agent with different trust levels?**
958
+ A: Yes. Trust is host config, not agent config.
959
+
960
+ ```python
961
+ # Same agent, different trust
962
+ host(agent, trust="open") # Dev
963
+ host(agent, trust="strict") # Prod
964
+ ```
965
+
966
+ **Q: How do I add custom verification?**
967
+ A: Add tools to TrustAgent:
280
968
 
281
- **Q: Can I change trust after agent creation?**
282
- A: Yes: `agent.trust = new_trust_agent`
969
+ ```python
970
+ trust = TrustAgent(
971
+ system_prompt="./my_policy.md",
972
+ tools=[my_custom_verifier]
973
+ )
974
+ ```
975
+
976
+ ## TODO
977
+
978
+ ### Prevent Promote Injection During Skill Test
979
+
980
+ **Problem:** If trust agent has tools like `promote_to_contact()`, during skill testing a malicious agent could trick the trust agent into calling these tools - essentially promoting itself or manipulating access management.
981
+
982
+ **Security Risk:**
983
+ - Skill test evaluates if agent can do what it claims
984
+ - Malicious agent could inject prompts to trigger `promote_to_contact()`
985
+ - Could bypass normal verification flow
986
+
987
+ **Possible Solutions:**
988
+ 1. Separate skill-test mode (no list management tools available)
989
+ 2. Require confirmation before list changes
990
+ 3. Sandbox trust agent during skill evaluation
991
+ 4. Use different trust agent instance for skill tests (read-only)
283
992
 
284
- **Q: How do trust agents communicate?**
285
- A: They're regular ConnectOnion agents - they talk naturally
993
+ **Status:** Needs design decision
286
994
 
287
- **Q: What if both agents have strict trust?**
288
- A: Both requirements must be met - most restrictive wins
995
+ ### WebSocket Protocol for Admin/Onboard
289
996
 
290
- **Q: Can I disable trust completely?**
291
- A: Yes: `trust="open"` accepts everyone without checks
997
+ Both HTTP and WebSocket are supported for admin and onboard operations. WebSocket is future-proof for decentralized/P2P scenarios (WebRTC).
998
+
999
+ **Client → Server Messages:**
1000
+
1001
+ | Type | Payload | Who |
1002
+ |------|---------|-----|
1003
+ | `INPUT` | `{ prompt, ... }` | Anyone |
1004
+ | `ONBOARD_SUBMIT` | `{ invite_code }` or `{ payment }` | Stranger |
1005
+ | `ADMIN_PROMOTE` | `{ client_id }` | Admin |
1006
+ | `ADMIN_DEMOTE` | `{ client_id }` | Admin |
1007
+ | `ADMIN_BLOCK` | `{ client_id, reason }` | Admin |
1008
+ | `ADMIN_UNBLOCK` | `{ client_id }` | Admin |
1009
+ | `ADMIN_GET_LEVEL` | `{ client_id }` | Admin |
1010
+ | `ADMIN_ADD` | `{ admin_id }` | Super Admin |
1011
+ | `ADMIN_REMOVE` | `{ admin_id }` | Super Admin |
1012
+
1013
+ **Server → Client Messages:**
1014
+
1015
+ | Type | Payload | When |
1016
+ |------|---------|------|
1017
+ | `OUTPUT` | `{ result, session_id }` | Agent response |
1018
+ | `ONBOARD_REQUIRED` | `{ methods, payment_amount? }` | Stranger needs to onboard |
1019
+ | `ONBOARD_SUCCESS` | `{ identity, level }` | Onboard complete |
1020
+ | `ADMIN_RESULT` | `{ action, success, message }` | Admin action result |
1021
+ | `ERROR` | `{ message }` | Any error |
1022
+
1023
+ **Example: Stranger connects, onboards, then chats:**
1024
+
1025
+ ```
1026
+ Client: { type: 'INPUT', prompt: 'Hello', payload, signature }
1027
+ Server: { type: 'ONBOARD_REQUIRED', methods: ['invite_code'], identity: '0x...' }
1028
+ Client: { type: 'ONBOARD_SUBMIT', payload: { invite_code: 'BETA2024' }, signature }
1029
+ Server: { type: 'ONBOARD_SUCCESS', identity: '0x...', level: 'contact' }
1030
+ Client: { type: 'INPUT', prompt: 'Hello', payload, signature }
1031
+ Server: { type: 'OUTPUT', result: 'Hi there!' }
1032
+ ```