Skip to main content

prometheus-research

Background deep-research daemon on 127.0.0.1:7891 (crate version 0.1.0, the value /health reports; it is versioned independently of the pack release): five MCP tools (research_start/status/cancel/export, render_component), an AG-UI SSE event stream, and an A2UI registry of eight server-rendered HTMX fragments (HTMX 2.0.8 + Alpine.js vendored).

Auto-starts via com.prometheus.research.plist launchd service; installed by scripts/install-binaries.sh.

Headless job execution​

research_start (and the equivalent POST /api/v1/jobs) does not run the pipeline in-process. It spawns a headless harness child — claude, falling back to codex — and that child drives the deep-research stage contract to completion. The daemon supervises: it records the package directory, mirrors per-stage events onto the SSE stream, and maps the child's exit code onto the job status.

Resolution order, both first-match-wins:

WhatOrder
Harnessclaude, then codex, on the daemon's PATH
DriverRESEARCH_DRIVER, then CLAUDE_PLUGIN_ROOT/skills/research/deep-research/scripts/run-research.sh, then ~/.claude/skills/deep-research/scripts/run-research.sh, then the in-tree path

Relevant environment: RESEARCH_DRIVER (driver path override), RESEARCH_HARNESS_ARGS (extra harness flags), RESEARCH_EVENT_SINK and RESEARCH_EVENT_TOKEN (the token-gated ingest endpoint the child posts stage events to), RESEARCH_OUTPUT_DIR (package root, default ~/.prometheus/research).

The daemon never reports a success it did not achieve​

A child that exits 0 without leaving a package is recorded failed with harness exit code 0 without producing a package under <root>, not complete. A missing harness is blocked with an actionable message. Exit codes map to unavailable (3), refused (2), and failed (anything else). Job status, package_dir, harness, harness_pid, exit_code, and error are all readable from GET /api/v1/jobs/{id}.

research_export refuses a job that is not complete, validates the package before answering, and returns package_dir, output_path, report_path, verification_status, and verification_verdict.

Execution self-check​

The daemon reports what it would actually run — at startup and at /health — so a broken install is visible before a job is spent discovering it:

{
"execution": {
"harness": { "status": "ok", "name": "claude", "path": "…", "size_bytes": 123456 },
"driver": { "status": "ok", "path": "…", "size_bytes": 30718,
"missing_stage_contract_markers": [] }
}
}

driver.status is stale when the resolved script does not implement the stage contract — the check looks for --resume, checkpoint, next_stage, and RESEARCH_STAGE_RUNNER, and names whichever are missing. Counting markers beats comparing file size: size drifts with every edit, but a driver either speaks the contract or it does not. A stale driver would run a job to exit 0 having produced no package.

harness.status is missing when nothing on PATH resolves. Under launchd that almost always means the plist granted no PATH.

The daemon warns and keeps serving rather than refusing to start: refusing would make a broken install harder to inspect, and /health is how an operator inspects it.

Deployment requirements​

The daemon needs a harness binary on its own PATH and a driver that implements the stage contract. Under launchd the process inherits only what its plist grants, so a plist without an EnvironmentVariables/PATH entry leaves the daemon unable to find claude or codex even when both are installed. Likewise, if the installed plugin generation predates the stage-contract driver, ~/.claude/skills/deep-research/scripts/run-research.sh resolves to an older script; set RESEARCH_DRIVER, or reinstall so the current generation is published.

Canonical source: substrate/prometheus-research — modules: a2ui, agui, config, job.