bash-notification-reminders · v1.1.0 · 2026-09-09 · sha256 d483abf0ed94444c
bash-notification-reminders v1.1.0A
Immutable. This exact content is served forever at /api/v1/blob/d483abf0ed94444c.
---
name: bash-notification-reminders
description: >
Nested shell-manual reference for one-shot wakeup reminders using
`.notification/cron.json`: payload, atomic writer, shell example, and the
rest checklist for pending work.
version: 1.1.0
last_changed_at: 2026-09-09T00:00:00Z
related_files:
- src/lingtai/tools/bash/manual/SKILL.md
- src/lingtai/tools/notification/__init__.py
- src/lingtai/tools/notification/schema.py
- src/lingtai/tools/bash/manual/reference/scheduled-work/SKILL.md
maintenance: |
Tracks one-shot notification reminders; update when that integration changes.
---
# One-shot notification reminders
For native Shell/Daemon jobs, rely on their completion notification; do not add
a competing timer. Only for async work without a reliable completion wake, use
`system(action="sleep", input={"reason": "check pending work", "force": false,
"delay": 240}, reasoning="last-resort wake")` as a last-resort one-shot alarm; `system-manual` owns its detail.
For an already-authorized external workflow requiring the cron channel, schedule
the writer below for the chosen future time. Running it now publishes now;
it does not create a timer. A reminder writes one complete
notification envelope to `<agent-workdir>/.notification/cron.json`; it is not a
recurring scheduler, human notification, or guarantee across process death and
sleep. After acting, dismiss the `cron` channel:
```text
notification(action="dismiss_channel",
input={"channel": "cron", "force": null, "reason": null},
reasoning="the cron reminder is handled")
```
Use a custom writer only when the built-in wake is unsuitable. Do not use it
for a human-facing message, a delay that must survive reboot (use
launchd/systemd/crontab), or frequent polling. Set one sane wake and rest.
## Envelope
A producer that cannot import the helper must still write the full shape:
```json
{
"header": "Cron reminder: check pending work",
"icon": "⏰",
"priority": "normal",
"published_at": "2026-05-18T06:42:00Z",
"data": {
"source": "cron-reminder",
"message": "Background work is still pending.",
"todo": "Check the named job and inspect its output.",
"reminder_id": "task-followup-2026-05-18T06-42"
}
}
```
Keep `published_at` as a UTC ISO timestamp and make `reminder_id` stable enough
to recognize duplicates. `message` says what changed; `todo` says the concrete
next action. Write through a temporary sibling and rename atomically:
```python
import json, os, pathlib
from datetime import datetime, timezone
agent = pathlib.Path(os.environ["AGENT_DIR"])
notification = agent / ".notification"
notification.mkdir(exist_ok=True)
payload = {
"header": "Cron reminder: check pending work", "icon": "⏰",
"priority": "normal",
"published_at": datetime.now(timezone.utc).strftime("%Y-%m-%dT%H:%M:%SZ"),
"data": {"source": "cron-reminder", "message": "Work is pending.",
"todo": "Check job status and output.",
"reminder_id": os.environ.get("REMINDER_ID", "cron-reminder")},
}
target = notification / "cron.json"
tmp = target.with_suffix(".json.tmp")
tmp.write_text(json.dumps(payload, ensure_ascii=False) + "\n", encoding="utf-8")
tmp.replace(target)
```
## Rest and wake
Before resting: record the state/check target in pad. For a custom cron wake,
save the writer as an authorized task script and schedule it once at the chosen
time using [scheduled work](../scheduled-work/SKILL.md); do not execute it
immediately and expect a delay. Then end the turn and rely on the event. On wake, handle the reminder, inspect the named job, and dismiss `cron`.
A detached `sleep` writer can be lost if the process or machine stops; use the
scheduled-work reference for longer or recurring delays.