registry  /  @holt-os/holt  /  0.14.0

@holt-os/holt@0.14.0

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

AI Security Review

scanned 1h ago · by lpm-firewall-ai

LPM treats this as warn-only first-party agent extension lifecycle risk. No confirmed malicious attack surface. The package exposes explicit agent-integration features that can run local agent CLIs, install Claude Code hooks, and bridge user-authorized Telegram messages to configured brains.

Static reason
High-risk behavior combination matched malicious policy.
Trigger
User runs commands such as `holt init`, `holt hook install`, `holt telegram setup`, `holt telegram`, or `holt run`.
Impact
Potentially broad agent capability if a user opts in, but no unconsented install-time mutation or exfiltration was found.
Mechanism
Explicit user-command agent integration and remote chat bridge
Rationale
Static inspection shows high-risk but package-aligned, user-invoked agent features rather than malicious install-time behavior. Because it can explicitly install Claude Code hooks and bridge agent output to Telegram, warn rather than block.
Evidence
package.jsondist/cli.js~/.holt/trust.json./.holt/config.json~/.holt/credentials.json~/.holt/telegram.json~/.claude/settings.json./.claude/settings.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 86.0% confidence as Dangerous Capability with medium false-positive risk.
Evidence for warning
  • dist/cli.js defines explicit `holt hook install` writing Holt commands into Claude Code settings hooks.
  • dist/cli.js `holt telegram` can long-poll Telegram, run configured LLM/agent tasks, and send replies to Telegram.
  • dist/cli.js can spawn configured agent CLIs (`claude`, `codex`, `gemini`) with user prompts.
Evidence against
  • package.json has no preinstall/install/postinstall lifecycle scripts.
  • Dangerous paths are user-invoked CLI commands, not install-time or import-time execution.
  • Telegram setup requires pasted bot token and allowed chat id; bot ignores other chats.
  • Claude hooks are guarded by trusted-folder and existing `.holt/memory` checks at runtime.
  • Network endpoints are package-aligned: Telegram, LLM APIs, local Ollama.
  • No evidence of credential harvesting, stealth persistence, remote payload loading, or destructive behavior.
Behavioral surface
Source
ChildProcessCryptoEnvironmentVarsFilesystemNetworkShell
Supply chain
HighEntropyStringsUrlStrings
ManifestNo manifest risk signals triggered.
scanned 1 file(s), 286 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, raw.githubusercontent.com, www.apple.com

Source & flagged code

5 flagged · loading source
dist/cli.jsView file
6951if (!p.quiet && (streamed || result.text) && !result.text.endsWith("\n")) { L6952: process.stdout.write("\n"); L6953: } L6954: if (p.out) { L6955: const target = resolve6(process.cwd(), p.out); L6956: try { ... L6966: // src/commands/schedule.ts L6967: import { spawnSync as spawnSync5 } from "child_process"; L6968: import { writeFileSync as writeFileSync16, mkdirSync as mkdirSync14, rmSync as rmSync6, existsSync as existsSync17 } from "fs";
Critical
Command Output Exfiltration

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

dist/cli.jsView on unpkg · L6951
6951Trigger-reachable chain: manifest.bin -> dist/cli.js L6951: if (!p.quiet && (streamed || result.text) && !result.text.endsWith("\n")) { L6952: process.stdout.write("\n"); L6953: } L6954: if (p.out) { L6955: const target = resolve6(process.cwd(), p.out); L6956: try { ... L6966: // src/commands/schedule.ts L6967: import { spawnSync as spawnSync5 } from "child_process"; L6968: import { writeFileSync as writeFileSync16, mkdirSync as mkdirSync14, rmSync as rmSync6, existsSync as existsSync17 } 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 · L6951
279// src/brains.ts L280: import { spawn, spawnSync } from "child_process"; L281: var MAX_REPLAY_TURNS = 12;
High
Child Process

Package source references child process execution.

dist/cli.jsView on unpkg · L279
4667} from "fs"; L4668: import { join as join14, resolve as resolve4, sep as sep2, isAbsolute as isAbsolute4 } from "path"; L4669: import { tmpdir } from "os"; L4670: import { spawnSync as spawnSync3 } from "child_process"; L4671: ... L4682: function registryUrl() { L4683: const env = (process.env.HOLT_REGISTRY_URL || "").trim(); L4684: return env || DEFAULT_REGISTRY_URL;
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 · L4667
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; ... L108: const ask = (q) => new Promise((resolve9) => { L109: if (q) process.stdout.write(q); L110: if (buffer.length) resolve9(buffer.shift()); ... L117: // src/workspace.ts L118: var GLOBAL_DIR = join(homedir(), ".holt"); L119: var TRUST_PATH = join(GLOBAL_DIR, "trust.json"); ... L130: try { L131: return JSON.parse(readFileSync(TRUST_PATH, "utf8")); L132: } 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