This repository has been archived on 2026-06-01. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
nerve/.knowledge/sense.md
T
xiaoju 9c832b0e21 docs(knowledge): update cards via knowledge-extraction workflow (5q/round)
7 cards updated, 4 new cards added. Topics: signal-routing,
worker-isolation, storage-layer, adapter-isolation, sense contracts,
workflow runtime enforcement, coding conventions details.

小橘 <xiaoju@shazhou.work>
2026-04-30 05:56:29 +00:00

2.8 KiB

Sense

A compute() function that samples or derives external data. The only first-class citizen in nerve.

Contract

Each sense module (src/index.ts) must export:

export { snapshots as table } from "./schema.ts";  // drizzle table for runtime to insert into

export async function compute(): Promise<ComputeResult<T>> { ... }  // pure, no args

Function Signature & Input Schema:

  • compute() is parameterless — no direct inputs, environment variables available
  • No database access within compute — runtime provides isolated execution context
  • Must be pure function (no side effects, no external API calls)

Return Value Contract:

  • ComputeResult<T> = null | { signal: T; workflow: WorkflowTrigger | null }
    • null → silent, no storage, no signal
    • { signal: data, workflow: null } → persist + emit signal
    • { signal, workflow: WorkflowTrigger } → persist + emit signal + trigger workflow
    • Any other value → treated as { signal: value, workflow: null }

Error Handling & Serialization:

  • Exceptions caught by worker, logged as errors (no signal emitted)
  • Signal payload must be JSON-serializable (passed via IPC)
  • Invalid workflow triggers silently dropped (signal still emitted)

Timeout & Scheduling Semantics:

  • Timeout priority: explicit config → AbortSignal → DEFAULT_TIMEOUT_MS (30s)
  • Enforced via Promise.race() with timeout promise
  • Grace period can trigger process.exit(1) after timeout (kills worker group)
  • Interval translation: YAML config values used directly as milliseconds in setInterval()
  • Jitter control: throttle mechanism prevents rapid-fire, single deferred trigger per throttle window

Config (nerve.yaml)

senses:
  cpu-usage:
    group: system        # senses in same group share a worker
    throttle: 10s        # min interval between computes
    timeout: 30s         # max compute duration
    grace_period: 5s     # wait before first compute
    interval: 30s        # periodic trigger (optional)
    on: [disk-pressure]  # trigger on signals from other senses (optional)

Manual Trigger Context

nerve sense trigger <name> sends IPC message to running daemon. The compute context is initialized as follows:

  • SQLite Database: Opened in read-write mode at data/senses/<name>.db
  • Migrations: All *.sql files in senses/<name>/migrations/ applied in lexicographic order
  • Environment: Inherits daemon process environment (no special secrets injection)
  • Arguments: No runtime arguments or mock inputs supported — compute() is always pure function with no parameters
  • Isolation: Runs in forked child process (worker) with full filesystem access within user permissions
  • Persistence: Runtime automatically calls db.insert(table).values(result.signal) if compute returns non-null signal