This commit is contained in:
Raven Scott
2026-05-20 23:14:20 -04:00
parent a2e7da7b5b
commit a020270cb1
11 changed files with 271 additions and 310 deletions
@@ -1,40 +1,36 @@
# hyper-p2p-task-orchestrator
HyperP2PTaskOrchestrator Novel distributed task orchestration primitive for Bare/Pear P2P. - DAG task dependencies & priority scheduling - Ed255255 signed tasks and results for authenticity
Distributed task DAG orchestration: signed tasks, dependencies, deadlines, retries, vector-clock causal events, P2P task gossip.
**Category:** Agents & workflows
**Composes with:** `hyper-p2p-agent-memory`, `hyper-p2p-workflow-graph`
**Composes with:** `hyper-p2p-vector-clock`, `hyper-p2p-activity-queue`, `hyper-p2p-capabilities`
**Protocol:** `hyper-p2p-task-orchestrator/v1`
## When to use
Multi-peer apps that need agents & workflows over a shared Hyperswarm topic.
Multi-peer agent systems that submit, assign, and complete typed tasks with dependency edges over a shared topic.
## When not to use
Single-process tools with no P2P topic (use local APIs only or skip `ready()`).
Single-node job queues with no P2P coordination (use `hyper-p2p-activity-queue` locally).
## Quick start
```js
const { HyperP2PTaskOrchestrator } = require('hyper-p2p-task-orchestrator')
const topic = process.argv[2] // 64-char hex or string
const mod = new HyperP2PTaskOrchestrator({ topic, enableBackgroundTimers: false })
await mod.ready() // joins swarm when topic set
// ... application logic ...
await mod.close()
const orch = new HyperP2PTaskOrchestrator({ topic: 'tasks' })
await orch.ready()
await orch.submitTask({ type: 'index', payload: { path: '/' } })
await orch.close()
```
## Docs
- [docs/api.md](docs/api.md) — constructor, methods, events, errors
- [docs/architecture.md](docs/architecture.md) — wire types, state, composition
- [../_shared/PRODUCTION.md](../../_shared/PRODUCTION.md) — production checklist
- [../_shared/DOC_STANDARDS.md](../../_shared/DOC_STANDARDS.md) — documentation standards
- Integration: [`../../real_tests/integration/`](../../../real_tests/integration/) — `task-orchestrator-two-node.js`
- [docs/api.md](docs/api.md)
- [docs/architecture.md](docs/architecture.md)
- Integration: [`../../../real_tests/integration/task-orchestrator-two-node.js`](../../../real_tests/integration/task-orchestrator-two-node.js)
## Test
@@ -2,124 +2,104 @@
**Protocol:** `hyper-p2p-task-orchestrator/v1`
**Export:** `HyperP2PTaskOrchestrator`
**Export:** `HyperP2PTaskOrchestrator`, `TASK_PROTOCOL`
## Overview
HyperP2PTaskOrchestrator Novel distributed task orchestration primitive for Bare/Pear P2P. - DAG task dependencies & priority scheduling - Ed255255 signed tasks and results for authenticity
`HyperP2PTaskOrchestrator` manages a signed task graph with priorities, deadlines, dependency gates, execution hooks, JSON file persistence, and Protomux gossip for remote task submission. Integrates `HyperP2PVectorClock` for causal lifecycle metadata.
## Constructor
```js
const mod = new HyperP2PTaskOrchestrator(opts)
const orch = new HyperP2PTaskOrchestrator(opts)
```
| Option | Type | Default | Description |
|--------|------|---------|-------------|
| `keyPair` | KeyPair | random Ed25519 | keyPair |
| `storageDir` | `<cwd>/{module}-storage` | `<cwd>/{module}-storage` | Hypercore/Hyperbee storage root |
| `defaultDeadlineMs` | varies | DEFAULT_DEADLINE_MS | defaultDeadline (ms) |
| `topic` | varies | null | topic |
| `keyPair` | `KeyPair` | random | Task signing identity |
| `topic` | `string` | `null` | Hyperswarm topic for gossip |
| `storageDir` | `string` | `{cwd}/hyper-p2p-task-orchestrator-storage` | `tasks.json` persistence |
| `defaultDeadlineMs` | `number` | `300000` | Default task TTL |
| `clock` | `HyperP2PVectorClock` | new instance | Causal clock helper |
## Methods
### `ready()`
### `ready()`
- **Returns:** `Promise`
- **Throws:** — (none documented in method body)
Loads storage, joins swarm when `topic` set, starts expiry cleanup interval.
- **Returns:** `Promise<void>`
- **Emits:** `ready`, `p2p-ready`
### `submitTask(taskSpec)`
- **Returns:** `Promise`
Creates signed pending task; records dependencies.
- **Parameters:** `{ type, payload?, owner?, priority?, deadline?, deps? }`
- **Returns:** `Promise<task>`
- **Throws:**
- `Error: Task signing failed`
- `Error: taskSpec.type required`
- `Error: Task signing failed`
### `assignTask(taskId, assignee = null)`
### `assignTask(taskId, assignee?)`
- **Returns:** `Promise`
- **Throws:**
- `Error: Task not assignable`
- `Error: Task not found`
Marks task `assigned` when dependencies satisfied.
### `completeTask(taskId, resultData = {}, success = true)`
- **Returns:** `Promise<task | null>`
- **Returns:** `Promise`
- **Throws:**
- `Error: Task not found`
### `completeTask(taskId, resultData?, success?)`
### `getTask(taskId)`
Stores result, updates status `completed` or `failed`, unblocks dependents.
- **Returns:** `Promise`
- **Throws:** — (none documented in method body)
- **Returns:** `Promise<result>`
### `queryTasks(filter = {})`
### `getTask(taskId)` / `queryTasks(filter)`
- **Returns:** `Promise`
- **Throws:** — (none documented in method body)
Read single task or filter by `status`, `type`, `owner`.
### `registerExecutionHook(taskType, handler)`
### `registerExecutionHook(taskType, handler)` / `executeTask(taskId)`
- **Returns:** `Promise`
- **Throws:**
- `Error: handler must be function`
Register per-type executor; run when assigned.
### `executeTask(taskId)`
### `getMetrics()` / `getStats()`
- **Returns:** `Promise`
- **Throws:**
- `Error: Task must be assigned`
Returns `metrics` counters + `{ ops, errors }`.
### `getMetrics(—)`
### `close()`
- **Returns:** `value`
- **Throws:** — (none documented in method body)
### `getStats(—)`
- **Returns:** `object`
- **Throws:** — (none documented in method body)
### `close(—)`
Clears timers, destroys swarm, persists tasks.
- **Returns:** `Promise<void>`
- **Throws:** — (none documented in method body)
## Task object
| Field | Description |
|-------|-------------|
| `taskId` | Hex id |
| `type` | Handler type string |
| `status` | `pending` \| `assigned` \| `completed` \| `failed` \| `expired` |
| `priority` | Higher runs first in queries |
| `deadline` | Unix ms |
| `deps` | Prerequisite task ids |
| `signature` | Base64 Ed25519 |
| `causal` | Vector clock snapshot at submit |
## Events
| Event | Payload |
|-------|---------|
| `closed` | no payload |
| `error` | err |
| `hook:registered` | payload object |
| `p2p-ready` | no payload |
| `ready` | no payload |
| `task:assigned` | task |
| `task:completed` | payload object |
| `task:deps-ready` | depTask |
| `task:error` | error |
| `task:expired` | task |
| `task:gossiped` | task |
| `task:retry` | task |
| `task:submitted` | task |
`ready`, `p2p-ready`, `task:submitted`, `task:assigned`, `task:completed`, `task:failed`, `task:expired`, `task:retry`, `task:received`, `error`
## getStats()
## Wire messages
Returns `{ ...this._stats }` — typically `ops`, `errors`, and module-specific counters (`created`, `relays`, `open`, `peers`, etc.).
Library-only modules may include `mode: 'local'`.
## Errors
Stable message substrings: see [`../_shared/ERROR_CODES.md`](../../_shared/ERROR_CODES.md).
| type | fields |
|------|--------|
| `task` | `task` (full signed task object) |
## P2P
When `topic` is set, `ready()` joins Hyperswarm and opens Protomux `hyper-p2p-task-orchestrator/v1`.
Uses `initModuleSwarm` from `p2p-bare.js` with protocol `hyper-p2p-task-orchestrator/v1`.
## Testing
```bash
npm install && npm test
npm test
```
Integration: [`../../real_tests/integration/task-orchestrator-two-node.js`](../../../real_tests/integration/task-orchestrator-two-node.js)
@@ -1,43 +1,29 @@
# Architecture: hyper-p2p-task-orchestrator
**Category:** Agents & workflows
**Category:** `agents-workflows` · **Protocol:** `hyper-p2p-task-orchestrator/v1`
```mermaid
flowchart LR
App[Application] --> Mod[HyperP2PTaskOrchestrator]
Mod --> Mux[Protomux hyper-p2p-task-orchestrator/v1]
Mux --> Swarm[Hyperswarm]
```
## Role
## Sequence (P2P)
```mermaid
sequenceDiagram
participant App
participant Mod as Module
participant SW as Hyperswarm
participant Peer
App->>Mod: ready(topic)
Mod->>SW: join(topic)
SW->>Peer: connection
Mod->>Peer: gossip / Protomux
Peer-->>Mod: onmessage
Mod-->>App: emit(event)
```
Signed DAG task orchestration with file persistence, dependency tracking, expiry/retry loop, and task gossip.
## Wire messages
| type | fields | direction | behavior |
|------|--------|-----------|----------|
| `task` | task | gossip | Handled in onmessage / gossipSend |
| type | direction | fields | behavior |
|------|-----------|--------|----------|
| `task` | gossip | `task` | Insert into `tasks` map; emit `task:received` |
## State model
- In-memory `Map` / `Set` structures for hot path
- Optional Hyperbee/Hypercore persistence when `storageDir` or `memoryOnly` is configured
- `close()` tears down swarm, timers, and clears ephemeral state
| Map | Content |
|-----|---------|
| `tasks` | taskId → task record |
| `results` | taskId → result blob |
| `dependencies` | taskId → Set of dep ids |
| `reverseDeps` | depId → dependent task ids |
| `executionHooks` | taskType → async handler |
Cleanup interval marks expired tasks, retries up to `MAX_RETRIES` (3).
## Composition
Composes with: `hyper-p2p-agent-memory`, `hyper-p2p-workflow-graph`.
`hyper-p2p-vector-clock` for causal fields; `hyper-p2p-activity-queue` for local scheduling; capabilities for gated execution.
@@ -0,0 +1,11 @@
require('bare-process/global')
const { HyperP2PTaskOrchestrator } = require('../index.js')
async function main () {
const orch = new HyperP2PTaskOrchestrator()
await orch.ready()
const task = await orch.submitTask({ type: 'demo', payload: { n: 1 } })
console.log('[task-orchestrator]', task.taskId, orch.getMetrics())
await orch.close()
}
main().catch(console.error)