feat(#93): implement agent spawn via federation

Implements FED-010: Agent Spawn via Federation feature that enables
spawning and managing Claude agents on remote federated Mosaic Stack
instances via COMMAND message type.

Features:
- Federation agent command types (spawn, status, kill)
- FederationAgentService for handling agent operations
- Integration with orchestrator's agent spawner/lifecycle services
- API endpoints for spawning, querying status, and killing agents
- Full command routing through federation COMMAND infrastructure
- Comprehensive test coverage (12/12 tests passing)

Architecture:
- Hub → Spoke: Spawn agents on remote instances
- Command flow: FederationController → FederationAgentService →
  CommandService → Remote Orchestrator
- Response handling: Remote orchestrator returns agent status/results
- Security: Connection validation, signature verification

Files created:
- apps/api/src/federation/types/federation-agent.types.ts
- apps/api/src/federation/federation-agent.service.ts
- apps/api/src/federation/federation-agent.service.spec.ts

Files modified:
- apps/api/src/federation/command.service.ts (agent command routing)
- apps/api/src/federation/federation.controller.ts (agent endpoints)
- apps/api/src/federation/federation.module.ts (service registration)
- apps/orchestrator/src/api/agents/agents.controller.ts (status endpoint)
- apps/orchestrator/src/api/agents/agents.module.ts (lifecycle integration)

Testing:
- 12/12 tests passing for FederationAgentService
- All command service tests passing
- TypeScript compilation successful
- Linting passed

Refs #93

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
Jason Woltje
2026-02-03 14:37:06 -06:00
parent a8c8af21e5
commit 12abdfe81d
405 changed files with 13545 additions and 2153 deletions

View File

@@ -52,6 +52,7 @@
### Peer-to-Peer Federation Model
Every Mosaic Stack instance is a **peer** that can simultaneously act as:
- **Master** — Control and query downstream spokes
- **Spoke** — Expose capabilities to upstream masters
@@ -120,15 +121,15 @@ Every Mosaic Stack instance is a **peer** that can simultaneously act as:
Authentik provides enterprise-grade identity management:
| Feature | Purpose |
|---------|---------|
| **OIDC/SAML** | Single sign-on across instances |
| **User Directory** | Centralized user management |
| **Groups** | Team/department organization |
| **RBAC** | Role-based access control |
| **Audit Logs** | Compliance and security tracking |
| **MFA** | Multi-factor authentication |
| **Federation** | Trust between external IdPs |
| Feature | Purpose |
| ------------------ | -------------------------------- |
| **OIDC/SAML** | Single sign-on across instances |
| **User Directory** | Centralized user management |
| **Groups** | Team/department organization |
| **RBAC** | Role-based access control |
| **Audit Logs** | Compliance and security tracking |
| **MFA** | Multi-factor authentication |
| **Federation** | Trust between external IdPs |
### Auth Architecture
@@ -199,6 +200,7 @@ When federating between instances with different IdPs:
```
**Identity Mapping:**
- Same email = same person (by convention)
- Explicit identity linking via federation protocol
- No implicit access—must be granted per instance
@@ -297,11 +299,7 @@ When federating between instances with different IdPs:
"returns": "Workspace[]"
}
],
"eventSubscriptions": [
"calendar.reminder",
"tasks.assigned",
"tasks.completed"
]
"eventSubscriptions": ["calendar.reminder", "tasks.assigned", "tasks.completed"]
}
```
@@ -467,19 +465,19 @@ Instance
### Role Permissions Matrix
| Permission | Owner | Admin | Member | Viewer | Guest |
|------------|-------|-------|--------|--------|-------|
| View workspace | ✓ | ✓ | ✓ | ✓ | ✓* |
| Create content | ✓ | ✓ | ✓ | ✗ | ✗ |
| Edit content | ✓ | ✓ | ✓ | ✗ | ✗ |
| Delete content | ✓ | ✓ | ✗ | ✗ | ✗ |
| Manage members | ✓ | ✓ | ✗ | ✗ | ✗ |
| Manage teams | ✓ | ✓ | ✗ | ✗ | ✗ |
| Configure workspace | ✓ | ✗ | ✗ | ✗ | ✗ |
| Delete workspace | ✓ | ✗ | ✗ | ✗ | ✗ |
| Manage federation | ✓ | ✗ | ✗ | ✗ | ✗ |
| Permission | Owner | Admin | Member | Viewer | Guest |
| ------------------- | ----- | ----- | ------ | ------ | ----- |
| View workspace | ✓ | ✓ | ✓ | ✓ | ✓\* |
| Create content | ✓ | ✓ | ✓ | ✗ | ✗ |
| Edit content | ✓ | ✓ | ✓ | ✗ | ✗ |
| Delete content | ✓ | ✓ | ✗ | ✗ | ✗ |
| Manage members | ✓ | ✓ | ✗ | ✗ | ✗ |
| Manage teams | ✓ | ✓ | ✗ | ✗ | ✗ |
| Configure workspace | ✓ | ✗ | ✗ | ✗ | ✗ |
| Delete workspace | ✓ | ✗ | ✗ | ✗ | ✗ |
| Manage federation | ✓ | ✗ | ✗ | ✗ | ✗ |
*Guest: scoped to specific shared items only
\*Guest: scoped to specific shared items only
### Federation RBAC
@@ -503,6 +501,7 @@ Cross-instance access is always scoped and limited:
```
**Key Constraints:**
- Federated users cannot exceed `maxRole` (e.g., member can't become admin)
- Access limited to `scopedWorkspaces` only
- Capabilities are explicitly allowlisted
@@ -545,14 +544,14 @@ Cross-instance access is always scoped and limited:
### What's Stored vs Queried
| Data Type | Home Instance | Work Instance | Notes |
|-----------|---------------|---------------|-------|
| Personal tasks | ✓ Stored | — | Only at home |
| Work tasks | Queried live | ✓ Stored | Never replicated |
| Personal calendar | ✓ Stored | — | Only at home |
| Work calendar | Queried live | ✓ Stored | Never replicated |
| Federation metadata | ✓ Stored | ✓ Stored | Connection config only |
| Query results cache | Ephemeral (5m TTL) | — | Optional, short-lived |
| Data Type | Home Instance | Work Instance | Notes |
| ------------------- | ------------------ | ------------- | ---------------------- |
| Personal tasks | ✓ Stored | — | Only at home |
| Work tasks | Queried live | ✓ Stored | Never replicated |
| Personal calendar | ✓ Stored | — | Only at home |
| Work calendar | Queried live | ✓ Stored | Never replicated |
| Federation metadata | ✓ Stored | ✓ Stored | Connection config only |
| Query results cache | Ephemeral (5m TTL) | — | Optional, short-lived |
### Severance Procedure
@@ -581,6 +580,7 @@ Result:
**Goal:** Multi-instance awareness, basic federation protocol
**Deliverables:**
- [ ] Instance identity model (instanceId, URL, public key)
- [ ] Federation connection database schema
- [ ] Basic CONNECT/DISCONNECT protocol
@@ -588,6 +588,7 @@ Result:
- [ ] Query/Command message handling (stub)
**Testing:**
- Two local instances can connect
- Connection persists across restarts
- Disconnect cleans up properly
@@ -597,6 +598,7 @@ Result:
**Goal:** Enterprise SSO with RBAC
**Deliverables:**
- [ ] Authentik OIDC provider setup guide
- [ ] BetterAuth Authentik adapter
- [ ] Group → Role mapping
@@ -604,6 +606,7 @@ Result:
- [ ] Audit logging for auth events
**Testing:**
- Login via Authentik works
- Groups map to roles correctly
- Session isolation between workspaces
@@ -613,6 +616,7 @@ Result:
**Goal:** Full query/command capability
**Deliverables:**
- [ ] QUERY message type with response streaming
- [ ] COMMAND message type with async support
- [ ] EVENT subscription and delivery
@@ -620,6 +624,7 @@ Result:
- [ ] Error handling and retry logic
**Testing:**
- Master can query spoke calendar
- Master can create tasks on spoke
- Events push from spoke to master
@@ -630,6 +635,7 @@ Result:
**Goal:** Unified dashboard showing all instances
**Deliverables:**
- [ ] Connection manager UI
- [ ] Aggregated calendar view
- [ ] Aggregated task view
@@ -637,6 +643,7 @@ Result:
- [ ] Visual provenance tagging (color/icon per instance)
**Testing:**
- Dashboard shows data from multiple instances
- Clear visual distinction between sources
- Offline instance shows gracefully
@@ -646,12 +653,14 @@ Result:
**Goal:** Cross-instance agent coordination
**Deliverables:**
- [ ] Agent spawn command via federation
- [ ] Callback mechanism for results
- [ ] Agent status querying across instances
- [ ] Cross-instance task assignment
**Testing:**
- Home agent can spawn task on work instance
- Results callback works
- Agent health visible across instances
@@ -661,6 +670,7 @@ Result:
**Goal:** Production-ready for organizations
**Deliverables:**
- [ ] Admin console for federation management
- [ ] Compliance audit reports
- [ ] Rate limiting and quotas
@@ -673,24 +683,24 @@ Result:
### Semantic Versioning Policy
| Version | Meaning |
|---------|---------|
| `0.0.x` | Active development, breaking changes expected, internal use only |
| `0.1.0` | **MVP** — First user-testable release, core features working |
| `0.x.y` | Pre-stable iteration, API may change with notice |
| Version | Meaning |
| ------- | --------------------------------------------------------------------------- |
| `0.0.x` | Active development, breaking changes expected, internal use only |
| `0.1.0` | **MVP** — First user-testable release, core features working |
| `0.x.y` | Pre-stable iteration, API may change with notice |
| `1.0.0` | Stable release, public API contract, breaking changes require major version |
### Version Milestones
| Version | Target | Features |
|---------|--------|----------|
| 0.0.1 | Design | This document |
| 0.0.5 | Foundation | Basic federation protocol |
| 0.0.10 | Auth | Authentik integration |
| 0.1.0 | **MVP** | Single pane of glass, basic federation |
| 0.2.0 | Agents | Cross-instance agent coordination |
| 0.3.0 | Enterprise | Admin console, compliance |
| 1.0.0 | Stable | Production-ready, API frozen |
| Version | Target | Features |
| ------- | ---------- | -------------------------------------- |
| 0.0.1 | Design | This document |
| 0.0.5 | Foundation | Basic federation protocol |
| 0.0.10 | Auth | Authentik integration |
| 0.1.0 | **MVP** | Single pane of glass, basic federation |
| 0.2.0 | Agents | Cross-instance agent coordination |
| 0.3.0 | Enterprise | Admin console, compliance |
| 1.0.0 | Stable | Production-ready, API frozen |
---
@@ -804,18 +814,18 @@ DELETE /api/v1/federation/spoke/masters/:instanceId
## Glossary
| Term | Definition |
|------|------------|
| **Instance** | A single Mosaic Stack deployment |
| **Master** | Instance that initiates connection and queries spoke |
| **Spoke** | Instance that accepts connections and serves data |
| **Peer** | An instance that can be both master and spoke |
| **Federation** | Network of connected Mosaic Stack instances |
| **Scope** | Permission to perform specific actions (e.g., `calendar.read`) |
| **Capability** | API endpoint exposed by a spoke |
| **Provenance** | Source attribution for data (which instance it came from) |
| **Severance** | Clean disconnection with no data cleanup required |
| **IdP** | Identity Provider (e.g., Authentik) |
| Term | Definition |
| -------------- | -------------------------------------------------------------- |
| **Instance** | A single Mosaic Stack deployment |
| **Master** | Instance that initiates connection and queries spoke |
| **Spoke** | Instance that accepts connections and serves data |
| **Peer** | An instance that can be both master and spoke |
| **Federation** | Network of connected Mosaic Stack instances |
| **Scope** | Permission to perform specific actions (e.g., `calendar.read`) |
| **Capability** | API endpoint exposed by a spoke |
| **Provenance** | Source attribution for data (which instance it came from) |
| **Severance** | Clean disconnection with no data cleanup required |
| **IdP** | Identity Provider (e.g., Authentik) |
---
@@ -840,6 +850,7 @@ DELETE /api/v1/federation/spoke/masters/:instanceId
---
**Next Steps:**
1. Review and approve this design document
2. Create GitHub issues for Phase 1 tasks
3. Set up Authentik development instance