Releases: Jovancoding/Network-AI
v5.7.1 — CodeQL Security Fixes
Network-AI v5.7.1 — CodeQL Security Fixes
All 3,136 tests pass. Zero TypeScript errors.
Security / Bug Fixes
compactWAL() race condition — CWE-367 (High)
lib/locked-blackboard.ts — Replaced the existsSync + writeFileSync pattern with a single atomic file-descriptor operation:
// Before (TOCTOU — file could be replaced between check and write):
if (existsSync(this.walPath)) {
writeFileSync(this.walPath, '', { encoding: 'utf-8', mode: 0o600 });
}
// After (atomic — openSync 'w' = O_WRONLY | O_CREAT | O_TRUNC):
const fd = openSync(this.walPath, 'w', 0o600);
closeSync(fd);openSync('w') atomically truncates an existing WAL or creates a new empty one — no intermediate existence check that could be exploited in a race. Resolves CodeQL js/file-system-race #160.
Unused imports removed — test-phase11.ts
CircuitOpenErrorimport removed (CodeQLjs/unused-local-variable#161)existsSyncimport removed (CodeQLjs/unused-local-variable#162)
Both were dead code from Phase 11 development that were never referenced after final test implementation.
Useless assignment removed — test-phase11.ts:384
c = await hookMgr.runAfter(c) reassigned c but the returned context was never read. Changed to await hookMgr.runAfter(c). Resolves CodeQL js/useless-assignment-to-local #163.
Zero functional changes — all 3,136 tests continue to pass unchanged.
v5.7.0 — OTel ITelemetryProvider BYOT Interface
Network-AI v5.7.0 — OTel ITelemetryProvider BYOT Interface
All 3,136 tests pass. Zero TypeScript errors.
Features
ITelemetryProvider BYOT abstraction (lib/telemetry-provider.ts)
A zero-dependency telemetry interface that lets you plug any OpenTelemetry SDK — or any custom backend — into Network-AI without modifying a single adapter.
Interface
interface ITelemetryProvider {
startSpan(name: string, attributes?: SpanAttributes): unknown;
endSpan(span: unknown, attributes?: SpanAttributes): void;
recordError(span: unknown, error: Error): void;
}Built-in implementations
| Class | Purpose |
|---|---|
NullTelemetryProvider |
No-op default — zero overhead, zero imports |
CapturingTelemetryProvider |
In-memory store for tests and local dev |
createOtelHooks(provider)
Factory that converts any ITelemetryProvider into three ExecutionHook[] ready to register with AdapterHookManager:
import { createOtelHooks, CapturingTelemetryProvider } from './lib/telemetry-provider.js';
import { AdapterHookManager } from './lib/adapter-hooks.js';
const telemetry = new CapturingTelemetryProvider();
const hookManager = new AdapterHookManager();
hookManager.registerHooks(createOtelHooks(telemetry));
// After execution:
const spans = telemetry.getSpans(); // CapturedSpan[]Wiring your OTel SDK
class MyOtelProvider implements ITelemetryProvider {
startSpan(name: string, attrs?: SpanAttributes) {
return otel.tracer('network-ai').startSpan(name, { attributes: attrs });
}
endSpan(span: unknown) { (span as Span).end(); }
recordError(span: unknown, error: Error) {
(span as Span).recordException(error);
(span as Span).setStatus({ code: SpanStatusCode.ERROR });
}
}
hookManager.registerHooks(createOtelHooks(new MyOtelProvider()));Zero new runtime dependencies — BYOT principle maintained throughout.
16 new tests added to test-phase11.ts.
v5.6.1 — Circuit Breaker on AdapterRegistry
Network-AI v5.6.1 — Circuit Breaker on AdapterRegistry
All 3,136 tests pass. Zero TypeScript errors.
Features
Circuit Breaker on AdapterRegistry (lib/circuit-breaker.ts)
A new standalone CircuitBreaker class with a three-state machine wired into every adapter in AdapterRegistry.
State machine
CLOSED ──(failureThreshold failures)──► OPEN
▲ │
│ (successThreshold successes) (recoveryTimeoutMs)
│ ▼
└────────────────────────── HALF_OPEN ──┤
│ (failure)
└──► OPEN
| State | Behavior |
|---|---|
CLOSED |
Normal execution — failures increment counter |
OPEN |
CircuitOpenError thrown immediately — no call made to adapter |
HALF_OPEN |
One probe call allowed — success closes, failure re-opens |
Configuration
const registry = new AdapterRegistry({
circuitBreaker: {
failureThreshold: 3, // trips after 3 consecutive failures (default)
recoveryTimeoutMs: 30_000, // waits 30 s before probing (default)
successThreshold: 1, // 1 success in HALF_OPEN closes circuit (default)
onStateChange: (from, to, adapterName) => console.log(`${adapterName}: ${from} → ${to}`),
},
fallbackChain: ['backup-agent', 'emergency-agent'],
});Fallback chain
When the circuit is OPEN, the registry automatically tries each adapter in fallbackChain in order before returning a CIRCUIT_OPEN error code. This enables zero-downtime failover without changing any call site.
Public API
registry.getCircuitState('my-agent'); // 'CLOSED' | 'OPEN' | 'HALF_OPEN'
registry.resetCircuit('my-agent'); // force back to CLOSED
registry.setCircuitBreakerConfig({ failureThreshold: 5 });New event types
circuit:open, circuit:half-open, circuit:close added to AdapterEventType.
Zero new runtime dependencies — BYOC principle maintained throughout.
13 new tests added to test-phase11.ts.
v5.6.0 — WAL Crash Recovery
Network-AI v5.6.0 — WAL Crash Recovery
All 3,136 tests pass. Zero TypeScript errors.
Features
LockedBlackboard Write-Ahead Log (WAL) crash recovery (lib/locked-blackboard.ts)
Every write(), commit(), and delete() now follows a strict append-before-write + checkpoint-after-write pattern:
- Before the file write — an
appendrecord is written to.wal.jsonl - The actual state file is updated
- After the write succeeds — a
checkpointrecord is appended to.wal.jsonl
On construction, replayWAL() is called automatically after loadFromDisk(). It scans .wal.jsonl for any append records that have no matching checkpoint (= the process crashed between steps 1 and 3) and replays them into the in-memory store. The WAL is then compacted.
// WAL is automatic — nothing to configure
const board = new LockedBlackboard('.', { env: 'prod' });
// Any uncommitted ops from a previous crash are replayed here
// Manual truncation after a full snapshot:
await board.compactWAL();WAL file locations
| Mode | Path |
|---|---|
| Env-scoped | <basePath>/<env>/.wal.jsonl |
| Legacy (no env) | <basePath>/data/.wal.jsonl |
Resilience properties
- Partial writes at crash time produce malformed tail lines — silently skipped
- WAL replay is idempotent: replaying an already-committed op overwrites with the same value
compactWAL()is safe to call at any time; a new WAL starts clean on the next write
7 new tests added to test-phase11.ts.
v5.5.9 — TTL Background Sweep
Network-AI v5.5.9 — TTL Background Sweep
All 3,136 tests pass. Zero TypeScript errors.
Features
LockedBlackboard TTL background sweep (lib/locked-blackboard.ts)
purgeExpired(): number— evicts all expired TTL entries from the in-memory cache on demand; returns the number of evictions. Call it anytime to reclaim memory without waiting for the next read or persist cycle.startSweep(intervalMs?: number)— starts a backgroundsetIntervalthat callspurgeExpired()automatically. Default interval: 60,000 ms (1 min). The timer isunref()'d so it never prevents a clean process exit.stopSweep()— cancels the sweep timer cleanly; safe to call even if no sweep is running.
Why this matters: read() and persistToDisk() already filtered expired entries on access, but keys that were written with a TTL and never read again would stay in the in-memory map until the next disk round-trip. startSweep() closes that gap for long-running processes with high write throughput and short-lived keys.
const board = new LockedBlackboard('.', { env: 'prod' });
board.startSweep(30_000); // evict expired entries every 30 s
// ...
board.stopSweep(); // clean shutdown8 new tests added to test-phase11.ts.
v5.5.8 — Operational Hardening
Network-AI v5.5.8 — Operational Hardening
All 3,093 tests pass. Zero TypeScript errors.
Features
approvalTimeoutMs — fail-closed approval gate timeout (lib/phase-pipeline.ts)
PhasePipelineOptions now accepts approvalTimeoutMs (default 300,000 ms / 5 min). If the onApproval callback does not settle within the deadline, the gate automatically denies — { approved: false } — preventing indefinite hangs in automated pipelines.
enforcePromotionChain — strict environment promotion (lib/env-manager.ts)
EnvironmentManager constructor accepts enforcePromotionChain: true. When enabled, promote() checks for a .promotion-record.json in the source environment directory and throws if missing, preventing skipped-stage deployments (e.g., direct dev → prod bypassing sit/qa/preprod). A record is written after every successful promotion regardless of flag state, so existing deployments accumulate records incrementally.
onCompact — archived phase results (lib/phase-pipeline.ts)
CompactionOptions.onCompact now receives a third argument: archivedPhases: ReadonlyArray<PhaseResult> containing the phases that were compacted. Existing two-argument callbacks continue to work without changes.
Improvements
- CLI
--jsonerror output (bin/cli.ts) — Fatal errors now emit{"error":"..."}JSON to stdout when--jsonis present, enabling consistent machine-readable pipeline consumption. - Adapter discovery warning (
adapters/adapter-registry.ts) —discoverAgents()now logsconsole.warnfor each adapter that fails during discovery rather than silently dropping it. FederatedBudgetpersist failure warning (lib/federated-budget.ts) — Blackboard persistence errors in_persist()now emitconsole.warninstead of being silently swallowed.
Documentation
AuthGuardianadvisory token notice — Class-level JSDoc clarifies that grant tokens are advisory scoring outputs only;agentIdis not cryptographically verified; callers must add a separate identity-verification step before gating PAYMENTS, DATABASE, or FILE_EXPORT operations.FileAccessorerror contract — JSDoc documents thatread,write, andlistnever throw; all access-denied paths are caught at the method boundary and returned as{ success: false, error: <message> }.LockedBlackboardsemantics — Options JSDoc documents dirty-read window with recommended optimistic-retry pattern, equal-priority last-writer-wins tie-break, andenvvalue frozen at construction.SandboxPolicyConfig.envfreeze notice — JSDoc statesNETWORK_AI_ENVis captured at construction; runtime changes have no effect.StreamingBaseAdapterauth once-at-start —executeAgentStream()JSDoc documents that the permission check fires once at stream start, not per-chunk.- SECURITY.md — Added
Fail-Closed Approval Timeout (v5.5.8)andStrict Promotion Chain Enforcement (v5.5.8)entries to bothSECURITY.mdcopies. - README.md — Phase Pipeline row updated to reflect
approvalTimeoutMsfail-closed timeout.
v5.5.7 — socket.json shellAccess False-Positive Fix
v5.5.7 — socket.json shellAccess False-Positive Fix
Type: Chore / Supply Chain
Date: 2026-05-18
What changed
Added shellAccess ignore entries to socket.json for AgentRuntime and McpToolConsumer.
Root cause: Socket.dev uses two distinct alert type IDs for child_process usage:
shellExec— triggered by shell command execution calls (e.g.execFile,execSync)shellAccess— triggered by thechild_processmodule import itself
Both files were already documented under shellExec (v5.5.6 and earlier). The shellAccess alert type requires a separate ignore entry.
Why these files use child_process:
- AgentRuntime (
lib/agent-runtime.ts) —ShellExecutoruseschild_process.spawnfor sandboxed command execution. Shell access is opt-in only; the caller must explicitly configure and enable theShellExecutorwith aSandboxPolicy. - McpToolConsumer (
lib/mcp-tool-consumer.ts) — useschild_process.spawnto launch MCP server subprocesses for stdio-based MCP transport. The MCP stdio protocol requires process spawning; the caller provides the server command.
Files changed
socket.json— four newshellAccessignore entries added- Version bumped to 5.5.7 in
package.json,skill.json,openapi.yaml,README.md, and all 12 doc/config files.
No code changes. All 3,093 tests continue to pass.
v5.5.6 — socket.json Supply Chain Scan Fix
v5.5.6 — socket.json Supply Chain Scan Fix
Type: Chore / Supply Chain
Date: 2026-05-18
What changed
Added networkAccess ignore entries to socket.json for ContextThrottler (lib/context-throttler.ts / dist/lib/context-throttler.js).
ContextThrottler is a pure in-memory blackboard-pruning utility — it filters blackboard state to the subset relevant to each agent's declared scope tags. It contains:
- Zero
fetchcalls - Zero outbound network access
- Zero external dependencies (pure TypeScript)
Socket.dev's transitive import-graph analysis was incorrectly flagging it under the networkAccess supply chain risk category, reducing the Supply Chain Security score. The existing socket.json already covered all other flagged files; this entry closes the remaining false positive.
Files changed
socket.json— two newnetworkAccessignore entries added- Version bumped to 5.5.6 in
package.json,skill.json,openapi.yaml,README.md,CLAUDE.md,CODEX.md,ARCHITECTURE.md,BENCHMARKS.md,AUDIT_LOG_SCHEMA.md,INTEGRATION_GUIDE.md,references/adapter-system.md,.github/copilot-instructions.md,SECURITY.md,.github/SECURITY.md,ENTERPRISE.md,CHANGELOG.md
No code changes. All 3,093 tests continue to pass.
v5.5.5 — MAESTRO/OWASP AST Framework Assessment
v5.5.5 — MAESTRO / OWASP AST Framework Assessment
Type: Documentation
Date: 2026-05-17
What changed
Added a new Security Framework Assessment (MAESTRO / OWASP AST) section to SKILL.md documenting Network-AI's architectural mitigations for three MAESTRO Agent Security Threat findings:
AST03 — Over-Privileged Skills (High)
Mitigations documented: permission manifest in frontmatter (bundle_scope, network_calls: none); least-privilege resource gating with --confirm-high-risk for PAYMENTS/FILE_EXPORT; abstract-only resource labels (no external credentials); HMAC-signed grant tokens (v5.5.2); SandboxPolicy + FileAccessor path scoping; advisory-only token enforcement.
AST06 — Weak Isolation (High)
Mitigations documented: zero subprocesses / zero network calls declared in frontmatter; AgentRuntime ShellExecutor allowlist/timeout; SourceProtectionError on out-of-scope paths; NETWORK_AI_ENV environment isolation; ApprovalGate for high-risk ops; no hot-reload surface.
AST07 — Update Drift (Medium)
Mitigations documented: exact version pinning in package.json; zero transitive dependencies (Python stdlib only); signed tagged releases; Socket.dev supply chain monitoring; no auto-update mechanism; CHANGELOG.md audit trail.
Files changed
SKILL.md— new MAESTRO/OWASP AST section added (before ClawHub findings table)- Version bumped to 5.5.5 in
package.json,skill.json,openapi.yaml,README.md,CLAUDE.md,CODEX.md,ARCHITECTURE.md,BENCHMARKS.md,AUDIT_LOG_SCHEMA.md,INTEGRATION_GUIDE.md,references/adapter-system.md,.github/copilot-instructions.md,SECURITY.md,.github/SECURITY.md,ENTERPRISE.md,CHANGELOG.md
No code changes. All tests continue to pass.
v5.5.4 — ClawHub scan findings documented (ASI03/ASI06 severity update + 2 new Low)
What's changed
Documentation — ClawHub scan findings
Updated SKILL.md Security Scan Findings table to reflect the v5.5.3 ClawHub scan results:
- Column renamed:
Confidence→Severity(matches ClawHub UI terminology) - ASI03 advisory tokens: severity High → Medium
- ASI06 project context: severity High → Medium
- New — Low ASI03 local grant state: the
.signing_keyandactive_grants.jsonfiles introduced in v5.5.2 are security-relevant local state; mitigation: keepdata/private, restrict OS-level permissions on shared machines - New — Low ASI06 audit log free text:
justificationfields anddata/audit_log.jsonlstore agent-provided free text locally — do not include PII, secrets, or credentials; restrictdata/directory on shared machines
All four remaining findings are by design. The documented controls in SKILL.md are the mitigations — not an elimination of the patterns.
SECURITY.md ClawHub scanner entry updated to summarise the v5.5.3 scan state (2 Medium, 2 Low, all acknowledged).
Full changelog: https://github.com/Jovancoding/Network-AI/blob/main/CHANGELOG.md
Documentation-only release. No code changes.