diff --git a/src/data/docsNav.ts b/src/data/docsNav.ts index 9fc0444..be37ee3 100644 --- a/src/data/docsNav.ts +++ b/src/data/docsNav.ts @@ -63,6 +63,8 @@ export const docsNav: NavItem[] = [ icon: '' }, { label: 'Configuration', href: '/docs/configuration', slug: 'configuration', icon: '' }, + { label: 'Message of the Day', href: '/docs/motd', slug: 'motd', + icon: '' }, { label: 'Integration', href: '/docs/integration', slug: 'integration', icon: '' }, // Reference diff --git a/src/pages/docs/configuration.astro b/src/pages/docs/configuration.astro index 7823f09..caadf4b 100644 --- a/src/pages/docs/configuration.astro +++ b/src/pages/docs/configuration.astro @@ -213,7 +213,7 @@ const bodyContent = `

Configuration

activePage="configuration" canonicalPath="/docs/configuration" prev={{ label: "Diagnostics", href: "/docs/diagnostics" }} - next={{ label: "Integration", href: "/docs/integration" }} + next={{ label: "Message of the Day", href: "/docs/motd" }} > diff --git a/src/pages/docs/integration.astro b/src/pages/docs/integration.astro index cd97286..78b155f 100644 --- a/src/pages/docs/integration.astro +++ b/src/pages/docs/integration.astro @@ -199,7 +199,7 @@ for (const msg of inbox.messages || []) { description="Integrate Pilot Protocol with OpenClaw, heartbeat patterns, webhook-driven agents, and custom workflows." activePage="integration" canonicalPath="/docs/integration" - prev={{ label: "Configuration", href: "/docs/configuration" }} + prev={{ label: "Message of the Day", href: "/docs/motd" }} next={{ label: "Error Codes", href: "/docs/error-codes" }} > diff --git a/src/pages/docs/motd.astro b/src/pages/docs/motd.astro new file mode 100644 index 0000000..f715d53 --- /dev/null +++ b/src/pages/docs/motd.astro @@ -0,0 +1,83 @@ +--- +import DocLayout from "../../layouts/DocLayout.astro"; + +const bodyContent = `

Message of the Day

+

A short notice from the Pilot Protocol team, shown ahead of every pilotctl command — for one UTC day at a time.

+ + + +

What it is

+ +

The message of the day (MOTD) is a network-wide banner the Pilot Protocol team can surface for a single UTC calendar day. When a message is active, it is prepended to the output of every pilotctl command — used for maintenance windows, incident updates, and breaking-change heads-ups. Messages are managed centrally by the Pilot Protocol team; there is nothing to set up to receive them.

+ +
pilotctl info
+Message of the day: overlay maintenance 22:00 UTC — expect ~5min blips
+
+<normal pilotctl info output>
+ +

When no message is active for the current UTC day, output is unchanged.

+ +

How it works

+ +

Two rules drive the design: pilotctl must stay fast and never hit the network to render the banner, and the daemon must not make an on-demand call when a command runs. So the work is split:

+ + + +
central feed  ──poll──▶  pilot-daemon  ──mirror──▶  ~/.pilot/motd.json
+ (Pilot team)             (only net I/O)              the local variable
+                                                           │ read (no net, no IPC)
+                                                           ▼
+                              pilotctl <any command>  ──▶  prepends banner
+ +

No new binary ships — the poll is a goroutine inside pilot-daemon, modelled on the existing skill-reconciler loop.

+ +

Output: text vs JSON

+ +

Text mode prepends a Message of the day: <text> line and a blank line, then the normal command output.

+ +

--json mode does not prepend text (that would break parsing). Instead the standard envelope carries a top-level important_update field:

+ +
pilotctl --json info
+# { "status": "ok", "data": { ... }, "important_update": "overlay maintenance 22:00 UTC" }
+ +

The same field is added to error envelopes. The daemon also surfaces the current value as motd inside pilotctl info.

+ +

Configuration

+ +

Operators running a daemon can tune or disable polling:

+ +
pilot-daemon --motd-feed-url <url>     # feed location; empty disables polling entirely
+pilot-daemon --motd-interval 15m       # how often to re-fetch (default 15m)
+ +

The PILOT_MOTD_URL environment variable overrides the feed URL. The mirror lives next to the daemon identity (normally ~/.pilot/motd.json), which is where pilotctl looks.

+ +

Rules & semantics

+ + `; +--- + + + diff --git a/src/pages/plain/docs/motd.astro b/src/pages/plain/docs/motd.astro new file mode 100644 index 0000000..faf6e97 --- /dev/null +++ b/src/pages/plain/docs/motd.astro @@ -0,0 +1,44 @@ +--- +import PlainLayout from '../../../layouts/PlainLayout.astro'; +--- + + +

← Docs index

+ +

Message of the Day

+ +

The message of the day (MOTD) is a network-wide banner the Pilot Protocol team can surface for a single UTC calendar day. When a message is active, it is prepended to the output of every pilotctl command. Use cases: maintenance windows, incident updates, breaking-change heads-ups. Messages are managed centrally by the Pilot Protocol team; there is nothing to set up to receive them. When no message is active for the current UTC day, output is unchanged.

+ +
pilotctl info
+Message of the day: overlay maintenance 22:00 UTC — expect ~5min blips
+
+<normal pilotctl info output>
+ +

How it works

+

The daemon is the only component that touches the network. A background loop fetches the central feed every interval (default 15m), selects the entry dated for the current UTC day, holds it in memory, and mirrors it to ~/.pilot/motd.json. pilotctl reads only that local mirror — one file read, no network, no IPC — and re-validates the UTC day on read, so a stale mirror never shows yesterday's message. No new binary ships; the poll is a goroutine inside pilot-daemon.

+ +

Output: text vs JSON

+

Text mode prepends a "Message of the day: <text>" line, then the normal output. In --json mode the standard envelope carries a top-level important_update field instead (prepending text would break parsing). The same field is added to error envelopes, and the daemon surfaces the current value as motd inside pilotctl info.

+
pilotctl --json info
+# { "status": "ok", "data": { ... }, "important_update": "overlay maintenance 22:00 UTC" }
+ +

Configuration

+

Operators running a daemon can tune or disable polling:

+
pilot-daemon --motd-feed-url <url>     # feed location; empty disables polling entirely
+pilot-daemon --motd-interval 15m       # how often to re-fetch (default 15m)
+

The PILOT_MOTD_URL environment variable overrides the feed URL. The mirror lives next to the daemon identity (normally ~/.pilot/motd.json), which is where pilotctl looks.

+ +

Rules and semantics

+
    +
  • UTC days: a message is active only on its UTC calendar day. pilotctl re-checks the day on read, so a message never lingers past its UTC day.
  • +
  • Self-clearing: when the active message is withdrawn, the banner disappears on its own within one poll interval — no action needed on your machine.
  • +
  • Fail-safe: network errors and malformed responses are non-fatal; the daemon keeps its last good mirror, so a transient fetch failure never blocks a command.
  • +
+ +

Related

+ + +