npm package: @geravant/sinain
Description: Ambient intelligence that sees what you see, hears what you hear, and acts on your behalf
Latest version: 1.12.0

# @geravant/sinain

This package serves two roles:

1. **Standalone launcher** — run `npx @geravant/sinain start` to launch the full sinain stack (core, sense, overlay, agent) on your Mac. See the [main README](../README.md#quick-start) for usage.
2. **OpenClaw plugin** — when installed on an OpenClaw gateway server (`npx @geravant/sinain install`), it manages the sinain-hud agent lifecycle.

---

## OpenClaw Plugin

Plugin for the [anthillnet fork of OpenClaw](https://github.com/anthillnet/openclaw) that manages the sinain-hud agent lifecycle on the server.

## What It Does

Five lifecycle hooks, one tool, four commands, and a background service:

### Hooks

| Hook | Purpose |
|---|---|
| `session_start` | Initializes per-session tool usage and compliance tracking |
| `before_agent_start` | Syncs HEARTBEAT.md, SKILL.md, sinain-memory/ (recursively, including eval/), and modules/ from `sinain-sources/` to workspace; generates effective playbook; creates memory directories |
| `tool_result_persist` | Strips `<private>` tags from tool results; tracks `sinain_heartbeat_tick` calls for compliance validation |
| `agent_end` | Writes structured session summary; validates heartbeat compliance (warns on skip, escalates after 3 consecutive skips) |
| `session_end` | Cleans up orphaned session state |

### Tool

| Tool | Purpose |
|---|---|
| `sinain_heartbeat_tick` | Executes all heartbeat mechanical work (signal analysis, insight synthesis, log writing). Returns structured JSON with results, recommended actions, and Telegram output. |

The heartbeat tool accepts `{ sessionSummary: string, idle: boolean }` and runs:
1. `uv run python3 sinain-memory/signal_analyzer.py` (60s timeout)
2. `uv run python3 sinain-memory/insight_synthesizer.py` (60s timeout)
3. Writes log entry to `memory/playbook-logs/YYYY-MM-DD.jsonl`

### Commands

| Command | Purpose |
|---|---|
| `/sinain_status` | Shows persistent session data from `sessions.json` (update time, tokens, compactions, transcript size) and resilience metrics |
| `/sinain_modules` | Shows active knowledge module stack, suspended and disabled modules |
| `/sinain_eval` | Shows latest evaluation report and recent tick evaluation metrics |
| `/sinain_eval_level` | Sets evaluation level: `mechanical`, `sampled`, or `full` |

### Service

**Curation pipeline** — runs every 30 minutes in the background:
1. Feedback analysis (`feedback_analyzer.py`) → extracts `curateDirective` + effectiveness metrics
2. Memory mining (`memory_miner.py`) → reads unread daily memory files
3. Playbook curation (`playbook_curator.py`) → archives, applies changes
4. Effectiveness footer update → writes metrics into playbook
5. Effective playbook regeneration → merges base playbook + active module patterns
6. Tick evaluation (`tick_evaluator.py`) → runs mechanical + sampled judges (120s timeout)
7. Daily eval report (`eval_reporter.py`) → generates report once per day after 03:00 UTC

## Configuration

Configured in `openclaw.json` under `plugins.entries.sinain-hud`:

```json
{
  "plugins": {
    "entries": {
      "sinain-hud": {
        "enabled": true,
        "config": {
          "heartbeatPath": "/home/node/.openclaw/sinain-sources/HEARTBEAT.md",
          "skillPath": "/home/node/.openclaw/sinain-sources/SKILL.md",
          "memoryPath": "/home/node/.openclaw/sinain-sources/sinain-memory",
          "modulesPath": "/home/node/.openclaw/sinain-sources/modules",
          "sessionKey": "agent:main:sinain"
        }
      }
    }
  }
}
```

| Field | Type | Description |
|---|---|---|
| `heartbeatPath` | string | Path to HEARTBEAT.md source (resolved relative to state dir) |
| `skillPath` | string | Path to SKILL.md source |
| `memoryPath` | string | Path to sinain-memory/ scripts directory |
| `modulesPath` | string | Path to modules/ directory for knowledge module system |
| `sessionKey` | string | Session key for the sinain agent |

## File Auto-Deploy

The `before_agent_start` hook copies files from the persistent source directory to the agent workspace:

```
/mnt/openclaw-state/sinain-sources/     →  /home/node/.openclaw/workspace/
  HEARTBEAT.md                               HEARTBEAT.md
  SKILL.md                                   SKILL.md
  sinain-memory/                               sinain-memory/
    *.json, *.sh, *.txt                        (always overwritten)
    *.py                                       (deploy-once — skip if exists)
  modules/                                   modules/
    manifest.json                              (always overwritten)
    module-registry.json                       (deploy-once)
    */patterns.md                              (deploy-once)
  sinain-memory/eval/                          sinain-memory/eval/   (recursive)
    *.py                                       (deploy-once)
    *.json, *.jsonl                             (always overwritten)
```

Only writes if content has actually changed (avoids unnecessary git diffs).

Also ensures these directories exist:
- `memory/`, `memory/playbook-archive/`, `memory/playbook-logs/`
- `memory/eval-logs/`, `memory/eval-reports/`

After syncing modules, the plugin generates `memory/sinain-playbook-effective.md` — a merged view of active module patterns (sorted by priority) plus the base playbook.

## Heartbeat Compliance Validation

The plugin enforces that the agent actually calls `sinain_heartbeat_tick` during heartbeat runs:

1. `tool_result_persist` sets `heartbeatToolCalled = true` when `sinain_heartbeat_tick` is invoked
2. `agent_end` checks if the run was a heartbeat (`messageProvider === "heartbeat"`)
3. If tool wasn't called: logs warning, increments `consecutiveHeartbeatSkips` counter
4. After 3 consecutive skips: logs ESCALATION warning
5. A successful tool call resets the counter to 0

## Privacy Tag Stripping

The `tool_result_persist` hook intercepts tool results before they're saved to session history. Any `<private>...</private>` blocks are removed from:
- String content (simple tool results)
- Text blocks in array content (structured tool results)

This is the server-side complement to sense_client's client-side `apply_privacy()` filter.

## Session Summaries

On `agent_end`, the plugin appends a JSON line to `memory/session-summaries.jsonl`:

```json
{
  "ts": "2026-02-18T12:00:00.000Z",
  "sessionKey": "agent:main:sinain",
  "agentId": "...",
  "durationMs": 45000,
  "success": true,
  "error": null,
  "toolCallCount": 12,
  "toolBreakdown": { "sessions_history": 3, "sinain_heartbeat_tick": 1, "Write": 5 },
  "messageCount": 8
}
```

## Context Overflow Watchdog

Automatically recovers from runaway context growth that causes repeated agent failures.

- **Detection:** Tracks consecutive errors matching `/overloaded|context.*too.*long|token.*limit/i` on `cfg.sessionKey`
- **Trigger:** 5 consecutive errors + transcript ≥ 1 MB
- **Action:** Archives transcript via `copyFileSync`, truncates to empty, resets `contextTokens` in `sessions.json`
- **Resets:** Counter clears on any successful session completion and on `gateway_start`

The 1 MB minimum guard prevents resets from transient API outages when the transcript is small.

## Deployment

**IMPORTANT:** Use `docker-compose.openclaw.yml` — the default compose file uses unset env vars and will fail.

```bash
# Upload plugin files to the server
scp -i ~/.ssh/<your-key> \
  sinain-hud-plugin/index.ts sinain-hud-plugin/openclaw.plugin.json \
  root@<your-server-ip>:/mnt/openclaw-state/extensions/sinain-hud/

# Restart gateway to load updated plugin
ssh -i ~/.ssh/<your-key> root@<your-server-ip> \
  'cd /opt/openclaw && docker compose -f docker-compose.openclaw.yml restart'

# Verify plugin loaded
ssh -i ~/.ssh/<your-key> root@<your-server-ip> \
  'cd /opt/openclaw && docker compose -f docker-compose.openclaw.yml logs --tail=30 openclaw-gateway 2>&1 | grep sinain'
```

## Files

| File | Purpose |
|---|---|
| `index.ts` | Plugin implementation (hooks, tool, commands, curation service) |
| `openclaw.plugin.json` | Plugin manifest (metadata, config schema, UI hints) |