adaptive-bitmask 1.0.0 → 2.0.4

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 CHANGED
@@ -1,148 +1,118 @@
1
1
  # adaptive-bitmask
2
2
 
3
- **The Sub-10ms Shared Cognition Engine for Multi-Agent Systems.**
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
- Achieve an **85x bandwidth reduction** (753 bytes -> exactly 24 bytes) for multi-agent coordination. Instead of shipping bloated JSON payloads between agents, `adaptive-bitmask` uses dynamically-pruned semantic bitmasks to achieve sub-10ms coordination latency.
5
+ [![DOI](https://zenodo.org/badge/DOI/10.5281/zenodo.18990535.svg)](https://doi.org/10.5281/zenodo.18990535)
6
+ Current package version: `2.0.0`.
6
7
 
7
- **🎉 Production-Ready v1.0.0-rc.1** - [93.3% production test pass rate](./PRODUCTION_ROADMAP.md) with sub-millisecond coordination for 1000+ agents.
8
+ ## Overview
8
9
 
9
- **To view the paper: "Go to files" -> "Adaptive Protocol(5)"**
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
- npm install adaptive-bitmask
23
+ npx create-swarm
13
24
  ```
14
25
 
15
- ## Production Features
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
- - **🚀 Sub-10ms Coordination** - 0.08ms average latency, 1.26ms for 2000 agents
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
- ## Quick Start (Real LLM Integration)
30
+ ```bash
31
+ npm install adaptive-bitmask
32
+ ```
25
33
 
26
- Coordinate a swarm of AI agents with different LLM providers, custom prompts, and your own API keys:
34
+ ## Quick Start
27
35
 
28
36
  ```typescript
29
- import { SharedCognition } from 'adaptive-bitmask';
37
+ import { CoordinationSession } from 'adaptive-bitmask/ai';
30
38
 
31
- // 1. Initialize the coordination engine
32
- const cognition = new SharedCognition();
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
- // 2. Define your agents with custom prompts and API keys
35
- const agents = [
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
- // 4. Run real-time coordination with live market data
88
- const marketData = "BTC surging 8% in 5 minutes with high volume";
89
- const observations = await Promise.all(
90
- agents.map(agent => getAgentObservations(agent, marketData))
91
- );
47
+ const { decision: current } = session.peek();
48
+ const { decision, aggregatedFeatures } = session.decide();
49
+ ```
92
50
 
93
- // 5. That's it - real LLM-powered swarm intelligence!
94
- const { decision, activeFeatures, latencyMs } = cognition.processSwarmTick(observations);
51
+ Key observability hooks:
95
52
 
96
- console.log(`🤖 Swarm Decision: ${decision} in ${latencyMs.toFixed(2)}ms`);
97
- console.log(`📊 Consensus Features:`, activeFeatures);
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
- **Environment Setup:**
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
- # Install the package
107
- npm install adaptive-bitmask
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
- **Key Benefits:**
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
- ## 🌐 Real-World Deployments
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
- ## 🔧 Production Deployment
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
- - name: adaptive-bitmask
170
- image: adaptive-bitmask:latest
171
- ports:
172
- - containerPort: 8080 # WebSocket
173
- - containerPort: 8081 # HTTP API
174
- resources:
175
- requests:
176
- memory: "512Mi"
177
- cpu: "250m"
178
- limits:
179
- memory: "1Gi"
180
- cpu: "500m"
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
- ## 📊 Performance Benchmarks
161
+ ## Performance Benchmarks
162
+
163
+ ### Coordination Benchmarks
193
164
 
194
165
  | Agent Count | Avg Latency | Max Latency | Memory Usage |
195
- |-------------|-------------|-------------|--------------|
196
- | 100 | 0.09ms | 0.75ms | ~50MB |
197
- | 500 | 0.27ms | 2.05ms | ~120MB |
198
- | 1000 | 0.66ms | 3.12ms | ~200MB |
199
- | 2000 | 1.26ms | 5.84ms | ~350MB |
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
- *All benchmarks run on M2 MacBook Pro with Node.js v20*
172
+ Benchmarks were run on an M2 MacBook Pro with Node.js 20.
202
173
 
203
- ## 🛠️ Transport Layers
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
- ## 📈 Monitoring & Observability
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.0.0-rc.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
- // Automatic performance tracking
262
- metrics.recordCoordinationLatency(85); // microseconds
263
- logger.info('Coordination', 'Decision made', {
264
- decision: 'EXECUTE',
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
- ## 🚨 Error Handling & Recovery
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
- // Circuit breaker for resilience
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, // 10s timeout
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, // max retries
293
- 1000 // base delay
296
+ 3,
297
+ 1000
294
298
  );
295
299
  ```
296
300
 
297
- ---
301
+ ## Advanced Usage
298
302
 
299
- ## Advanced Usage / Internal Engine
303
+ For lower-level access to the protocol internals, the package exposes schema management, binary serialization, arbitration primitives, and transport helpers.
300
304
 
301
- For hardcore engineers who want direct access to the raw mathematical primitives and binary serialization logic.
305
+ Protocol model:
302
306
 
303
- Based on the [Adaptive Bitmask Protocol paper](https://arxiv.org/abs/TODO) (Jiang, 2026):
304
-
305
- ```
306
- Layer 0: SchemaManager ← Feature-to-bit mappings, frequency pruning
307
- Layer 1: Worker Agents ← Encode observations as 64-bit bitmasks
308
- Layer 2: Coordinator ← OR-aggregate, compute per-bit confidence
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
- **24-byte wire format:**
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
- ## Key Features
324
+ ### Schema Management
321
325
 
322
- **Schema Management** — Dynamic feature-to-bit mapping with frequency-based pruning. Emergency features (bits 56-63) are never pruned regardless of activation frequency.
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(); // retains top-56 by frequency + all emergency features
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
- **Schema Distribution** — Deterministic schema export/import with fingerprinting for cross-node compatibility checks.
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
- **Binary Serialization** — Messages serialize to exactly 24 bytes. Round-trips through `serialize()` / `deserialize()` for any transport layer.
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(); // Uint8Array(24)
354
+ const bytes = msg.toBytes();
353
355
  const restored = BitmaskMessage.deserialize(bytes);
354
356
  ```
355
357
 
356
- **Weighted Scoring** — Configurable importance weights per bit position. Domain-specific presets included.
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 arbiter = createFinancialArbiter(); // emergency bits weighted 0.45
362
- const arbiter = createRoboticArbiter(); // obstacle detection weighted 0.30
365
+ const financialArbiter = createFinancialArbiter();
366
+ const roboticArbiter = createRoboticArbiter();
363
367
  ```
364
368
 
365
- **Paper-Canonical Strategy Arbitration (Section 6)** — Rank strategy candidates by `s_final = 0.6*s_raw + 0.4*c`, then apply lead/synthesis thresholds.
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
- { id: 'trend', mask: trendMask, confidence: trendConf },
370
- { id: 'mean_revert', mask: mrMask, confidence: mrConf },
371
- { id: 'breakout', mask: boMask, confidence: boConf },
372
- ], {
373
- leadThreshold: 0.15,
374
- rejectThreshold: 0.40,
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: `arbiter.score(mask, confidence?)` remains unchanged for existing integrations.
387
+ Legacy compatibility is preserved through `arbiter.score(mask, confidence?)`.
379
388
 
380
- **Bitwise Primitives** — Full suite of 64-bit operations using BigInt for precision.
389
+ ### Bitwise Primitives
381
390
 
382
391
  ```typescript
383
392
  import { setBit, popcount, merge, delta, hammingDistance } from 'adaptive-bitmask';
384
393
  ```
385
394
 
386
- **Strict Encoding Mode** — Fail fast on unknown features to catch schema drift at ingestion time.
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
- **Stale Schema Policy** — Choose how coordinators handle version-mismatched messages.
403
+ ### Stale Schema Policy
395
404
 
396
405
  ```typescript
397
406
  const coordinator = new Coordinator({
398
407
  schemaVersion: schema.version,
399
- staleMessagePolicy: 'drop', // 'accept' | 'warn' | 'drop'
408
+ staleMessagePolicy: 'drop',
400
409
  });
401
410
  ```
402
411
 
403
- **Telemetry Hooks** — Attach runtime callbacks for coordination and decision metrics.
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
- Writes benchmark results to `benchmarks/latest.json`.
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
- - relative: `BENCH_MAX_REGRESSION_PCT` (default `40`)
494
- - absolute: `BENCH_MAX_ABS_REGRESSION_US` (default `1.5`)
495
- - baseline file: `BENCH_BASELINE_PATH` (default `benchmarks/baseline.json`)
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()` · `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)`
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?)` · `.register(feature)` · `.registerAll(features)` · `.recordActivations(features)` · `.prune()` · `.snapshot()` · `.exportSchema()` · `.importSchema(exported)` · `.expectedExcludedFeatures(featureCount?)` · `.theoreticalCollisionRate` · `.fingerprint` · `.featureToBit` · `.bitToFeatures` · `.version`
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)` · `BitmaskMessage.now(mask, agentId, version)` · `.serialize()` · `.toBytes()` · `BitmaskMessage.deserialize(buf)` · `.sizeBytes` · `.compressionVsJson`
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?)` · `.score(mask, confidence?)` (legacy) · `.scoreStrategies(candidates, options?)` (paper-canonical) · `.scoreMessages(messages, version?)` · `.setWeight(pos, weight)` · `createFinancialArbiter()` · `createRoboticArbiter()` (`onTelemetry`)
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?)` · `.startRound()` · `.receive(msg)` · `.receiveAll(msgs)` · `.aggregate()` · `.schemaVersion` (`staleMessagePolicy`: `'accept' | 'warn' | 'drop'`, `onTelemetry`)
482
+ `new Coordinator(config?)`, `.startRound()`, `.receive(msg)`, `.receiveAll(msgs)`, `.aggregate()`, `.schemaVersion`
518
483
 
519
484
  ### Transport Envelope
520
485
 
521
- `createEnvelope(msg, schemaFingerprint, roundId?)` · `decodeEnvelope(envelope, expectedSchemaFingerprint?)`
486
+ `createEnvelope(msg, schemaFingerprint, roundId?)`, `decodeEnvelope(envelope, expectedSchemaFingerprint?)`
522
487
 
523
488
  ## License
524
489