Lamprey Diagnostics & Tooling
SkillCommerce & financeHow to MEASURE Lamprey instead of eyeballing it — verify-proof and its skip accounting, the smoke scripts, streaming vitals, the events/tool_calls audit tables, the reasoning trace surface, prompt byte measurement, token accounting — plus tested read-only inspection scripts (db-health.cjs, loop-state.cjs) shipped in this skill's scripts/ directory. Load when you need numbers, evidence, or an incident timeline rather than an impression.
Available today. Use it from your connected AI after setup.
No other account needed.
Connect ahel once, and every AI you use reads what you have installed.
Then ask your AI: use the Lamprey Diagnostics & Tooling skill
What this skill tells your AI
The instructions your AI receives, as published by uss-parks/lamprey-harness in .claude/skills/lamprey-diagnostics-and-tooling/SKILL.md and read by ahel’s review.
When to use / when not
- Use when you need to quantify something: is the stream alive, what did this turn cost, what happened at 14:32, how big is the prompt, is the DB healthy.
- Don't use for triage decision trees (see
lamprey-debugging-playbook), the meaning of gate layers (seelamprey-validation-and-qa), or loop test protocols (seelamprey-loop-reliability-campaign).
Shipped scripts (in scripts/ next to this file — tested 2026-07-02)
Both are read-only (SQLite opened readOnly: true), take the DB path as an optional argument (default: the platform userData path), and degrade gracefully when tables are missing. Requires Node ≥ 22 (node:sqlite). Copy the DB or close the app first if you're paranoid; read-only mode is safe alongside WAL but a copy is safer for long analysis.
db-health.cjs — one-shot health report
node .claude/skills/lamprey-diagnostics-and-tooling/scripts/db-health.cjs "%APPDATA%\Lamprey\lamprey.db"
Reports: file size, user_version (compare to LATEST_VERSION = 18 as of v0.16.0 — a lower live value means migrations aren't running: the v0.9.2 signature), integrity_check, table count, row counts for the 14 key tables, orphan messages (expected 0 since JM-17 transactional deletes), pending wake-up total, and loops stuck in running.
Real example output (synthetic fixture with one planted orphan):
user_version: 18 (compare to LATEST_VERSION in electron/services/db-migrations.ts — 18 as of v0.16.0)
integrity_check: ok
...
orphan messages (no conversation): 1 (expected 0 — deleteConversation is transactional since v0.16.0)
pending loop wake-ups: 1 (cap is 10 per conversation; a big global number deserves a look)
loops currently marked running:
{"id":"l1","status":"running","iteration":3}
Interpretation: non-zero orphans on a ≥v0.16.0 DB = a deletion path regressed. A running loop while the app is closed = crash-recovery sweep candidate (it should be settled on next launch — if it persists, that's a campaign finding).
loop-state.cjs — loop subsystem dump
node .claude/skills/lamprey-diagnostics-and-tooling/scripts/loop-state.cjs "%APPDATA%\Lamprey\lamprey.db"
Dumps: loops (status, iteration, active_ms — the JM-6 working-time ceiling counter), recent loop_runs, loop_backlog, latest loop_wakeups, and pending wake-ups per conversation (cap 10). This is the primary evidence tool for lamprey-loop-reliability-campaign.
The built-in diagnostic surfaces
| Surface | Where | How to read it |
|---|---|---|
| verify:proof | npm run verify:proof (flags --no-tests, --require-smokes, --list-native-skips) | Composite gate. Always read the native-skip accounting block: it states whether better-sqlite3 loads under the current Node and lists the guarded test cohort. Any skip on a dev machine ≥ Electron 43 is a finding. |
| Bundle/renderer smokes | npm run smoke:bundle, npm run smoke:renderer | Exit 0 or a specific failure (missing asset, empty chunk, no createRoot). A smoke failure after a dep bump usually means bundler hoisting/TDZ — see lamprey-build-and-env. |
| Streaming vitals | chat:streaming-vitals event (~2s) → "Ns since last chunk" pill | Distinguishes "model thinking" (N resets on chunks) from "stream dead" (N climbs toward the 60s watchdog). |
| events table | SELECT * FROM events ORDER BY rowid DESC LIMIT 50 (read-only, node:sqlite) | Structured event log incl. model.request.started/completed/failed, key mutations (no key values), tool lifecycle. Reconstruct an incident timeline by conversation id + timestamps. 90-day retention. |
| tool_calls table | SELECT tool_name,status,id FROM tool_calls ORDER BY rowid DESC LIMIT 50 | Every call with terminal status (completed/failed/denied). fb_-prefixed ids = fallback-parsed calls (trust-degraded). |
| Reasoning Trace viewer | right-panel pill; export to .md/.csv | Full per-turn chain-of-thought audit (local only). Use for "why did the model do that" questions instead of speculating. |
| Token/cost accounting | per-turn accumulation from runChatRound (JM-12: counts the full sent stack per round, not just the prompt) | Loop token budgets consume this; read a loop's spend from loops / loop_runs rows. |
| Debug trace | opt-in setting only | Writes tool arguments to plaintext lamprey-debug.log in userData. The JM-1 incident: it once shipped force-enabled. Enable for a session, harvest, turn it off. Never commit a force-enable. |
Prompt byte measurement
Prompt size is a managed budget here (the Lampshade→Hygiene→Unburdening arc). To re-measure:
- Locate the guard tests:
grep -rn "3,\?300\|3300\|3,\?900\|3900" electron/services/system-prompt-builder*.test.ts electron/services/*.test.ts 2>/dev/null | head— the contract guard is < 3,300 bytes and the coding-mode prompt guard is < 3,900 bytes as of UB-8 (v0.14.0). - Measure directly: import/build the prompt in a scratch node script via the same builder functions a test uses (see how the guard test constructs it), then
Buffer.byteLength(prompt, 'utf8'). - Any growth needs justification against the guard (see
lamprey-proof-and-analysis-toolkitrecipe 3). Raising a guard number is a reviewed decision, not a fix.
Incident timeline recipe
- Pin the window (user report time ± a few minutes).
eventsrows in that window for the conversation → request lifecycle + failures.tool_callsfor the same window → what executed, what was denied,fb_provenance.messages(content,content_raw,reasoning,role='system'notices) → what the user saw vs what the model emitted.- If loops are involved:
loop-state.cjs+loop_runsaround the window. - Write the chain down (first cause → amplifier → detection gap) per the postmortem method in
lamprey-proof-and-analysis-toolkitrecipe 5.
Provenance and maintenance
Scripts authored and run 2026-07-02 against a synthetic fixture (output above is real). Surfaces verified against scripts/verify-proof.cjs, providers/registry.ts (vitals), DEVLOG JM entries, at v0.16.0.
Re-verify:
- Scripts still run:
node .claude/skills/lamprey-diagnostics-and-tooling/scripts/db-health.cjs <db>(exit 0) - verify:proof flags:
head -25 scripts/verify-proof.cjs - Byte guards current values:
grep -rn "3300\|3900" electron/services/*.test.ts | head -5 - Retention window:
grep -rn "90" electron/services/*retention* electron/services/*sweep* 2>/dev/null | head -3
Signals
- GitHub stars
- 62
- Forks
- 2
- Last commit
- Sep 2026
Advanced
- Catalog kind
- skill
- Gateway key
lamprey-diagnostics-and-tooling- Source
- github.com/uss-parks/lamprey-harness