registry  /  @holt-os/holt  /  0.9.0

@holt-os/holt@0.9.0

An open-source personal agent OS: any LLM, private memory you can see and walk.

AI Security Review

scanned 4d ago · by lpm-firewall-ai

LPM treats this as warn-only first-party agent extension lifecycle risk. No confirmed malicious install-time or hidden exfiltration behavior was found. The real risk is an explicit, package-owned Claude Code hook integration that mutates an AI-agent control surface and later injects/captures memory in trusted Holt workspaces.

Static reason
High-risk behavior combination matched malicious policy.
Trigger
User runs `holt hook install`, `holt init`, `holt telegram`, or other CLI commands.
Impact
Claude Code prompts may receive Holt memory context, transcripts may be summarized into local Holt memory, and Telegram runs may return brain output to the configured chat.
Mechanism
Explicit CLI agent extension setup and user-configured task forwarding
Rationale
Source inspection supports a warning for explicit AI-agent extension lifecycle risk, not a publish block: there are no npm lifecycle hooks, hidden install-time mutations, credential harvesting, or unconsented broad control-surface writes. The risky primitives are documented, user-invoked, and aligned with the package's stated agent OS functionality.
Evidence
package.jsondist/cli.jsREADME.md~/.claude/settings.json./.claude/settings.json~/.claude/settings.json.holt-bak./.claude/settings.json.holt-bak~/.holt/telegram.json~/.holt/credentials.json./.holt/config.json./.holt/memory/turns.jsonl./.holt/memory/facts.md
Network endpoints5
api.telegram.orgapi.anthropic.com/v1/messagesapi.openai.com/v1/chat/completionsgenerativelanguage.googleapis.com/v1beta/models/127.0.0.1:11434

Decision evidence

public snapshot
AI called this Suspicious at 84.0% confidence as Dangerous Capability with medium false-positive risk.
Evidence for warning
  • dist/cli.js implements explicit `holt hook install` that writes Claude Code hooks into `~/.claude/settings.json` or `./.claude/settings.json`.
  • Installed hooks run `holt hook inject` on `UserPromptSubmit` and `holt hook capture` on `Stop`, affecting Claude Code context/memory.
  • Hook capture reads Claude transcript path from hook input and can run the configured brain to distill facts into `.holt/memory`.
  • `holt telegram` can send `runTask` output to Telegram after user setup with bot token and allowed chat id.
Evidence against
  • package.json has no preinstall/install/postinstall lifecycle scripts.
  • CLI dispatch requires explicit user commands; no import-time hidden execution beyond `main()` command routing.
  • Hook runtime is guarded by trusted workspace and existing `.holt/memory`.
  • Telegram is opt-in setup, restricted to configured `allowedChatId`, and uses the user's bot token.
  • External AI/API endpoints are package-aligned configurable brain providers or local Ollama.
Behavioral surface
Source
ChildProcessCryptoEnvironmentVarsFilesystemNetworkShell
Supply chain
HighEntropyStringsUrlStrings
ManifestNo manifest risk signals triggered.
scanned 1 file(s), 228 KB of source, external domains: 127.0.0.1, api.anthropic.com, api.openai.com, api.telegram.org, generativelanguage.googleapis.com, github.com, ollama.com, productsdecoded.com, www.apple.com

Source & flagged code

5 flagged · loading source
dist/cli.jsView file
5320if (!p.quiet && (streamed || result.text) && !result.text.endsWith("\n")) { L5321: process.stdout.write("\n"); L5322: } L5323: if (p.out) { L5324: const target = resolve4(process.cwd(), p.out); L5325: try { ... L5335: // src/commands/schedule.ts L5336: import { spawnSync as spawnSync4 } from "child_process"; L5337: import { writeFileSync as writeFileSync14, mkdirSync as mkdirSync12, rmSync as rmSync6, existsSync as existsSync14 } from "fs";
Critical
Command Output Exfiltration

Source executes local commands and sends command output to an external endpoint.

dist/cli.jsView on unpkg · L5320
5320Trigger-reachable chain: manifest.bin -> dist/cli.js L5320: if (!p.quiet && (streamed || result.text) && !result.text.endsWith("\n")) { L5321: process.stdout.write("\n"); L5322: } L5323: if (p.out) { L5324: const target = resolve4(process.cwd(), p.out); L5325: try { ... L5335: // src/commands/schedule.ts L5336: import { spawnSync as spawnSync4 } from "child_process"; L5337: import { writeFileSync as writeFileSync14, mkdirSync as mkdirSync12, rmSync as rmSync6, existsSync as existsSync14 } from "fs";
Critical
Trigger Reachable Dangerous Capability

A package entrypoint or install-time lifecycle script reaches a source file with blocking dangerous behavior.

dist/cli.jsView on unpkg · L5320
215// src/brains.ts L216: import { spawn, spawnSync } from "child_process"; L217: var MAX_REPLAY_TURNS = 12;
High
Child Process

Package source references child process execution.

dist/cli.jsView on unpkg · L215
2798import { join as join10 } from "path"; L2799: import { spawn as spawn3 } from "child_process"; L2800: L2801: // src/localmodel.ts L2802: var OLLAMA_URL2 = process.env.HOLT_OLLAMA_URL || "http://127.0.0.1:11434"; L2803: async function localModelStatus(model) {
High
Same File Env Network Execution

A single source file combines environment access, network access, and code or shell execution; review context before blocking.

dist/cli.jsView on unpkg · L2798
13import readline from "readline"; L14: var on = process.stdout.isTTY && !process.env.NO_COLOR; L15: var wrap = (code) => (s) => on ? `\x1B[${code}m${s}\x1B[0m` : s; ... L44: const ask = (q) => new Promise((resolve7) => { L45: if (q) process.stdout.write(q); L46: if (buffer.length) resolve7(buffer.shift()); ... L53: // src/workspace.ts L54: var GLOBAL_DIR = join(homedir(), ".holt"); L55: var TRUST_PATH = join(GLOBAL_DIR, "trust.json"); ... L66: try { L67: return JSON.parse(readFileSync(TRUST_PATH, "utf8")); L68: } catch {
Medium
Install Persistence

Source writes installer persistence such as shell profile or service configuration.

dist/cli.jsView on unpkg · L13

Findings

2 Critical3 High4 Medium4 Low
CriticalCommand Output Exfiltrationdist/cli.js
CriticalTrigger Reachable Dangerous Capabilitydist/cli.js
HighChild Processdist/cli.js
HighShell
HighSame File Env Network Executiondist/cli.js
MediumNetwork
MediumEnvironment Vars
MediumInstall Persistencedist/cli.js
MediumStructural Risk Force Deep Review
LowScripts Present
LowFilesystem
LowHigh Entropy Strings
LowUrl Strings