@merittdev/horus 0.1.0 → 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +371 -0
- package/dist/index.cjs +1 -1
- package/package.json +3 -2
package/README.md
ADDED
|
@@ -0,0 +1,371 @@
|
|
|
1
|
+
<p align="center">
|
|
2
|
+
<img src="https://meritt-dev-assets.s3.eu-central-1.amazonaws.com/public/horus-logo-dark-20260614171147.svg" width="72" alt="Horus" />
|
|
3
|
+
</p>
|
|
4
|
+
|
|
5
|
+
# Horus
|
|
6
|
+
|
|
7
|
+
**Understand what happened.**
|
|
8
|
+
|
|
9
|
+
Horus turns logs, metrics, traces, queues, databases, and code into a deterministic incident report.
|
|
10
|
+
|
|
11
|
+
CLI-only. Read-only against production systems. Horus never writes to your infrastructure.
|
|
12
|
+
|
|
13
|
+
**Website:** [horus.sh](https://horus.sh)
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
curl -fsSL https://horus.sh/install.sh | bash
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
---
|
|
20
|
+
|
|
21
|
+
## What Horus does
|
|
22
|
+
|
|
23
|
+
Horus reads from your existing systems and reconstructs the incident through evidence, correlation, and reasoning.
|
|
24
|
+
|
|
25
|
+
It does not dump thousands of logs. It connects runtime signals to source context and returns a **deterministic report** — root cause, confidence, supporting evidence, contradictions, and recommended actions. Evidence before inference. The report is the product.
|
|
26
|
+
|
|
27
|
+
Every incident leaves evidence.
|
|
28
|
+
|
|
29
|
+
## What Horus is not
|
|
30
|
+
|
|
31
|
+
| | |
|
|
32
|
+
| ----------------- | -------------------------- |
|
|
33
|
+
| **Monitoring** | Detects problems |
|
|
34
|
+
| **Observability** | Shows signals |
|
|
35
|
+
| **Horus** | Reconstructs what happened |
|
|
36
|
+
|
|
37
|
+
Horus is not another dashboard, alerting tool, or log viewer. It sits on top of the systems you already use.
|
|
38
|
+
|
|
39
|
+
> Monitoring detects. Observability shows. Horus reconstructs.
|
|
40
|
+
|
|
41
|
+
## How it works
|
|
42
|
+
|
|
43
|
+
**Evidence in. Explanation out.**
|
|
44
|
+
|
|
45
|
+
```
|
|
46
|
+
Runtime Evidence → Investigation Engine → Investigation Report
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
| Runtime Evidence | Investigation Engine | Investigation Report |
|
|
50
|
+
| ---------------- | -------------------- | -------------------- |
|
|
51
|
+
| Logs | Correlation | Root Cause |
|
|
52
|
+
| Metrics | Timeline | Confidence |
|
|
53
|
+
| Traces | Hypotheses | Evidence |
|
|
54
|
+
| Queues | Reconstruction | Contradictions |
|
|
55
|
+
| Databases | | Recommended Actions |
|
|
56
|
+
|
|
57
|
+
Pipeline: **Evidence → Correlation → Hypotheses → Timeline → Report**
|
|
58
|
+
|
|
59
|
+
Signals are easy. Correlation is hard. Every system sees a piece of the incident — Horus connects evidence across sources so the sequence of events becomes visible.
|
|
60
|
+
|
|
61
|
+
## Sources Horus investigates
|
|
62
|
+
|
|
63
|
+
Logs · Metrics · Traces · Redis · MongoDB · Elasticsearch · BullMQ · Git · Ownership
|
|
64
|
+
|
|
65
|
+
Every signal is read-only and project-scoped.
|
|
66
|
+
|
|
67
|
+
## Example
|
|
68
|
+
|
|
69
|
+
```bash
|
|
70
|
+
horus investigate \
|
|
71
|
+
--project atlas-payments \
|
|
72
|
+
--env production \
|
|
73
|
+
"checkout latency spike"
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
```text
|
|
77
|
+
Collecting evidence...
|
|
78
|
+
✓ Elasticsearch
|
|
79
|
+
✓ Redis
|
|
80
|
+
✓ BullMQ
|
|
81
|
+
✓ Git
|
|
82
|
+
✓ Ownership
|
|
83
|
+
|
|
84
|
+
Building timeline...
|
|
85
|
+
✓ 14 events reconstructed
|
|
86
|
+
|
|
87
|
+
Correlating signals...
|
|
88
|
+
✓ 23 relationships identified
|
|
89
|
+
|
|
90
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
91
|
+
|
|
92
|
+
Root Cause: Redis connection pool exhaustion
|
|
93
|
+
Confidence: 82%
|
|
94
|
+
|
|
95
|
+
Supporting Evidence:
|
|
96
|
+
• Deploy #784
|
|
97
|
+
• Queue backlog growth
|
|
98
|
+
• Worker starvation
|
|
99
|
+
• Request timeout increase
|
|
100
|
+
|
|
101
|
+
Owner: payments-platform
|
|
102
|
+
Next Action: Inspect worker concurrency changes
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
## Principles
|
|
106
|
+
|
|
107
|
+
**Read-only** — Horus never writes to your production systems. It collects evidence and leaves everything untouched.
|
|
108
|
+
|
|
109
|
+
**Deterministic first** — Evidence before inference. Reports are built from signals and source context, not generated explanations.
|
|
110
|
+
|
|
111
|
+
**Local-first** — Runs close to your infrastructure. Connectors read from your own clusters, not a hosted black box.
|
|
112
|
+
|
|
113
|
+
**Project-scoped** — Every investigation belongs to a specific project and environment. No global defaults, no accidental cross-talk.
|
|
114
|
+
|
|
115
|
+
## Capabilities
|
|
116
|
+
|
|
117
|
+
Under active development.
|
|
118
|
+
|
|
119
|
+
**Today**
|
|
120
|
+
|
|
121
|
+
- Elasticsearch evidence
|
|
122
|
+
- MongoDB evidence
|
|
123
|
+
- BullMQ evidence
|
|
124
|
+
- Source-code investigations
|
|
125
|
+
- Timeline generation
|
|
126
|
+
- Evidence correlation
|
|
127
|
+
|
|
128
|
+
**Coming next**
|
|
129
|
+
|
|
130
|
+
- Kubernetes evidence
|
|
131
|
+
- Trace reconstruction
|
|
132
|
+
- Incident replay
|
|
133
|
+
- Slack evidence ingestion
|
|
134
|
+
|
|
135
|
+
## Can I use Horus today?
|
|
136
|
+
|
|
137
|
+
The investigation engine runs end-to-end. Some surfaces require a local setup before they work — Postgres for the audit store, a source-intelligence host, and at least one configured runtime connector for live evidence.
|
|
138
|
+
|
|
139
|
+
| Feature | Status | Notes |
|
|
140
|
+
| ------------------------------------------------- | ----------- | ----------------------------------------------------------------------------------------- |
|
|
141
|
+
| Install (`curl` or direct download) | Partial | Builds and runs from source; public binary release not yet published |
|
|
142
|
+
| `horus init` | Works today | Creates `.horus/config.json` and registers the project |
|
|
143
|
+
| `horus doctor` | Works today | Checks CLI, git root, config, and source-intelligence setup |
|
|
144
|
+
| `horus setup` | Works today | Verifies prerequisites and guides fixes |
|
|
145
|
+
| Source indexing (`horus index`) | Partial | Command works; requires a source-intelligence host running locally |
|
|
146
|
+
| `horus investigate` | Works today | Full deterministic report; requires Postgres + at least one connector or git history |
|
|
147
|
+
| `horus replay` | Works today | Re-renders a saved investigation from the audit store; no re-query |
|
|
148
|
+
| `horus postmortem` | Works today | Drafts an editable Markdown postmortem from a saved investigation |
|
|
149
|
+
| Runtime connectors (ES / Mongo / Grafana / Redis) | Partial | Connectors exist; each requires a live instance and per-project connector config |
|
|
150
|
+
| AI narrative (`--ai` flag on `investigate`) | Partial | Requires `ANTHROPIC_API_KEY`; falls back to deterministic output automatically on failure |
|
|
151
|
+
| Local AI provider bridge | Partial | Provider detection works; execution requires a local model installed |
|
|
152
|
+
|
|
153
|
+
**Prerequisites before Horus works end-to-end:**
|
|
154
|
+
|
|
155
|
+
- Postgres 16 (audit store) — `docker compose up -d` starts it
|
|
156
|
+
- At least one runtime connector configured via `horus connect <type>`
|
|
157
|
+
- Source-intelligence host running locally for source-aware commands (`horus index`, `horus explain`, `horus blast-radius`, `horus architecture`, `horus search`)
|
|
158
|
+
|
|
159
|
+
`horus replay` and `horus postmortem` work from the saved audit store and require neither live connectors nor a source-intelligence host.
|
|
160
|
+
|
|
161
|
+
---
|
|
162
|
+
|
|
163
|
+
## Architecture
|
|
164
|
+
|
|
165
|
+
Horus is organized in four layers:
|
|
166
|
+
|
|
167
|
+
**Source Intelligence**
|
|
168
|
+
|
|
169
|
+
- Built-in source-intelligence backend — code graph, semantic search, impact analysis, ownership (see below).
|
|
170
|
+
|
|
171
|
+
**Runtime Evidence**
|
|
172
|
+
|
|
173
|
+
- **Elasticsearch** — logs → synthesized error-signature evidence
|
|
174
|
+
- **MongoDB** — application/operational state
|
|
175
|
+
- **Grafana** — metrics via its datasource proxy
|
|
176
|
+
- **Redis / BullMQ** — queue runtime state
|
|
177
|
+
- **Git** — change history, ownership signals
|
|
178
|
+
|
|
179
|
+
**Investigation** (deterministic)
|
|
180
|
+
|
|
181
|
+
- **Queue Stitcher** — connects producer `queue.add(...)` to consumer `@Processor` handlers
|
|
182
|
+
- **Timeline Engine** — orders evidence into a sequence of events
|
|
183
|
+
- **Correlation Engine** — connects evidence across sources into incident threads
|
|
184
|
+
|
|
185
|
+
**Presentation**
|
|
186
|
+
|
|
187
|
+
- **Deterministic investigation report** — evidence, timeline, hypotheses, gap analysis, next actions
|
|
188
|
+
- **Optional AI narrative** — a later layer on top of the deterministic report
|
|
189
|
+
|
|
190
|
+
### Source intelligence is built into Horus
|
|
191
|
+
|
|
192
|
+
**Source intelligence is the expected intelligence layer used by Horus** — not an optional integration. Semantic search, impact analysis, ownership signals, change detection, and the process graph live in the source-intelligence backend; Horus does not duplicate them.
|
|
193
|
+
|
|
194
|
+
The **only** code-intelligence gap Horus owns is **queue-boundary stitching**: the source graph terminates around `queue.add(...)` and doesn't connect a producer to the consumer's `@Processor`. The stitcher synthesizes those producer → queue → worker edges.
|
|
195
|
+
|
|
196
|
+
> If the source-intelligence backend is unavailable, Horus can still collect runtime evidence, but source context, impact analysis, change analysis, and queue stitching become degraded.
|
|
197
|
+
|
|
198
|
+
Horus talks to the source-intelligence backend over **HTTP/MCP only** (no CLI shell-outs for queries). Run `horus index` in a repository to start and register its source-intelligence host.
|
|
199
|
+
|
|
200
|
+
## Configuration
|
|
201
|
+
|
|
202
|
+
The config model separates **code** from **runtime**:
|
|
203
|
+
|
|
204
|
+
- **Code belongs to the project** — `repositories[]`, each served by its own source-intelligence host.
|
|
205
|
+
- **Runtime belongs to the environment** — `environments[].connectors` (Elasticsearch, MongoDB, Grafana, Redis/BullMQ).
|
|
206
|
+
|
|
207
|
+
```ts
|
|
208
|
+
// config/horus.config.ts
|
|
209
|
+
export default defineConfig({
|
|
210
|
+
projects: [
|
|
211
|
+
{
|
|
212
|
+
name: 'atlas-payments',
|
|
213
|
+
repositories: [
|
|
214
|
+
{
|
|
215
|
+
name: 'atlas-payments',
|
|
216
|
+
path: '/repos/atlas-payments',
|
|
217
|
+
source: { hostUrl: 'http://127.0.0.1:8420' },
|
|
218
|
+
},
|
|
219
|
+
],
|
|
220
|
+
environments: [
|
|
221
|
+
{
|
|
222
|
+
name: 'production',
|
|
223
|
+
readOnly: true,
|
|
224
|
+
connectors: {
|
|
225
|
+
elasticsearch: {
|
|
226
|
+
indexPattern: 'atlas-payments-prod-*',
|
|
227
|
+
serviceName: 'atlas-payments-prod',
|
|
228
|
+
},
|
|
229
|
+
mongodb: {
|
|
230
|
+
database: 'atlas_payments_prod',
|
|
231
|
+
collections: ['orders', 'payments', 'workers'],
|
|
232
|
+
},
|
|
233
|
+
grafana: {},
|
|
234
|
+
},
|
|
235
|
+
},
|
|
236
|
+
],
|
|
237
|
+
},
|
|
238
|
+
],
|
|
239
|
+
database: {
|
|
240
|
+
url: process.env.DATABASE_URL ?? 'postgresql://horus:horus@localhost:5433/horus',
|
|
241
|
+
},
|
|
242
|
+
});
|
|
243
|
+
```
|
|
244
|
+
|
|
245
|
+
**No connector runs without an explicit project/env scope** — there are no global connector defaults.
|
|
246
|
+
|
|
247
|
+
**Secrets are never committed.** Connector credentials are read from environment variables at runtime. Keep them in a gitignored file (e.g. `~/.horus.env`) and `source` it before running. For a full reference on which Horus files to commit and which to gitignore, see **[docs/gitignore-guide.md](./docs/gitignore-guide.md)**.
|
|
248
|
+
|
|
249
|
+
## Install
|
|
250
|
+
|
|
251
|
+
```bash
|
|
252
|
+
curl -fsSL https://horus.sh/install.sh | bash
|
|
253
|
+
horus --version
|
|
254
|
+
horus setup
|
|
255
|
+
```
|
|
256
|
+
|
|
257
|
+
The installer downloads the Horus CLI from GitHub Releases and installs it to your PATH. No npm step required.
|
|
258
|
+
|
|
259
|
+
### What the installer installs
|
|
260
|
+
|
|
261
|
+
| Component | Role | Required |
|
|
262
|
+
| ------------------------------------- | ----------------------------------------------------------------------------- | -------- |
|
|
263
|
+
| **Horus CLI** | The `horus` command | Yes |
|
|
264
|
+
| **Horus source-intelligence backend** | Enables `horus index`, `horus explain`, `horus changes`, `horus architecture` | Optional |
|
|
265
|
+
|
|
266
|
+
### Prerequisites
|
|
267
|
+
|
|
268
|
+
| Requirement | Role |
|
|
269
|
+
| --------------------- | -------------------------------------------------------------------------------------------- |
|
|
270
|
+
| Node.js 22+ | Horus CLI runtime (the installed binary needs Node.js) |
|
|
271
|
+
| Postgres 16 | Investigation audit store — run locally via `docker compose up -d` or use a managed instance |
|
|
272
|
+
| Python 3.11+ + uv/pip | Required only for the source-intelligence backend |
|
|
273
|
+
|
|
274
|
+
The installer **does not** configure Elasticsearch, MongoDB, Grafana, Redis, or any production system. Runtime connectors are added per-project after install via `horus connect`.
|
|
275
|
+
|
|
276
|
+
### Direct download (without the curl installer)
|
|
277
|
+
|
|
278
|
+
```bash
|
|
279
|
+
# Replace vX.Y.Z with the current release tag
|
|
280
|
+
curl -fsSL https://github.com/meritt-dev/horus/releases/download/v0.1.0/horus-v0.1.0 -o horus
|
|
281
|
+
chmod +x horus
|
|
282
|
+
sudo mv horus /usr/local/bin/horus
|
|
283
|
+
horus --version
|
|
284
|
+
```
|
|
285
|
+
|
|
286
|
+
**Package managers:** npm (`npm install -g @merittdev/horus`) is now live. The Homebrew tap (`meritt-dev/tap`) is prepared but still pending publish approval. See [docs/install.md](./docs/install.md#package-manager-installs) for the channel comparison and commands.
|
|
287
|
+
|
|
288
|
+
To **update** to a newer version, re-run the installer — it overwrites the binary and leaves your config untouched. To **uninstall**, see **[docs/install.md#uninstall](./docs/install.md#uninstall)** for what to remove and what to keep.
|
|
289
|
+
|
|
290
|
+
If something goes wrong after install, see **[docs/troubleshooting.md](./docs/troubleshooting.md)** for symptoms, likely causes, and exact fix commands covering: config missing, database not running, source-intelligence host unreachable, no indexed repo, connector not configured, and low-confidence reports.
|
|
291
|
+
|
|
292
|
+
## Local development / Usage
|
|
293
|
+
|
|
294
|
+
```bash
|
|
295
|
+
pnpm install
|
|
296
|
+
docker compose up -d # Postgres 16 on localhost:5433
|
|
297
|
+
pnpm build # builds apps/horus/dist/index.cjs
|
|
298
|
+
|
|
299
|
+
# Per repository: start the source-intelligence host and stitch queue boundaries
|
|
300
|
+
horus index
|
|
301
|
+
|
|
302
|
+
source ~/.horus.env
|
|
303
|
+
|
|
304
|
+
node apps/horus/dist/index.cjs status
|
|
305
|
+
```
|
|
306
|
+
|
|
307
|
+
**Verify the full v0.1 user path (init → investigate → replay → postmortem):**
|
|
308
|
+
|
|
309
|
+
```bash
|
|
310
|
+
# No-services startup check (version, help, doctor):
|
|
311
|
+
./scripts/smoke-test.sh apps/horus/dist/index.cjs
|
|
312
|
+
|
|
313
|
+
# Full end-to-end flow (requires Postgres from docker compose up -d):
|
|
314
|
+
./scripts/e2e-smoke.sh apps/horus/dist/index.cjs
|
|
315
|
+
```
|
|
316
|
+
|
|
317
|
+
```bash
|
|
318
|
+
horus --help
|
|
319
|
+
horus help <command>
|
|
320
|
+
horus investigate --help
|
|
321
|
+
```
|
|
322
|
+
|
|
323
|
+
### Core commands
|
|
324
|
+
|
|
325
|
+
| Command | What it does |
|
|
326
|
+
| --------------------------------------------------------------------------- | --------------------------------------------------------------------- |
|
|
327
|
+
| `horus status [--project --env]` | Per-project/env connector-health matrix |
|
|
328
|
+
| `horus index --project <p> --env <e>` | Build the queue map (stitcher) for a project |
|
|
329
|
+
| `horus investigate --project <p> --env <e> "<hint>"` | Full deterministic investigation report |
|
|
330
|
+
| `horus logs [service] --project <p> --env <e>` | Error-signature evidence (`--raw` for lines) |
|
|
331
|
+
| `horus state --project <p> --env <e>` | MongoDB application-state evidence (read-only) |
|
|
332
|
+
| `horus metrics [hint] --project <p> --env <e>` | Grafana metrics evidence |
|
|
333
|
+
| `horus explain <symbol>` · `blast-radius` · `architecture` · `what-changed` | Source-aware code intelligence (requires source-intelligence backend) |
|
|
334
|
+
|
|
335
|
+
## Local project workflow (git-style)
|
|
336
|
+
|
|
337
|
+
A repo carries a `.horus/config.json` (discovered by walking up from the working directory, like `.git`), and a global registry (`~/.horus/registry.json`) lets `--name` resolve a project from anywhere.
|
|
338
|
+
|
|
339
|
+
```bash
|
|
340
|
+
horus setup
|
|
341
|
+
|
|
342
|
+
cd /repos/atlas-payments
|
|
343
|
+
horus index
|
|
344
|
+
|
|
345
|
+
horus investigate "checkout latency spike"
|
|
346
|
+
horus investigate --name atlas-payments "checkout latency spike"
|
|
347
|
+
horus projects
|
|
348
|
+
```
|
|
349
|
+
|
|
350
|
+
`horus index` reuses an already-running source-intelligence host when one is healthy. Runtime connectors are added to the env block of `.horus/config.json` afterwards.
|
|
351
|
+
|
|
352
|
+
## Layout
|
|
353
|
+
|
|
354
|
+
```
|
|
355
|
+
packages/
|
|
356
|
+
core/ evidence model, config schema + project/env resolution, version pins
|
|
357
|
+
connectors/ provider contracts + source intelligence (HTTP/MCP) · Elasticsearch · Grafana · MongoDB · Git
|
|
358
|
+
stitcher/ queue-boundary stitcher
|
|
359
|
+
db/ Drizzle schema + migrations (plain Postgres, no pgvector)
|
|
360
|
+
engine/ deterministic investigation pipeline (timeline, correlation, hypotheses, gaps)
|
|
361
|
+
cli/ commander CLI
|
|
362
|
+
apps/horus/ composition root (bundled bin)
|
|
363
|
+
config/ horus.config.ts
|
|
364
|
+
```
|
|
365
|
+
|
|
366
|
+
## Foundation
|
|
367
|
+
|
|
368
|
+
- TypeScript monorepo (pnpm + Turborepo)
|
|
369
|
+
- Postgres + Drizzle — semantic search delegated to source-intelligence backend
|
|
370
|
+
- Built-in **source-intelligence backend**, over HTTP/MCP only
|
|
371
|
+
- Project/environment-scoped connectors; read-only against production
|
package/dist/index.cjs
CHANGED
|
@@ -50314,7 +50314,7 @@ init_cjs_shims();
|
|
|
50314
50314
|
|
|
50315
50315
|
// ../../packages/core/src/version.ts
|
|
50316
50316
|
init_cjs_shims();
|
|
50317
|
-
var HORUS_VERSION = "0.1.
|
|
50317
|
+
var HORUS_VERSION = "0.1.1";
|
|
50318
50318
|
var PINNED_AXON_VERSION = "1.0.1";
|
|
50319
50319
|
var PINNED_SOURCE_VERSION = PINNED_AXON_VERSION;
|
|
50320
50320
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@merittdev/horus",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.1",
|
|
4
4
|
"description": "Local-first, source-aware production-incident investigation engine",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -13,7 +13,8 @@
|
|
|
13
13
|
"build": "tsup",
|
|
14
14
|
"typecheck": "tsc --noEmit",
|
|
15
15
|
"test": "tsup && vitest run --passWithNoTests",
|
|
16
|
-
"prepublishOnly": "tsup"
|
|
16
|
+
"prepublishOnly": "tsup",
|
|
17
|
+
"prepack": "cp ../../README.md README.md"
|
|
17
18
|
},
|
|
18
19
|
"engines": {
|
|
19
20
|
"node": ">=22"
|