lazy documentationv0.91

System messages

System messages are proactive reports the system writes for the human: a first-class inbox that report tasks, the daemon, and the builder file into, and that every surface can always display.

Lazy should help you unprompted — a task whose job is to produce a report (a post-mortem, a tool-call pattern analysis, a token usage summary) files its findings here, and system messages are how those findings reach you. The same inbox is how an agent tells you that something in your environment is broken and only you can fix it. You don't have to remember to run anything: unread messages appear in the builder's launch context, and lazy messages shows the inbox at any time.

What a message is

Each message carries:

Field Meaning
id UUID; any unique prefix works on the CLI and MCP tools
source What produced it — a task code, daemon, or builder. Derived from the producer's identity, never free-form input
title One-line headline; compact surfaces render only this. Single-line by contract: newlines and control characters are rejected at the post boundary (unread titles are rendered into the builder's prompt, and the builder is an agent too)
body The full report (markdown)
kind report (a produced analysis), notice (a system event worth knowing), or alert (needs attention soon)
read_at / dismissed_at Lifecycle state — see below

Lifecycle: append-only, never deleted

Creation is append-only. Messages are never edited or deleted — reading and dismissal are state changes on the message, so the record of what the system told you is permanent:

Surfaces

Builder launch. Unread messages are injected compactly into the builder's system prompt — the same shape as the memory index: title + attribution per message, bodies on demand via lazy_messages(id="..."). The builder is expected to relay them to you. A storage failure logs loudly and skips the section; it never blocks the launch.

CLI.

lazy messages                 # the inbox (dismissed hidden)
lazy messages read 3f9a01b2   # full body; marks it read
lazy messages dismiss 3f9a01b2
lazy messages list --all      # everything, including dismissed

MCP tools.

Web inbox. The daemon's built-in dashboard — lazy daemon dashboard-url prints its address — serves the same inbox at /messages:

Both actions are ordinary form submissions — the inbox works with scripting turned off. The dashboard is a loopback surface for the person sitting at the machine; dismissals from it are recorded as human, exactly as the CLI's are.

Why agents may post but not dismiss

Shared memory is agent-read-only because memory records are injected into every future session as guidance — an agent-writable store would be a prompt-injection channel. System messages are different: they are attributed data displayed to the human, never injected into agent prompts as guidance, so agent creation is safe — and necessary, because report tasks run as agents. Dismissal is the human's (or their builder's) decision alone.

Environment blockers agents cannot fix

The other thing that lands in your inbox is a blocker an agent hit and cannot do anything about from inside its task: a wedged CI runner, a stuck process holding a lock, an expired credential, a broken shared fixture, a machine out of disk.

Agents are told to investigate a failing check on their own branch rather than call it "out of scope" — and when the cause turns out to be infrastructure rather than the code, to tell you what is broken, the evidence, the concrete remedy, and which task hit it. The kind says how urgent it is: alert when the blocker is holding up that task's acceptance, notice when it isn't. You are the only one who can fix these, and you can't fix what nobody reported; a message is also how a recurring blocker becomes a permanent fix instead of something every future task works around.

This is distinct from the per-task channel an agent has. A raised item (lazy raised) is either a decision about that task's own scope or diff — one that blocks accept until you answer it — or orthogonal code work for you to triage later, which never blocks. A system message is neither — it's a report about your environment, and it belongs to the project rather than to one task.

Boundary: not lazy's own diagnosis channel

lazy doctor remains the single diagnosis surface for lazy's own configuration and health — commands print one generic "Run lazy doctor" pointer and doctor owns the details, so other commands do not file doctor-shaped warnings here. Doctor itself files one inbox alert when a run finds errors, so people who never run lazy doctor still see the findings. System messages otherwise carry things written for you: proactive reports and analyses, and blockers in your project's environment that only you can clear.

Built-in producers