npm package: @helmetfire-labs/cartridge-common
Description: Shared logging, error boundaries, trace helpers, and durable reducer runtime for infrastructure cartridges
Latest version: 0.2.0

# @helmetfire-labs/cartridge-common

Shared logging, error boundaries, trace helpers, durable reducer runtime, and trust infrastructure for AgentRuntime cartridges.

This is a **library**, not a service. It provides the building blocks that all cartridges use for structured logging, error handling, multi-agent state isolation, and auditable state management.

## Philosophy

Every cartridge is a process with a behavioral contract. It declares what it does (action schema), what it's allowed to do (process policy), and how its state changes over time (reducer). All three are cryptographically bound — the action log is hash-chained, the policy is signed at write time, and the verifier can replay any cartridge's history to prove correctness.

Infrastructure cartridges never expose admin APIs. The operator reads logs and edits config — the Conversational Control Plane. Trust is earned through observable behavior: verified action logs, policy compliance, and operator attestation feed a scoring engine that automates tier promotion from T0 (untrusted) through T5 (community-verified).

## Install

```bash
npm install @helmetfire-labs/cartridge-common
```

## Exports

### Logging & Observability

| Export | Module | Description |
|--------|--------|-------------|
| `logEvent`, `LogEventOpts` | `logger` | Structured log event emitter |
| `TAGS`, `isValidTag`, `TagKey`, `TagValue` | `tags` | Standard tag constants and validation |
| `ACTIONS`, `ActionKey`, `ActionValue` | `actions` | Standard action verb constants |
| `generateTraceId`, `extractTraceId`, `traceMetadata`, `extractHop`, `NO_TRACE` | `trace` | Trace ID generation and propagation |
| `extractShape` | `shape` | Error shape extraction |
| `withErrorBoundary`, `classifyError`, `ERROR_SHAPES`, `ErrorShapeKey` | `errors` | Error boundary wrapper and classification |

### Namespace Scope (Multi-Agent State Isolation)

| Export | Module | Description |
|--------|--------|-------------|
| `extractNamespace`, `ScopedStateManager` | `namespace` | Multi-agent namespace isolation |
| `ScopeMode`, `CrossNamespacePolicy`, `NamespaceScopeConfig`, `NamespaceInfo` | `namespace` | Namespace type definitions |

### Durable Reducer Runtime

| Export | Module | Description |
|--------|--------|-------------|
| `sha256`, `hashState`, `hashLine` | `durable-reducer` | Cryptographic hashing for state and action logs |
| `DurableReducer`, `DurableActionLogEntry`, `VerifyResult`, `VerifyFailure` | `durable-reducer` | Reducer types and verification result types |
| `DurableDispatcher`, `DispatcherConfig` | `durable-dispatcher` | Persistent dispatcher with hash-chained action logging |
| `verify` | `verify` | Replay-based action log verification |
| `containerReducer`, `containerActionSchema`, `ContainerStatus`, `ContainerState`, `ContainerAction` | `container-reducer` | Built-in reducer for container lifecycle |

### Action Schemas

| Export | Module | Description |
|--------|--------|-------------|
| `defineActionSchema`, `action`, `writeActionSchema`, `getSchemaHash`, `validateAction` | `action-schema` | Schema definition, validation, and persistence |
| `ActionSchema`, `ActionVariant`, `FieldType` | `action-schema` | Schema type definitions |

### Process Policy

| Export | Module | Description |
|--------|--------|-------------|
| `hashPolicy`, `writePolicy`, `readPolicy`, `verifyPolicy` | `policy` | Cryptographically-verified process policy lifecycle |
| `isNetworkAllowed`, `isFilesystemAllowed`, `isSpawnAllowed` | `policy` | Runtime permission checks |
| `DEFAULT_POLICY`, `INSTALL_POLICY` | `policy` | Standard policy presets |
| `CartridgePolicy`, `FilesystemPolicy`, `NetworkPolicy`, `NetworkEndpoint`, `ProcessPolicy`, `PolicyVerifyResult` | `policy` | Policy type definitions |

### Trust Tiers & Scoring

| Export | Module | Description |
|--------|--------|-------------|
| `evaluateTrust`, `checkT3`, `checkT4` | `trust-tiers` | Automated trust tier evaluation (T0–T5) |
| `TrustTier`, `TierCheck`, `TrustAssessment` | `trust-tiers` | Trust tier type definitions |
| `computeTrustDelta`, `applyDecay`, `updateTrustScore`, `computeTrustBadge`, `badgeLabel` | `trust-score` | T5 consensus trust scoring engine |
| `countAnchorConsistency`, `recencyWeight`, `getOperatorWeight`, `initialTrustScoreState` | `trust-score` | Scoring utilities and initial state |
| `OperatorTier`, `TrustBadge`, `TrustSignal`, `TrustScoreState`, `AnchorConsistencyInput` | `trust-score` | Scoring type definitions |

## Durable Reducer Runtime

The reducer runtime gives every cartridge an auditable, replay-verifiable state machine.

```typescript
import {
  DurableDispatcher,
  containerReducer,
  type ContainerState,
  type ContainerAction,
} from "@helmetfire-labs/cartridge-common";

// Create a dispatcher — persists hash-chained action.log
const dispatcher = new DurableDispatcher<ContainerState, ContainerAction>({
  reducer: containerReducer,
  configDir: "./config",
  skipProjection: true, // don't write clear.json (incremental integration)
});

// Dispatch typed actions — each entry gets a stateHash binding
dispatcher.dispatch({ type: "start", name: "registry", pid: 1234, timestamp: Date.now() });

// Verify the log — replays all actions and checks hash chain integrity
import { verify } from "@helmetfire-labs/cartridge-common";
const result = await verify(containerReducer, "./config/action.log");
// result.ok === true if the log is tamper-free
```

### Action Schemas

Define typed, validated action schemas for your reducer:

```typescript
import { defineActionSchema, action } from "@helmetfire-labs/cartridge-common";

const schema = defineActionSchema("my-cartridge", [
  action("init", { name: "string" }),
  action("update", { value: "number", reason: "string?" }),  // ? = optional
  action("reset"),
]);
```

## Process Policy

Self-declared, cryptographically-verified permissions for cartridge sandboxing:

```typescript
import { writePolicy, verifyPolicy, isNetworkAllowed } from "@helmetfire-labs/cartridge-common";

// Write a signed policy to config/
await writePolicy("./config", {
  filesystem: { read: ["./data/**"], write: ["./state/**"], deny: ["/etc/**"] },
  network: { allow: [{ host: "api.example.com", port: 443 }], denyAll: false },
  process: { allowSpawn: false, allowedCommands: [] },
});

// Verify policy hasn't been tampered with
const result = await verifyPolicy("./config");
// result.ok === true

// Runtime permission checks
isNetworkAllowed(policy, "api.example.com", 443); // true
```

## Namespace Scope (Multi-Agent State Isolation)

When multiple agents connect to the same SSE MCP tool server, each agent needs its own isolated state. The supervisor assigns each agent a namespace via `?ns=<name>` on the SSE URL. Agents never control their own namespace — the supervisor asserts the identity.

```typescript
import { extractNamespace, ScopedStateManager } from "@helmetfire-labs/cartridge-common";

const state = new ScopedStateManager({
  mode: "isolated",      // "isolated" | "shared" | "hybrid"
  crossNamespace: "allow" // "allow" | "log" | "deny"
}, "brw");

const ns = extractNamespace(req.url); // e.g. "claude" from ?ns=claude
state.registerSession(transport.sessionId, ns);
const store = state.getStore(transport.sessionId, "view_page");
```

### Scope Modes

| Mode | Behavior |
|------|----------|
| `isolated` | Each agent gets its own state partition |
| `shared` | All agents share one state pool, `ns` tracks attribution |
| `hybrid` | Some tools isolated, some shared (configured via `sharedTools`) |

### Cross-Namespace Policy

| Policy | Behavior |
|--------|----------|
| `allow` | No enforcement (default, for development) |
| `log` | Access permitted but logged with attribution |
| `deny` | Access rejected, escalation requires attributed override |

## Standard Tags

| Key | Tag | Cartridge |
|-----|-----|-----------|
| `mutex` | `mtx` | mcp-mutex |
| `semaphore` | `sem` | mcp-semaphore |
| `readonly` | `rdo` | mcp-readonly |
| `retry` | `rty` | mcp-retry |
| `timeout` | `tmo` | mcp-timeout |
| `circuitBreaker` | `brk` | mcp-circuit-breaker |
| `router` | `rtr` | mcp-router |
| `cache` | `cch` | mcp-cache |
| `auth` | `aut` | mcp-auth |
| `transform` | `tfm` | mcp-transform |
| `sanitize` | `san` | mcp-sanitize |
| `webhook` | `whk` | mcp-webhook |
| `cron` | `crn` | mcp-cron |
| `audit` | `aud` | mcp-audit |
| `relay` | `rly` | mcp-relay |
| `mock` | `mck` | mcp-mock |
| `shadow` | `shd` | mcp-shadow |
| `bridge` | `brg` | mcp-bridge |
| `tee` | `tee` | mcp-tee |
| `approval` | `apv` | mcp-approval |
| `verify` | `vfy` | mcp-verify |
| `browser` | `brw` | tools-browser |
| `namespace` | `nsp` | namespace scope |

## Build

```bash
npm run build       # compile TypeScript
npm run typecheck   # type-check only
npm test            # run tests (239 tests)
```