Thread Registry: - Root thread initialization at boot - Thread chain tracking for message flow - register_thread() for external message UUIDs LLM Router: - Multi-backend support with failover strategy - Token bucket rate limiting per backend - Async completion API with retries Console Handler: - Message-driven REPL (not separate async loop) - ConsolePrompt/ConsoleInput payloads - Handler returns None to disconnect Boot System: - System primitives module - Boot message injected at startup - Initializes root thread context Documentation: - Updated v2.1 docs for new architecture - LLM router documentation - Gap analysis cross-check Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
433 lines
12 KiB
Markdown
433 lines
12 KiB
Markdown
# AgentServer v2.1 Documentation Cross-Check
|
|
**Analysis Date:** January 07, 2026
|
|
|
|
## Executive Summary
|
|
Overall the documentation is **highly consistent** and well-structured. Found minor inconsistencies and a few areas needing clarification, but no major contradictions.
|
|
|
|
---
|
|
|
|
## 1. CRITICAL ISSUES (Must Fix)
|
|
|
|
### 1.1 Missing Core Principles Document Reference
|
|
**Issue:** Core principles referenced everywhere but not in upload
|
|
**Impact:** Cannot verify complete consistency
|
|
**Files affected:** README.md, listener-class-v2.1.md, message-pump-v2.1.md
|
|
**Recommendation:** Need to review core-principles-v2.1.md for final check
|
|
|
|
### 1.2 Handler Signature Inconsistency
|
|
**Issue:** Different handler signatures across documents
|
|
|
|
**listener-class-v2.1.md:**
|
|
```python
|
|
async def handler(
|
|
payload: PayloadDataclass,
|
|
metadata: HandlerMetadata
|
|
) -> bytes:
|
|
```
|
|
|
|
**self-grammar-generation.md:**
|
|
```python
|
|
def add_handler(payload: AddPayload) -> bytes: # NOT async!
|
|
result = payload.a + payload.b
|
|
return f"<result>{result}</result>".encode("utf-8")
|
|
```
|
|
|
|
**README.md:**
|
|
```python
|
|
def add_handler(payload: AddPayload) -> bytes: # NOT async!
|
|
```
|
|
|
|
**Conflict:** Some examples show `async def`, others show `def`
|
|
**Resolution needed:** Clarify if handlers MUST be async or can be sync
|
|
**Recommendation:**
|
|
- If both allowed: document that sync handlers are auto-wrapped
|
|
- If async only: fix all examples to use `async def`
|
|
|
|
---
|
|
|
|
## 2. MEDIUM ISSUES (Should Fix)
|
|
|
|
### 2.1 HandlerMetadata Fields Discrepancy
|
|
**listener-class-v2.1.md:**
|
|
```python
|
|
@dataclass(frozen=True)
|
|
class HandlerMetadata:
|
|
thread_id: str
|
|
from_id: str
|
|
own_name: str | None = None
|
|
is_self_call: bool = False
|
|
```
|
|
|
|
**Our discussion (coroutine trust boundary):**
|
|
- Handlers should receive MINIMAL context
|
|
- `from_id` exposes sender identity (breaks purity?)
|
|
- `is_self_call` implies handler knows about calling patterns
|
|
|
|
**Question:** Does exposing `from_id` violate "handlers don't know topology"?
|
|
- If yes: Remove `from_id`, handlers only get `thread_id`
|
|
- If no: Clarify why this is safe (e.g., "sender's name is not topology")
|
|
|
|
**Recommendation:** Document the distinction between:
|
|
- Metadata handlers CAN see (thread_id, own_name for agents)
|
|
- Metadata system keeps private (thread_path, parent, peers enforcement)
|
|
|
|
### 2.2 Root Tag Derivation Formula Inconsistency
|
|
**configuration.md:**
|
|
> Root tag = `{lowercase_name}.{lowercase_dataclass_name}`
|
|
|
|
**listener-class-v2.1.md:**
|
|
> `{lowercase_registered_name}.{lowercase_dataclass_name}`
|
|
|
|
**Example from listener-class:**
|
|
```
|
|
Registered name: calculator.add
|
|
Dataclass: AddPayload
|
|
Root tag: calculator.add.addpayload
|
|
```
|
|
|
|
**Issue:** This produces THREE dots: `calculator.add.addpayload`
|
|
- Is this intended? (hierarchical namespace)
|
|
- Or should it be: `calculator-add.addpayload`?
|
|
|
|
**Recommendation:** Clarify if dots in registered names are part of the root tag or if there's a separator convention
|
|
|
|
### 2.3 `own_name` Exposure Rationale
|
|
**configuration.md:**
|
|
> `agent: true` → enforces unique root tag, exposes `own_name` in HandlerMetadata
|
|
|
|
**Our discussion concluded:**
|
|
- Agents don't need to know their name for self-iteration (blind routing works)
|
|
- `<todo-until>` is automatic self-routing
|
|
|
|
**Question:** Why expose `own_name` at all?
|
|
- Logging/audit trails?
|
|
- Self-referential prompts?
|
|
- Legacy from earlier design?
|
|
|
|
**Recommendation:** Either:
|
|
1. Document the specific use case for `own_name`
|
|
2. Or remove it if truly unnecessary
|
|
|
|
### 2.4 System Primitives Not Listed
|
|
**Files mention but don't enumerate:**
|
|
- `<todo-until>` - documented in discussion, not in files
|
|
- `<huh>` - mentioned in message-pump-v2.1.md
|
|
- Thread pruning notifications - discussed, not documented
|
|
|
|
**Recommendation:** Add a "System Primitives" section to core principles:
|
|
```markdown
|
|
## System Primitives
|
|
|
|
The organism pre-loads the following message types with special routing:
|
|
|
|
1. **`<todo-until>`** (routing: self)
|
|
- Enables agent iteration
|
|
- Schema: primitives/todo-until.xsd
|
|
- Emitters: any agent
|
|
|
|
2. **`<huh>`** (routing: sender, system-only)
|
|
- Validation error feedback
|
|
- Schema: primitives/huh.xsd
|
|
- Emitters: system only
|
|
```
|
|
|
|
---
|
|
|
|
## 3. MINOR ISSUES (Nice to Have)
|
|
|
|
### 3.1 Thread Pruning Documentation Gap
|
|
**Discussed extensively but not documented:**
|
|
- When threads are pruned (on delegation return)
|
|
- UUID deletion and storage cleanup
|
|
- Optional `notify_on_prune: true` in YAML
|
|
|
|
**Files affected:** None explicitly cover this
|
|
**Recommendation:** Add to configuration.md under listener options
|
|
|
|
### 3.2 Multi-Payload Extraction Details
|
|
**message-pump-v2.1.md:**
|
|
> `multi_payload_extract` wraps in `<dummy>` (idempotent)
|
|
|
|
**Question:** What does "idempotent" mean here?
|
|
- If handler already wrapped in `<dummy>`, does it double-wrap?
|
|
- Or does it detect existing wrapper?
|
|
|
|
**Recommendation:** Clarify the dummy-wrapping logic
|
|
|
|
### 3.3 Broadcast Mechanism Not Fully Specified
|
|
**configuration.md:**
|
|
```yaml
|
|
broadcast: true # Shares root tag with other listeners
|
|
```
|
|
|
|
**Questions:**
|
|
- How do agents address broadcast groups?
|
|
- Do they list individual listeners or a group name?
|
|
- What happens if broadcast listener subset changes via hot-reload?
|
|
|
|
**Recommendation:** Add broadcast routing section to message-pump or configuration docs
|
|
|
|
### 3.4 Gateway vs Local Listener Routing
|
|
**configuration.md shows:**
|
|
```yaml
|
|
listeners:
|
|
- name: search.google
|
|
broadcast: true
|
|
|
|
gateways:
|
|
- name: web_search
|
|
remote_url: ...
|
|
```
|
|
|
|
**Agent peers list:**
|
|
```yaml
|
|
peers:
|
|
- web_search # Gateway name, not listener name
|
|
```
|
|
|
|
**Question:** How does routing distinguish:
|
|
- Local listener `search.google`
|
|
- Gateway group `web_search`
|
|
- What if names collide?
|
|
|
|
**Recommendation:** Document gateway resolution precedence
|
|
|
|
### 3.5 `<respond>` Tag Status Unclear
|
|
**Our discussion suggested:**
|
|
- Maybe there's no explicit `<respond>` tag
|
|
- System routes non-self/non-peer payloads to parent automatically
|
|
|
|
**Files don't mention `<respond>` at all**
|
|
|
|
**Recommendation:** Clarify if:
|
|
1. There IS a `<respond>` primitive (add to system primitives)
|
|
2. There ISN'T (document implicit parent routing)
|
|
|
|
---
|
|
|
|
## 4. CONSISTENCY CHECKS (All Good ✓)
|
|
|
|
### 4.1 XSD Validation Flow ✓
|
|
**Consistent across:**
|
|
- README.md: "XSD validation, no transcription bugs"
|
|
- listener-class-v2.1.md: "XSD-validated instance"
|
|
- message-pump-v2.1.md: "xsd_validation_step"
|
|
|
|
### 4.2 Handler Purity Principle ✓
|
|
**Consistent across:**
|
|
- README.md: "pure handlers"
|
|
- listener-class-v2.1.md: "pure async handler function"
|
|
- Our discussion: handlers are untrusted, coroutine captures metadata
|
|
|
|
### 4.3 Opaque UUID Threading ✓
|
|
**Consistent across:**
|
|
- README.md: "opaque UUID threading for privacy"
|
|
- listener-class-v2.1.md: "Opaque UUID matching <thread/> in envelope"
|
|
- configuration.md: "Opaque thread UUIDs"
|
|
|
|
### 4.4 Mandatory Description ✓
|
|
**Consistent across:**
|
|
- README.md: "one-line human description"
|
|
- listener-class-v2.1.md: "mandatory human-readable description"
|
|
- configuration.md: "Mandatory short blurb"
|
|
|
|
### 4.5 Closed-Loop Pipeline ✓
|
|
**Consistent across:**
|
|
- README.md: "ALL messages undergo identical security processing"
|
|
- message-pump-v2.1.md: handler responses go through multi_payload_extract → route_and_process
|
|
- Our discussion: everything validates, no fast paths
|
|
|
|
---
|
|
|
|
## 5. MISSING DOCUMENTATION
|
|
|
|
### 5.1 Bootstrap Sequence
|
|
**Referenced but not detailed:**
|
|
- How organism.yaml is loaded
|
|
- Order of listener registration
|
|
- When pipelines start accepting messages
|
|
- System pipeline instantiation
|
|
|
|
**Recommendation:** Add "Bootstrap Sequence" section to configuration.md
|
|
|
|
### 5.2 Hot-Reload Process
|
|
**Mentioned but not specified:**
|
|
- How OOB hot-reload works
|
|
- What happens to in-flight messages during reload
|
|
- Schema version migration
|
|
|
|
**Recommendation:** Add "Hot-Reload Mechanics" section
|
|
|
|
### 5.3 Error Message Format
|
|
**`<huh>` mentioned but schema not shown:**
|
|
```xml
|
|
<huh>
|
|
<error>XSD validation failed: ...</error>
|
|
<original-attempt>...</original-attempt>
|
|
</huh>
|
|
```
|
|
|
|
**Recommendation:** Document `<huh>` schema in primitives section
|
|
|
|
### 5.4 Token Budget Enforcement
|
|
**Mentioned in README:**
|
|
> Token budgets enforce computational bounds
|
|
|
|
**Not documented:**
|
|
- How budgets are tracked
|
|
- What happens when exceeded
|
|
- Per-thread vs per-agent budgets
|
|
|
|
**Recommendation:** Add token budget section to message-pump or core principles
|
|
|
|
### 5.5 Fair Scheduling Details
|
|
**README mentions:**
|
|
> Thread-based message queue with bounded memory and fair scheduling
|
|
|
|
**Not documented:**
|
|
- Scheduling algorithm (breadth-first/depth-first from config?)
|
|
- Queue size limits
|
|
- Backpressure handling
|
|
|
|
**Recommendation:** Expand message-pump-v2.1.md with scheduling details
|
|
|
|
---
|
|
|
|
## 6. TERMINOLOGY CONSISTENCY ✓
|
|
|
|
### Consistent Terms Used:
|
|
- "Listener" (not "handler" or "capability" inconsistently)
|
|
- "Organism" (not "system" or "platform" inconsistently)
|
|
- "Pipeline" (not "processor" or "chain")
|
|
- "Thread UUID" (not "session" or "context")
|
|
- "Peers list" (not "allowed targets" or "capabilities")
|
|
|
|
### Good Naming Conventions:
|
|
- Files: kebab-case (listener-class-v2_1.md)
|
|
- Root tags: lowercase.dotted (calculator.add.addpayload)
|
|
- Registered names: dotted.hierarchy (calculator.add)
|
|
- Dataclasses: PascalCase (AddPayload)
|
|
|
|
---
|
|
|
|
## 7. SECURITY MODEL CONSISTENCY ✓
|
|
|
|
### Handler Trust Boundary
|
|
**README.md:**
|
|
> Handlers are untrusted code... cannot forge identity, escape thread, route arbitrarily
|
|
|
|
**Our discussion:**
|
|
> Coroutine captures metadata before handler execution
|
|
|
|
**Status:** Consistent! README correctly summarizes the trust model
|
|
|
|
### Topology Privacy
|
|
**README.md:**
|
|
> Opaque UUIDs, private path registry, peers list enforcement
|
|
|
|
**listener-class-v2.1.md:**
|
|
> Handlers receive only `thread_id` (opaque UUID)
|
|
|
|
**Status:** Consistent! Though need to clarify `from_id` exposure
|
|
|
|
### Anti-Paperclip
|
|
**README.md:**
|
|
> No persistent cross-thread memory, token budgets, thread pruning
|
|
|
|
**Our discussion:**
|
|
> Thread-scoped storage, automatic cleanup, no global state
|
|
|
|
**Status:** Consistent!
|
|
|
|
---
|
|
|
|
## 8. RECOMMENDED ADDITIONS
|
|
|
|
### 8.1 Add to configuration.md:
|
|
```yaml
|
|
listeners:
|
|
- name: example
|
|
notify_on_prune: boolean # Optional: receive thread-pruned notifications
|
|
```
|
|
|
|
### 8.2 Add to listener-class-v2.1.md:
|
|
**Section: "Handler Execution Model"**
|
|
- Clarify async vs sync handlers
|
|
- Explain coroutine capture
|
|
- Document metadata availability vs privacy
|
|
|
|
### 8.3 Add to message-pump-v2.1.md:
|
|
**Section: "System Primitives"**
|
|
- List all magic tags (`<todo-until>`, `<huh>`)
|
|
- Document routing policies
|
|
- Explain emission restrictions
|
|
|
|
### 8.4 Create new file: `primitives.md`
|
|
Document all system primitives with:
|
|
- Schema (XSD)
|
|
- Routing policy
|
|
- Emission restrictions
|
|
- Usage examples
|
|
|
|
### 8.5 Add to README.md:
|
|
**Section: "Computational Model"**
|
|
Brief explanation of:
|
|
- `<todo-until>` for iteration
|
|
- Blind self-routing
|
|
- Token budgets
|
|
- Thread pruning
|
|
|
|
---
|
|
|
|
## 9. DOCUMENTATION QUALITY SCORES
|
|
|
|
| Document | Clarity | Completeness | Consistency | Overall |
|
|
|----------|---------|--------------|-------------|---------|
|
|
| README.md | 9/10 | 8/10 | 10/10 | 9/10 |
|
|
| configuration.md | 10/10 | 9/10 | 10/10 | 9.5/10 |
|
|
| listener-class-v2.1.md | 9/10 | 9/10 | 9/10 | 9/10 |
|
|
| message-pump-v2.1.md | 8/10 | 7/10 | 9/10 | 8/10 |
|
|
| self-grammar-generation.md | 8/10 | 8/10 | 8/10 | 8/10 |
|
|
| why-not-json.md | 10/10 | 10/10 | N/A | 10/10 |
|
|
|
|
**Average: 9.1/10**
|
|
|
|
---
|
|
|
|
## 10. CRITICAL PATH TO 1.0 RELEASE
|
|
|
|
### Must Fix Before Release:
|
|
1. ✅ Resolve async vs sync handler signature
|
|
2. ✅ Clarify `from_id` in HandlerMetadata (privacy concern)
|
|
3. ✅ Document system primitives (`<todo-until>`, `<huh>`)
|
|
4. ✅ Add thread pruning documentation
|
|
5. ✅ Specify `<respond>` behavior (if it exists)
|
|
|
|
### Should Fix Before Release:
|
|
6. Document bootstrap sequence
|
|
7. Document hot-reload mechanics
|
|
8. Add token budget details
|
|
9. Clarify broadcast routing
|
|
10. Add gateway resolution rules
|
|
|
|
### Nice to Have:
|
|
11. Create primitives.md reference
|
|
12. Add more handler examples
|
|
13. Document fair scheduling algorithm
|
|
14. Add troubleshooting guide
|
|
|
|
---
|
|
|
|
## FINAL VERDICT
|
|
|
|
**The documentation is production-ready with minor fixes.**
|
|
|
|
The architecture is sound, the security model is well-thought-out, and the core principles are consistently represented. The main gaps are:
|
|
|
|
1. **Implementation details** (bootstrap, hot-reload, scheduling)
|
|
2. **System primitives** (need explicit documentation)
|
|
3. **Handler signature** (async vs sync needs clarification)
|
|
|
|
Once core-principles-v2.1.md is reviewed and the above items addressed, this is **ready for implementation and external review**.
|
|
|
|
The "It just works... safely" tagline is earned. 🎯
|