adaptive-bitmask 1.0.0 → 2.0.5
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.
- package/README.md +220 -255
- package/dist/ai/index.d.mts +16 -1
- package/dist/ai/index.d.ts +16 -1
- package/dist/ai/index.js +102 -6
- package/dist/ai/index.mjs +53 -5
- package/dist/{chunk-ZWEXRT33.mjs → chunk-QICJNGMQ.mjs} +53 -2
- package/dist/cli/index.d.mts +1 -0
- package/dist/cli/index.d.ts +1 -0
- package/dist/cli/index.js +378 -0
- package/dist/cli/index.mjs +355 -0
- package/dist/{coordinator-Df48t6yJ.d.mts → coordinator-CqBBHhXv.d.mts} +6 -1
- package/dist/{coordinator-Df48t6yJ.d.ts → coordinator-CqBBHhXv.d.ts} +6 -1
- package/dist/index.d.mts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +53 -2
- package/dist/index.mjs +1 -1
- package/package.json +17 -4
package/README.md
CHANGED
|
@@ -1,148 +1,118 @@
|
|
|
1
1
|
# adaptive-bitmask
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
`adaptive-bitmask` is a low-latency coordination protocol for multi-agent systems. It reduces coordination payloads to a fixed 24-byte binary format using dynamically pruned semantic bitmasks, with published benchmarks showing up to an 85x reduction versus JSON-based messaging.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
[](https://doi.org/10.5281/zenodo.18990535)
|
|
6
|
+
Current package version: `2.0.5`.
|
|
6
7
|
|
|
7
|
-
|
|
8
|
+
## Overview
|
|
8
9
|
|
|
9
|
-
|
|
10
|
+
- Fixed 24-byte wire format for coordination messages
|
|
11
|
+
- Sub-10ms coordination targets for multi-agent workloads
|
|
12
|
+
- Core package with no runtime dependencies
|
|
13
|
+
- Optional AI workflow integration through `adaptive-bitmask/ai`
|
|
14
|
+
- Built-in support for telemetry, transport helpers, and schema versioning
|
|
15
|
+
|
|
16
|
+
See `PRODUCTION_ROADMAP.md` for production validation details.
|
|
17
|
+
|
|
18
|
+
## Installation
|
|
19
|
+
|
|
20
|
+
Create a new project with the CLI:
|
|
10
21
|
|
|
11
22
|
```bash
|
|
12
|
-
|
|
23
|
+
npx create-swarm
|
|
13
24
|
```
|
|
14
25
|
|
|
15
|
-
|
|
26
|
+
The CLI can scaffold a project, configure parallel agent execution, add optional Vercel AI SDK integration, and set up a live dashboard.
|
|
16
27
|
|
|
17
|
-
|
|
18
|
-
- **📦 Zero Dependencies** - Core engine has no runtime dependencies
|
|
19
|
-
- **🛡️ Production Hardening** - Error handling, circuit breakers, graceful degradation
|
|
20
|
-
- **📊 Built-in Monitoring** - Health checks, metrics collection, structured logging
|
|
21
|
-
- **🔌 Transport Layers** - WebSocket and HTTP with production features
|
|
22
|
-
- **🔒 Enterprise Security** - Input validation, rate limiting, authentication hooks
|
|
28
|
+
Install the package directly:
|
|
23
29
|
|
|
24
|
-
|
|
30
|
+
```bash
|
|
31
|
+
npm install adaptive-bitmask
|
|
32
|
+
```
|
|
25
33
|
|
|
26
|
-
|
|
34
|
+
## Quick Start
|
|
27
35
|
|
|
28
36
|
```typescript
|
|
29
|
-
import {
|
|
37
|
+
import { CoordinationSession } from 'adaptive-bitmask/ai';
|
|
30
38
|
|
|
31
|
-
|
|
32
|
-
|
|
39
|
+
const session = new CoordinationSession({
|
|
40
|
+
features: ['price_up', 'volume_spike', 'trend_up'],
|
|
41
|
+
onLog: (log) => console.log(`[${log.agentId}] ${log.content}`),
|
|
42
|
+
});
|
|
33
43
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
{
|
|
37
|
-
name: 'Trading Bot Alpha',
|
|
38
|
-
llm: 'openai',
|
|
39
|
-
apiKey: process.env.OPENAI_API_KEY,
|
|
40
|
-
systemPrompt: `You are a quantitative trading analyst.
|
|
41
|
-
Analyze market data and respond ONLY with comma-separated features from:
|
|
42
|
-
price_up, price_down, volume_spike, momentum_strong, breakout_detected, EMERGENCY_halt
|
|
43
|
-
Focus on risk management and pattern recognition.`
|
|
44
|
-
},
|
|
45
|
-
{
|
|
46
|
-
name: 'Risk Manager Beta',
|
|
47
|
-
llm: 'anthropic',
|
|
48
|
-
apiKey: process.env.ANTHROPIC_API_KEY,
|
|
49
|
-
systemPrompt: `You are a risk management specialist.
|
|
50
|
-
Respond ONLY with comma-separated features from:
|
|
51
|
-
volatility_high, correlation_break, liquidity_dry, EMERGENCY_market_crash
|
|
52
|
-
Prioritize capital preservation.`
|
|
53
|
-
},
|
|
54
|
-
{
|
|
55
|
-
name: 'Sentiment Gamma',
|
|
56
|
-
llm: 'openai',
|
|
57
|
-
apiKey: process.env.OPENAI_API_KEY,
|
|
58
|
-
systemPrompt: `You are a market sentiment analyst.
|
|
59
|
-
Respond ONLY with comma-separated features from:
|
|
60
|
-
sentiment_bullish, sentiment_bearish, news_volume_high, social_trending
|
|
61
|
-
Focus on market psychology indicators.`
|
|
62
|
-
}
|
|
63
|
-
];
|
|
64
|
-
|
|
65
|
-
// 3. Get real LLM observations from each agent
|
|
66
|
-
async function getAgentObservations(agent, marketData) {
|
|
67
|
-
const response = await fetch(`https://api.${agent.llm}.com/v1/chat/completions`, {
|
|
68
|
-
method: 'POST',
|
|
69
|
-
headers: {
|
|
70
|
-
'Authorization': `Bearer ${agent.apiKey}`,
|
|
71
|
-
'Content-Type': 'application/json'
|
|
72
|
-
},
|
|
73
|
-
body: JSON.stringify({
|
|
74
|
-
model: agent.llm === 'anthropic' ? 'claude-3-haiku' : 'gpt-4o-mini',
|
|
75
|
-
messages: [
|
|
76
|
-
{ role: 'system', content: agent.systemPrompt },
|
|
77
|
-
{ role: 'user', content: `Analyze: ${marketData}` }
|
|
78
|
-
],
|
|
79
|
-
temperature: 0.3
|
|
80
|
-
})
|
|
81
|
-
});
|
|
82
|
-
|
|
83
|
-
const result = await response.json();
|
|
84
|
-
return result.choices[0].message.content.split(',').map(s => s.trim());
|
|
85
|
-
}
|
|
44
|
+
session.logThinking('Agent-1', 'Analyzing volatility clusters...');
|
|
45
|
+
session.report('Agent-1', ['price_up', 'volume_spike']);
|
|
86
46
|
|
|
87
|
-
|
|
88
|
-
const
|
|
89
|
-
|
|
90
|
-
agents.map(agent => getAgentObservations(agent, marketData))
|
|
91
|
-
);
|
|
47
|
+
const { decision: current } = session.peek();
|
|
48
|
+
const { decision, aggregatedFeatures } = session.decide();
|
|
49
|
+
```
|
|
92
50
|
|
|
93
|
-
|
|
94
|
-
const { decision, activeFeatures, latencyMs } = cognition.processSwarmTick(observations);
|
|
51
|
+
Key observability hooks:
|
|
95
52
|
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
53
|
+
- `session.logThinking(id, msg)` captures agent reasoning for dashboards or logs.
|
|
54
|
+
- `session.peek()` inspects mid-round consensus without clearing the buffer.
|
|
55
|
+
- `onLog` streams coordination events to a UI, logger, or database sink.
|
|
99
56
|
|
|
100
|
-
|
|
101
|
-
```bash
|
|
102
|
-
# Set your API keys
|
|
103
|
-
export OPENAI_API_KEY="your-openai-key"
|
|
104
|
-
export ANTHROPIC_API_KEY="your-anthropic-key"
|
|
57
|
+
## Features
|
|
105
58
|
|
|
106
|
-
|
|
107
|
-
|
|
59
|
+
- Sub-10ms coordination with benchmarked averages as low as `0.08ms`
|
|
60
|
+
- Zero runtime dependencies in the core engine
|
|
61
|
+
- Live dashboard support for monitoring agent reasoning and consensus
|
|
62
|
+
- Production-oriented error handling, circuit breakers, and graceful degradation
|
|
63
|
+
- Built-in health checks, metrics collection, and structured logging
|
|
64
|
+
- WebSocket and HTTP transport layers
|
|
65
|
+
- Security-oriented hooks for validation, rate limiting, and authentication
|
|
66
|
+
|
|
67
|
+
## Formal Verification (Lean 4)
|
|
68
|
+
|
|
69
|
+
The core mathematical foundations of the `adaptive-bitmask` protocol are mechanically proven using the Lean 4 theorem prover. This ensures absolute correctness for mission-critical properties.
|
|
70
|
+
|
|
71
|
+
**Benefits:**
|
|
72
|
+
- **Mathematical Certainty:** Core operations like bitwise consensus and threshold logic are proven correct for all possible inputs.
|
|
73
|
+
- **Protocol Safety:** Prevents integer overflow, undefined behavior, and logical inconsistencies in distributed decision-making.
|
|
74
|
+
- **Algorithmic Trust:** Provides formal guarantees that threshold calculations and aggregation functions strictly adhere to their specifications.
|
|
75
|
+
|
|
76
|
+
**Running the Verification:**
|
|
77
|
+
To run the Lean proofs locally, ensure you have Lean 4 and Lake installed (via `elan`), then run:
|
|
78
|
+
|
|
79
|
+
```bash
|
|
80
|
+
cd lean
|
|
81
|
+
lake build
|
|
108
82
|
```
|
|
109
83
|
|
|
110
|
-
|
|
111
|
-
- 🧠 **Real LLM intelligence** - Each agent uses actual AI reasoning
|
|
112
|
-
- 🔑 **Your API keys** - Complete control over authentication
|
|
113
|
-
- 📝 **Custom prompts** - Tailored for each domain (trading, risk, sentiment)
|
|
114
|
-
- 🌐 **Multi-provider** - Mix OpenAI, Anthropic, Google, local models
|
|
115
|
-
- ⚡ **Sub-10ms coordination** - Swarm decision in milliseconds
|
|
84
|
+
See the [Lean Verification Guide](LEAN_VERIFICATION.md) for full details on the formalized properties.
|
|
116
85
|
|
|
117
|
-
##
|
|
86
|
+
## Deployment Examples
|
|
118
87
|
|
|
119
88
|
### High-Frequency Trading
|
|
89
|
+
|
|
120
90
|
```typescript
|
|
121
|
-
// 1000 trading bots coordinating in 0.66ms
|
|
122
91
|
const tradingCognition = new SharedCognition({
|
|
123
|
-
arbiter: { executeThreshold: 0.60, emergencyOverride: true }
|
|
92
|
+
arbiter: { executeThreshold: 0.60, emergencyOverride: true },
|
|
124
93
|
});
|
|
125
94
|
```
|
|
126
95
|
|
|
127
96
|
### IoT Sensor Networks
|
|
97
|
+
|
|
128
98
|
```typescript
|
|
129
|
-
// 200 sensors reaching consensus in 0.20ms
|
|
130
99
|
const iotCognition = new SharedCognition({
|
|
131
|
-
schema: { emergencyPrefix: 'EMERGENCY_' }
|
|
100
|
+
schema: { emergencyPrefix: 'EMERGENCY_' },
|
|
132
101
|
});
|
|
133
102
|
```
|
|
134
103
|
|
|
135
104
|
### Chat Moderation Systems
|
|
105
|
+
|
|
136
106
|
```typescript
|
|
137
|
-
// 150 moderation agents deciding in 0.07ms
|
|
138
107
|
const moderationCognition = new SharedCognition({
|
|
139
|
-
arbiter: { executeThreshold: 0.70 }
|
|
108
|
+
arbiter: { executeThreshold: 0.70 },
|
|
140
109
|
});
|
|
141
110
|
```
|
|
142
111
|
|
|
143
|
-
##
|
|
112
|
+
## Deployment
|
|
144
113
|
|
|
145
114
|
### Docker
|
|
115
|
+
|
|
146
116
|
```dockerfile
|
|
147
117
|
FROM node:20-alpine
|
|
148
118
|
WORKDIR /app
|
|
@@ -153,6 +123,7 @@ CMD ["node", "dist/index.js"]
|
|
|
153
123
|
```
|
|
154
124
|
|
|
155
125
|
### Kubernetes
|
|
126
|
+
|
|
156
127
|
```yaml
|
|
157
128
|
apiVersion: apps/v1
|
|
158
129
|
kind: Deployment
|
|
@@ -166,83 +137,119 @@ spec:
|
|
|
166
137
|
template:
|
|
167
138
|
spec:
|
|
168
139
|
containers:
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
140
|
+
- name: adaptive-bitmask
|
|
141
|
+
image: adaptive-bitmask:latest
|
|
142
|
+
ports:
|
|
143
|
+
- containerPort: 8080
|
|
144
|
+
- containerPort: 8081
|
|
145
|
+
resources:
|
|
146
|
+
requests:
|
|
147
|
+
memory: "512Mi"
|
|
148
|
+
cpu: "250m"
|
|
149
|
+
limits:
|
|
150
|
+
memory: "1Gi"
|
|
151
|
+
cpu: "500m"
|
|
181
152
|
```
|
|
182
153
|
|
|
183
154
|
### Monitoring
|
|
155
|
+
|
|
184
156
|
```bash
|
|
185
|
-
# Health check
|
|
186
157
|
curl http://localhost:8081/api/health
|
|
187
|
-
|
|
188
|
-
# Metrics endpoint
|
|
189
158
|
curl http://localhost:8081/api/metrics
|
|
190
159
|
```
|
|
191
160
|
|
|
192
|
-
##
|
|
161
|
+
## Performance Benchmarks
|
|
162
|
+
|
|
163
|
+
### Coordination Benchmarks
|
|
193
164
|
|
|
194
165
|
| Agent Count | Avg Latency | Max Latency | Memory Usage |
|
|
195
|
-
|
|
196
|
-
| 100
|
|
197
|
-
| 500
|
|
198
|
-
| 1000
|
|
199
|
-
| 2000
|
|
166
|
+
| --- | --- | --- | --- |
|
|
167
|
+
| 100 | 0.09ms | 0.75ms | ~50MB |
|
|
168
|
+
| 500 | 0.27ms | 2.05ms | ~120MB |
|
|
169
|
+
| 1000 | 0.66ms | 3.12ms | ~200MB |
|
|
170
|
+
| 2000 | 1.26ms | 5.84ms | ~350MB |
|
|
200
171
|
|
|
201
|
-
|
|
172
|
+
Benchmarks were run on an M2 MacBook Pro with Node.js 20.
|
|
202
173
|
|
|
203
|
-
|
|
174
|
+
### Protocol Simulation
|
|
175
|
+
|
|
176
|
+
Measured on the protocol simulation across 1,000 trials:
|
|
177
|
+
|
|
178
|
+
| Operation | Mean | p99 |
|
|
179
|
+
| --- | --- | --- |
|
|
180
|
+
| Encode features | 2.0us | 3.9us |
|
|
181
|
+
| Serialize message | 0.5us | 0.8us |
|
|
182
|
+
| Aggregate (10 agents) | 84us | 122us |
|
|
183
|
+
| Score (weighted linear) | 15us | 26us |
|
|
184
|
+
| Full pipeline (no LLM) | 110us | 159us |
|
|
185
|
+
|
|
186
|
+
The protocol overhead is negligible relative to LLM inference; a representative run measured LLM latency at `6.8ms`, or `97.7%` of end-to-end time.
|
|
187
|
+
|
|
188
|
+
## Transport Layers
|
|
204
189
|
|
|
205
190
|
### WebSocket Transport
|
|
191
|
+
|
|
206
192
|
```typescript
|
|
207
193
|
import { createWebSocketTransport } from 'adaptive-bitmask';
|
|
208
194
|
|
|
209
195
|
const wsTransport = createWebSocketTransport({
|
|
210
196
|
port: 8080,
|
|
211
197
|
maxConnections: 1000,
|
|
212
|
-
enableCompression: true
|
|
198
|
+
enableCompression: true,
|
|
213
199
|
});
|
|
214
200
|
|
|
215
|
-
// Real-time bidirectional coordination
|
|
216
201
|
wsTransport.on('message', ({ agentId, message }) => {
|
|
217
202
|
console.log(`Agent ${agentId}:`, message);
|
|
218
203
|
});
|
|
219
204
|
```
|
|
220
205
|
|
|
221
206
|
### HTTP Transport
|
|
207
|
+
|
|
222
208
|
```typescript
|
|
223
209
|
import { createHttpTransport } from 'adaptive-bitmask';
|
|
224
210
|
|
|
225
211
|
const httpTransport = createHttpTransport({
|
|
226
212
|
port: 8081,
|
|
227
213
|
enableCors: true,
|
|
228
|
-
rateLimitPerMinute: 1000
|
|
214
|
+
rateLimitPerMinute: 1000,
|
|
229
215
|
});
|
|
230
216
|
|
|
231
|
-
// REST API for coordination
|
|
232
217
|
fetch('http://localhost:8081/api/coordinate', {
|
|
233
218
|
method: 'POST',
|
|
234
|
-
body: bitmaskMessage.toBytes()
|
|
219
|
+
body: bitmaskMessage.toBytes(),
|
|
235
220
|
});
|
|
236
221
|
```
|
|
237
222
|
|
|
238
|
-
|
|
223
|
+
### Transport-Agnostic Usage
|
|
224
|
+
|
|
225
|
+
The protocol is transport-agnostic. The 24-byte message format can be sent over WebSocket, gRPC, HTTP, or any other byte-capable transport.
|
|
226
|
+
|
|
227
|
+
```typescript
|
|
228
|
+
ws.send(msg.toBytes());
|
|
229
|
+
grpcStream.write({ payload: msg.toBytes() });
|
|
230
|
+
fetch('/coordinate', { body: msg.serialize() });
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
Optional helper for control-plane metadata:
|
|
234
|
+
|
|
235
|
+
```typescript
|
|
236
|
+
import { createEnvelope, decodeEnvelope } from 'adaptive-bitmask';
|
|
237
|
+
|
|
238
|
+
const envelope = createEnvelope(msg, schema.fingerprint, 'round-42');
|
|
239
|
+
const restored = decodeEnvelope(envelope, schema.fingerprint);
|
|
240
|
+
```
|
|
241
|
+
|
|
242
|
+
See [`examples/transport.ts`](./examples/transport.ts) for an end-to-end example.
|
|
243
|
+
|
|
244
|
+
## Monitoring and Observability
|
|
239
245
|
|
|
240
246
|
### Health Checks
|
|
247
|
+
|
|
241
248
|
```json
|
|
242
249
|
{
|
|
243
250
|
"status": "HEALTHY",
|
|
244
251
|
"uptime": 3600000,
|
|
245
|
-
"version": "1.
|
|
252
|
+
"version": "1.1.1",
|
|
246
253
|
"metrics": {
|
|
247
254
|
"messagesProcessed": 1000000,
|
|
248
255
|
"memoryUsageMB": 256,
|
|
@@ -252,138 +259,140 @@ fetch('http://localhost:8081/api/coordinate', {
|
|
|
252
259
|
```
|
|
253
260
|
|
|
254
261
|
### Metrics Collection
|
|
262
|
+
|
|
255
263
|
```typescript
|
|
256
264
|
import { MetricsCollector, Logger } from 'adaptive-bitmask';
|
|
257
265
|
|
|
258
266
|
const metrics = new MetricsCollector();
|
|
259
267
|
const logger = Logger.getInstance();
|
|
260
268
|
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
agentCount: 1000
|
|
269
|
+
metrics.recordCoordinationLatency(85);
|
|
270
|
+
logger.info('Coordination', 'Decision made', {
|
|
271
|
+
decision: 'EXECUTE',
|
|
272
|
+
agentCount: 1000,
|
|
266
273
|
});
|
|
267
274
|
```
|
|
268
275
|
|
|
269
|
-
##
|
|
276
|
+
## Error Handling and Recovery
|
|
270
277
|
|
|
271
278
|
```typescript
|
|
272
|
-
import {
|
|
273
|
-
ValidationError,
|
|
274
|
-
CircuitBreaker,
|
|
279
|
+
import {
|
|
280
|
+
ValidationError,
|
|
281
|
+
CircuitBreaker,
|
|
275
282
|
TimeoutManager,
|
|
276
|
-
RecoveryManager
|
|
283
|
+
RecoveryManager,
|
|
277
284
|
} from 'adaptive-bitmask';
|
|
278
285
|
|
|
279
|
-
|
|
280
|
-
const circuitBreaker = new CircuitBreaker(5); // 5 failures threshold
|
|
286
|
+
const circuitBreaker = new CircuitBreaker(5);
|
|
281
287
|
|
|
282
|
-
// Timeout protection
|
|
283
288
|
await TimeoutManager.withTimeout(
|
|
284
289
|
coordinationOperation(),
|
|
285
|
-
10000,
|
|
290
|
+
10000,
|
|
286
291
|
'swarm-coordination'
|
|
287
292
|
);
|
|
288
293
|
|
|
289
|
-
// Retry with exponential backoff
|
|
290
294
|
await RecoveryManager.withRetry(
|
|
291
295
|
failingOperation,
|
|
292
|
-
3,
|
|
293
|
-
1000
|
|
296
|
+
3,
|
|
297
|
+
1000
|
|
294
298
|
);
|
|
295
299
|
```
|
|
296
300
|
|
|
297
|
-
|
|
301
|
+
## Advanced Usage
|
|
298
302
|
|
|
299
|
-
|
|
303
|
+
For lower-level access to the protocol internals, the package exposes schema management, binary serialization, arbitration primitives, and transport helpers.
|
|
300
304
|
|
|
301
|
-
|
|
305
|
+
Protocol model:
|
|
302
306
|
|
|
303
|
-
Based on the [Adaptive Bitmask Protocol paper](https://
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
Layer
|
|
307
|
-
Layer
|
|
308
|
-
Layer
|
|
309
|
-
Layer 3: Arbiter ← Weighted scoring → EXECUTE / SYNTHESIZE / REJECT
|
|
307
|
+
Based on the [Adaptive Bitmask Protocol paper](https://zenodo.org/records/18990535) (Jiang, 2026):
|
|
308
|
+
```text
|
|
309
|
+
Layer 0: SchemaManager
|
|
310
|
+
Layer 1: Worker Agents
|
|
311
|
+
Layer 2: Coordinator
|
|
312
|
+
Layer 3: Arbiter
|
|
310
313
|
```
|
|
311
314
|
|
|
312
|
-
|
|
315
|
+
### 24-Byte Wire Format
|
|
316
|
+
|
|
313
317
|
| Offset | Type | Field |
|
|
314
|
-
|
|
318
|
+
| --- | --- | --- |
|
|
315
319
|
| 0-7 | uint64 | Feature bitmask |
|
|
316
320
|
| 8-11 | uint32 | Agent ID |
|
|
317
321
|
| 12-19 | int64 | Timestamp (ms) |
|
|
318
322
|
| 20-23 | uint32 | Schema version |
|
|
319
323
|
|
|
320
|
-
|
|
324
|
+
### Schema Management
|
|
321
325
|
|
|
322
|
-
|
|
326
|
+
Dynamic feature-to-bit mapping supports frequency-based pruning. Emergency features in bits `56-63` are never pruned regardless of activation frequency.
|
|
323
327
|
|
|
324
328
|
```typescript
|
|
325
329
|
const schema = new SchemaManager({ emergencyPrefix: 'EMERGENCY_' });
|
|
326
330
|
schema.registerAll(myFeatures);
|
|
327
331
|
schema.recordActivations(observedFeatures);
|
|
328
|
-
schema.prune();
|
|
332
|
+
schema.prune();
|
|
329
333
|
|
|
330
|
-
// Paper-aligned collision math utilities
|
|
331
334
|
const p = schema.theoreticalCollisionRate;
|
|
332
|
-
// p = 1 - (1 - 1/64)^(m - 1), where m = activeFeatureCount
|
|
333
|
-
|
|
334
335
|
const excluded = schema.expectedExcludedFeatures(80);
|
|
335
|
-
// E[excluded] = m - 64 * (1 - (1 - 1/64)^m)
|
|
336
336
|
```
|
|
337
337
|
|
|
338
|
-
|
|
338
|
+
### Schema Distribution
|
|
339
|
+
|
|
340
|
+
Deterministic schema export and import allow compatibility checks across nodes.
|
|
339
341
|
|
|
340
342
|
```typescript
|
|
341
343
|
const exported = schema.exportSchema();
|
|
342
|
-
// Send exported JSON through your control plane
|
|
343
344
|
|
|
344
345
|
const replica = new SchemaManager();
|
|
345
346
|
replica.importSchema(exported);
|
|
346
|
-
// replica.fingerprint === schema.fingerprint
|
|
347
347
|
```
|
|
348
348
|
|
|
349
|
-
|
|
349
|
+
### Binary Serialization
|
|
350
|
+
|
|
351
|
+
Messages serialize to exactly 24 bytes and round-trip through `serialize()` and `deserialize()`.
|
|
350
352
|
|
|
351
353
|
```typescript
|
|
352
|
-
const bytes = msg.toBytes();
|
|
354
|
+
const bytes = msg.toBytes();
|
|
353
355
|
const restored = BitmaskMessage.deserialize(bytes);
|
|
354
356
|
```
|
|
355
357
|
|
|
356
|
-
|
|
358
|
+
### Weighted Scoring
|
|
359
|
+
|
|
360
|
+
Importance weights can be configured by bit position, and domain-specific presets are included.
|
|
357
361
|
|
|
358
362
|
```typescript
|
|
359
363
|
import { createFinancialArbiter, createRoboticArbiter } from 'adaptive-bitmask';
|
|
360
364
|
|
|
361
|
-
const
|
|
362
|
-
const
|
|
365
|
+
const financialArbiter = createFinancialArbiter();
|
|
366
|
+
const roboticArbiter = createRoboticArbiter();
|
|
363
367
|
```
|
|
364
368
|
|
|
365
|
-
|
|
369
|
+
### Strategy Arbitration
|
|
370
|
+
|
|
371
|
+
Strategy candidates can be ranked with `scoreStrategies()` using threshold-based lead and rejection criteria.
|
|
366
372
|
|
|
367
373
|
```typescript
|
|
368
|
-
const result = arbiter.scoreStrategies(
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
374
|
+
const result = arbiter.scoreStrategies(
|
|
375
|
+
[
|
|
376
|
+
{ id: 'trend', mask: trendMask, confidence: trendConf },
|
|
377
|
+
{ id: 'mean_revert', mask: mrMask, confidence: mrConf },
|
|
378
|
+
{ id: 'breakout', mask: boMask, confidence: boConf },
|
|
379
|
+
],
|
|
380
|
+
{
|
|
381
|
+
leadThreshold: 0.15,
|
|
382
|
+
rejectThreshold: 0.40,
|
|
383
|
+
}
|
|
384
|
+
);
|
|
376
385
|
```
|
|
377
386
|
|
|
378
|
-
Legacy compatibility
|
|
387
|
+
Legacy compatibility is preserved through `arbiter.score(mask, confidence?)`.
|
|
379
388
|
|
|
380
|
-
|
|
389
|
+
### Bitwise Primitives
|
|
381
390
|
|
|
382
391
|
```typescript
|
|
383
392
|
import { setBit, popcount, merge, delta, hammingDistance } from 'adaptive-bitmask';
|
|
384
393
|
```
|
|
385
394
|
|
|
386
|
-
|
|
395
|
+
### Strict Encoding
|
|
387
396
|
|
|
388
397
|
```typescript
|
|
389
398
|
const { mask } = encode(features, schema.featureToBit, {
|
|
@@ -391,16 +400,16 @@ const { mask } = encode(features, schema.featureToBit, {
|
|
|
391
400
|
});
|
|
392
401
|
```
|
|
393
402
|
|
|
394
|
-
|
|
403
|
+
### Stale Schema Policy
|
|
395
404
|
|
|
396
405
|
```typescript
|
|
397
406
|
const coordinator = new Coordinator({
|
|
398
407
|
schemaVersion: schema.version,
|
|
399
|
-
staleMessagePolicy: 'drop',
|
|
408
|
+
staleMessagePolicy: 'drop',
|
|
400
409
|
});
|
|
401
410
|
```
|
|
402
411
|
|
|
403
|
-
|
|
412
|
+
### Telemetry Hooks
|
|
404
413
|
|
|
405
414
|
```typescript
|
|
406
415
|
const coordinator = new Coordinator({
|
|
@@ -420,69 +429,13 @@ const arbiter = new Arbiter({
|
|
|
420
429
|
});
|
|
421
430
|
```
|
|
422
431
|
|
|
423
|
-
## Performance
|
|
424
|
-
|
|
425
|
-
Measured on the protocol simulation (1,000 trials):
|
|
426
|
-
|
|
427
|
-
| Operation | Mean | p99 |
|
|
428
|
-
|-----------|------|-----|
|
|
429
|
-
| Encode features | 2.0μs | 3.9μs |
|
|
430
|
-
| Serialize message | 0.5μs | 0.8μs |
|
|
431
|
-
| Aggregate (10 agents) | 84μs | 122μs |
|
|
432
|
-
| Score (weighted linear) | 15μs | 26μs |
|
|
433
|
-
| **Full pipeline (no LLM)** | **110μs** | **159μs** |
|
|
434
|
-
|
|
435
|
-
The protocol overhead is negligible. LLM inference (6.8ms) accounts for 97.7% of end-to-end latency.
|
|
436
|
-
|
|
437
|
-
## Migration Notes (`0.1.x` -> `0.2.0-rc.0`)
|
|
438
|
-
|
|
439
|
-
`BitmaskMessage` validation is now strict:
|
|
440
|
-
- `deserialize()` now requires exactly `24` bytes (not "at least 24")
|
|
441
|
-
- constructor throws for out-of-range `mask`, `agentId`, `schemaVersion`, or unsafe `timestampMs`
|
|
442
|
-
|
|
443
|
-
Coordinator behavior adds explicit stale handling:
|
|
444
|
-
- new config: `staleMessagePolicy: 'accept' | 'warn' | 'drop'`
|
|
445
|
-
- aggregate output now includes `droppedStaleMessages`
|
|
446
|
-
|
|
447
|
-
Schema coordination helpers are now available:
|
|
448
|
-
- `schema.exportSchema()` / `schema.importSchema(...)`
|
|
449
|
-
- deterministic `schema.fingerprint` for compatibility checks
|
|
450
|
-
|
|
451
|
-
## Transport
|
|
452
|
-
|
|
453
|
-
This library is **transport-agnostic**. The 24-byte message format works with any transport layer:
|
|
454
|
-
|
|
455
|
-
```typescript
|
|
456
|
-
// WebSocket
|
|
457
|
-
ws.send(msg.toBytes());
|
|
458
|
-
|
|
459
|
-
// gRPC (as bytes field)
|
|
460
|
-
grpcStream.write({ payload: msg.toBytes() });
|
|
461
|
-
|
|
462
|
-
// HTTP (base64 or raw body)
|
|
463
|
-
fetch('/coordinate', { body: msg.serialize() });
|
|
464
|
-
|
|
465
|
-
// Vercel AI SDK (coming soon)
|
|
466
|
-
```
|
|
467
|
-
|
|
468
|
-
Optional helper for control-plane metadata:
|
|
469
|
-
|
|
470
|
-
```typescript
|
|
471
|
-
import { createEnvelope, decodeEnvelope } from 'adaptive-bitmask';
|
|
472
|
-
|
|
473
|
-
const envelope = createEnvelope(msg, schema.fingerprint, 'round-42');
|
|
474
|
-
const restored = decodeEnvelope(envelope, schema.fingerprint);
|
|
475
|
-
```
|
|
476
|
-
|
|
477
|
-
See [examples/transport.ts](/Users/hjiang/Developer/adaptive-bitmask/examples/transport.ts) for end-to-end transport payload patterns.
|
|
478
|
-
|
|
479
432
|
## Benchmarking
|
|
480
433
|
|
|
481
434
|
```bash
|
|
482
435
|
npm run benchmark
|
|
483
436
|
```
|
|
484
437
|
|
|
485
|
-
|
|
438
|
+
This writes benchmark results to `benchmarks/latest.json`.
|
|
486
439
|
|
|
487
440
|
```bash
|
|
488
441
|
npm run benchmark:run
|
|
@@ -490,35 +443,47 @@ npm run benchmark:check
|
|
|
490
443
|
```
|
|
491
444
|
|
|
492
445
|
`benchmark:check` fails if an operation regresses beyond both thresholds:
|
|
493
|
-
|
|
494
|
-
-
|
|
495
|
-
-
|
|
446
|
+
|
|
447
|
+
- Relative: `BENCH_MAX_REGRESSION_PCT` (default `40`)
|
|
448
|
+
- Absolute: `BENCH_MAX_ABS_REGRESSION_US` (default `1.5`)
|
|
449
|
+
- Baseline file: `BENCH_BASELINE_PATH` (default `benchmarks/baseline.json`)
|
|
450
|
+
|
|
451
|
+
## Migration Notes
|
|
452
|
+
|
|
453
|
+
Changes introduced in the `0.2.0-rc.0` line:
|
|
454
|
+
|
|
455
|
+
- `BitmaskMessage.deserialize()` now requires exactly `24` bytes.
|
|
456
|
+
- Constructors throw for out-of-range `mask`, `agentId`, `schemaVersion`, or unsafe `timestampMs`.
|
|
457
|
+
- Coordinators support `staleMessagePolicy: 'accept' | 'warn' | 'drop'`.
|
|
458
|
+
- Aggregate output now includes `droppedStaleMessages`.
|
|
459
|
+
- `schema.exportSchema()` and `schema.importSchema(...)` are available.
|
|
460
|
+
- `schema.fingerprint` provides deterministic compatibility checks.
|
|
496
461
|
|
|
497
462
|
## API Reference
|
|
498
463
|
|
|
499
464
|
### Bitmask Primitives
|
|
500
465
|
|
|
501
|
-
`empty()
|
|
466
|
+
`empty()`, `setBit(mask, pos)`, `clearBit(mask, pos)`, `testBit(mask, pos)`, `popcount(mask)`, `activeBits(mask)`, `forEachSetBit(mask, fn)`, `merge(a, b)`, `intersect(a, b)`, `delta(prev, next)`, `hammingDistance(a, b)`, `hasEmergency(mask)`, `toBytes(mask)`, `fromBytes(buf)`, `encode(features, schema, options?)`, `decode(mask, reverseSchema)`
|
|
502
467
|
|
|
503
468
|
### SchemaManager
|
|
504
469
|
|
|
505
|
-
`new SchemaManager(config?)
|
|
470
|
+
`new SchemaManager(config?)`, `.register(feature)`, `.registerAll(features)`, `.recordActivations(features)`, `.prune()`, `.snapshot()`, `.exportSchema()`, `.importSchema(exported)`, `.expectedExcludedFeatures(featureCount?)`, `.theoreticalCollisionRate`, `.fingerprint`, `.featureToBit`, `.bitToFeatures`, `.version`
|
|
506
471
|
|
|
507
472
|
### BitmaskMessage
|
|
508
473
|
|
|
509
|
-
`new BitmaskMessage(data)
|
|
474
|
+
`new BitmaskMessage(data)`, `BitmaskMessage.now(mask, agentId, version)`, `.serialize()`, `.toBytes()`, `BitmaskMessage.deserialize(buf)`, `.sizeBytes`, `.compressionVsJson`
|
|
510
475
|
|
|
511
476
|
### Arbiter
|
|
512
477
|
|
|
513
|
-
`new Arbiter(config?)
|
|
478
|
+
`new Arbiter(config?)`, `.score(mask, confidence?)`, `.scoreStrategies(candidates, options?)`, `.scoreMessages(messages, version?)`, `.setWeight(pos, weight)`, `createFinancialArbiter()`, `createRoboticArbiter()`
|
|
514
479
|
|
|
515
480
|
### Coordinator
|
|
516
481
|
|
|
517
|
-
`new Coordinator(config?)
|
|
482
|
+
`new Coordinator(config?)`, `.startRound()`, `.receive(msg)`, `.receiveAll(msgs)`, `.aggregate()`, `.schemaVersion`
|
|
518
483
|
|
|
519
484
|
### Transport Envelope
|
|
520
485
|
|
|
521
|
-
`createEnvelope(msg, schemaFingerprint, roundId?)
|
|
486
|
+
`createEnvelope(msg, schemaFingerprint, roundId?)`, `decodeEnvelope(envelope, expectedSchemaFingerprint?)`
|
|
522
487
|
|
|
523
488
|
## License
|
|
524
489
|
|