Skip to content
Back to skills

Reminders Review

ASecurity

The reminder janitor — a periodic sweep that reviews every OPEN reminder on the board and CLOSES the ones whose job is already done or whose moment has passed, so the reminders list stays a live to-do surface instead of a graveyard of stale nudges. It reads each reminder's full context via the `board` MCP, then sorts it into CLOSE (done), DISMISS (no longer relevant / superseded), KEEP-OPEN (still live, or pinned by a star / priority), or NEEDS-YOU (a passed deadline it can't prove is settled...

  • 4 stars
  • 0 votes
  • 0 copies
  • 0 views
  • Added September 2, 2026
ai-agentsrustgobashreactnoderailsawsgitapisecurity

Works with

  • api
  • mcp

Security analysis

A100/100

Scanned September 20, 2026

npx -y skills add philipyaz/cos --skill reminders-review --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Reminders Review?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Reminders Review
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/philipyaz-reminders-review/badge)](https://www.skillsdirectory.com/skills/philipyaz-reminders-review)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: reminders-review
description: >
  The reminder janitor — a periodic sweep that reviews every OPEN reminder on the
  board and CLOSES the ones whose job is already done or whose moment has passed, so
  the reminders list stays a live to-do surface instead of a graveyard of stale nudges.
  It reads each reminder's full context via the `board` MCP, then sorts it into CLOSE
  (done), DISMISS (no longer relevant / superseded), KEEP-OPEN (still live, or pinned
  by a star / priority), or NEEDS-YOU (a passed deadline it can't prove is settled). It
  AUTO-closes ONLY what is PROVEN done; every judgment call it PROPOSES for your
  approval, and it NEVER deletes. Use when the user says "review my reminders", "what
  reminders can I close", "clean up / tidy my reminders", "close the old / stale / done
  reminders", "which reminders are still relevant", "go through my reminders", or when
  the scheduled reminders-review sweep runs. Also runs the filtered-mail digest —
  first-time senders the mail sweep dropped, each a one-word keep-or-confirm ('what did
  Cos filter?').
---

# Reminders → Review (the open-reminder sweep)

This skill keeps the board's **reminders** list honest. Reminders are lightweight
nudges — *CHECK this, DO that, be READY for the parcel* — and unlike messages or
cases they have **no channel that clears them**: nothing marks a reminder done just
because the parcel arrived, the deadline passed, or you quietly decided not to apply.
So they pile up. This sweep is the counter-force: it walks **every open reminder**,
works out whether the nudge has served its purpose, and **closes the ones that have**
— by **completing** (it got done / happened) or **dismissing** (it's no longer
relevant) — so what's left is genuinely still-actionable.

It writes to the board **only** through the **`board`** MCP — never `bash`/`curl`
(Cowork's sandbox blocks outbound HTTP; the tools exist for exactly this). **The board
is a state machine; YOU are the intelligence.** The board just lists, reads, and flips
the status of reminders deterministically — it has *no* notion of "this one is stale."
Judging closeability is entirely **your** job here, from the context the reads give
you. The only writes this skill makes are `complete_reminder`,
`update_reminder {status:"dismissed"}`, and — for the filtered-mail digest (STEP 5) —
`resolve_triage_decision`; it never creates, links, or **deletes** a reminder (that's the
reconcilers' job, and hard-delete is nobody's job in this sweep).

> **Guardrail 1 — overdue is NOT the same as done.** A passed due date, or a nudge
> that's sat for weeks, is a prompt to **ASK**, not a licence to close. *"Submit the
> meter readings by Fri"* going overdue might mean you did it — **or** that you still
> owe it and it's now urgent. Only **auto-close** when the completion is **PROVEN** by
> concrete state (a checklist fully checked, a linked case in a done/closed lane, a
> one-shot delivery/event whose date has clearly passed). When "done" is merely
> **inferred** from age, **propose** it or leave it as **NEEDS-YOU** — never silently
> flip it.

> **Guardrail 2 — the human's hand wins, and a reminder carries no author.** Unlike a
> case, a reminder has **no `human`/`agent` attribution and no manual-actions block**,
> so you *cannot* tell whether the user is deliberately keeping one open. Treat that
> uncertainty conservatively: **auto-close only the PROVEN-done set** (Guardrail 1);
> route **every inferred-stale close** — age, a lapsed decision, a cold FYI — through
> **approval** so the user confirms. And **never `delete_reminder`** in this sweep:
> complete/dismiss is the **reversible** close (a done/dismissed reminder is restorable
> from Trash for ~30 days); a hard delete is not yours to make here.

---

## STEP 0 — Read the auto-sync switch (always first)

Read `config/auto-sync.json` → `{ "autoSync": <bool> }` (default **ON** if the file or
key is missing). State the mode once at the start of the run.

- **`autoSync: true` (auto mode).** **Auto-close** the **PROVEN-done** set (STEP 4
  defines exactly which) and **log every close**. Still **present** the inferred-stale
  candidates (lapsed job-alerts, past-dated plans, cold FYIs) as a **single batch** for
  a quick confirm before closing them.
- **`autoSync: false` (approval mode).** Close **nothing** directly. Gather the whole
  picture and **present every proposed close** (id · title · age · verdict · one-line
  reason) for the user to `approve`/`reject`, then close only the approved ones.

**Approval here is conversational, not the board `propose` queue.** The board's pending
queue only accepts **case** verbs (`update_case`, `move`, `archive`, `add_task`, …) —
it has **no** reminder verb, so `propose {verb:"complete_reminder"}` **400s**. So
"propose" in this skill means: **show the batch in chat, get the go-ahead, then call
`complete_reminder`/`update_reminder`.** Read-only context-gathering (`list_reminders`,
`get_reminder`, `get_case`, `get_priorities`, `search`) never needs confirmation.

## STEP 1 — Ground in priorities, then pull the open set

1. **`get_priorities` FIRST.** It returns the user's **starred** nodes and free-text
   **priority notes** (`PRI-…`). A reminder linked to (or clearly about) a starred /
   `P0`/`P1` matter is **pinned intent** — handle it conservatively (STEP 3, KEEP-OPEN
   row): surface it if it looks stale, but **never auto-close** it.
2. **`list_reminders {status:"open", verbose:true}`** — the working set **with every
   reminder's full content in ONE call**: the `detail` text, `created`/`updated` (the
   age signal — a dateless *"review X, decide whether to Y"* nudge has only its created
   date to tell you how long it's been rotting), the `dueAt`, the **task checklist with
   done-flags**, labels, domain, and linked `caseId`. This is what lets you triage the
   whole set for staleness up front **without a `get_reminder` per reminder** — pull it
   once and reason over the lot.
3. **`list_reminders {status:"done"}`** (a light pass) — learn the **recent lifecycle
   patterns** so you can match them. Example: if a prior order shows the *parcel
   delivered → reminder completed* pattern, a new *"parcel in transit"* nudge whose
   window has passed almost certainly followed suit.

## STEP 2 — Fill the two gaps the verbose list doesn't cover

The `verbose` list from STEP 1 already handed you **every reminder's own record** —
detail, age, due, checklist with done-flags, labels, `caseId` — so most of the triage
happens right there, in memory, with **no per-reminder round-trip**. You only reach for
a second read to cover the two things a reminder record can't carry:

- **The linked case's state → `get_case {caseId}`** (only for reminders that have a
  `caseId`). This is the join the board **deliberately does not do for you** — the list
  gives you the raw `caseId`, not the case. Read the case's **status / lane / tasks**:
  if the matter is in a **done/closed lane or archived**, the nudge's job is finished →
  a clean **complete**; if it's still active, the reminder is probably still live — keep
  it.
- **The linked emails → `get_reminder {id}`** — the *one* thing not on the reminder
  record. Fetch it only for the handful where an email's content would actually change
  your verdict (the `detail` usually already summarizes it).
- Use board **`search`** when a reminder might be **superseded** by a newer reminder or
  case covering the same thing (→ dismiss the duplicate).

## STEP 3 — The closeability rubric (take a CRITICAL look)

Sort every open reminder into one verdict. Be **critical** — the default failure mode
is timidity that lets 60 dead nudges rot — but obey the two guardrails: PROVEN-done
auto-closes; inferred-stale gets proposed; a maybe-still-owed deadline is NEEDS-YOU.

**First, the deeper cut — does this even pass the five tests of a real reminder?** Much
of an overgrown list isn't *stale* so much as it **never should have been a reminder**:
the reconcilers minted it from a notification, a watch, or a want. A reminder earns its
place only if **all five** hold; fail one and it's **dismissible now** with a named
reason — the same reasons the reconcilers now DROP on at creation, so the sweep and the
intake gate speak one language:

1. **Commitment, not notification** — fail → **Notification** (job alert, marketplace
   listing, "terms updated", a machine alert like disk-full). Dismiss.
2. **Ball in your court** — fail → **Watch** (waiting on someone else). Dismiss (or
   `add_note` it onto the case); it belongs back only as a *dated follow-up you own*.
3. **Real, dated consequence** — fail → **No-stakes** ("free up storage"). Dismiss.
4. **Specific next action** — fail → **Open-loop** ("review / monitor / decide whether to
   apply"). Dismiss.
5. **Ties to something you care about** — fail → **Want/courtesy** (a record, show
   tickets, a guest review). Dismiss — but this is a *values* call, so **propose**, never
   auto.

A reminder that PASSES all five is a real obligation — *then* judge it on **state**: has
it been **done**, has its **moment passed**, or is it **still live**? That's the table:

| What you observe | Verdict | Verb | Auto or propose |
|---|---|---|---|
| The reminder's own **`tasks` checklist is fully checked** (all `done`) | CLOSE | `complete` | **auto** |
| It links a case and **`get_case` shows that case in a done/closed lane or archived** | CLOSE — the nudge's job is finished | `complete` | **auto** |
| A **delivery / collection** nudge (*"parcel in transit / will be delivered soon / DELIVERED — collect"*) whose expected date has **clearly passed**, and a sibling shows the delivered→done pattern | CLOSE | `complete` | **auto** when the date is unambiguously past; else propose |
| A **one-shot dated event / plan** (*"catch-up Thu 25 Jun", "rdv Wed 19:00"*) whose `dueAt` is **in the past**, nothing recurring | CLOSE — the moment has passed | `complete` | **propose** (you can't prove it happened) — auto only if a linked case/email confirms it did |
| A **decision-window / cold FYI** (*"review the LinkedIn alert, decide whether to apply", an RSVP, "buy tickets if interested", "record available on Discogs"*) sitting **many days** past creation with no action | CLOSE — the window has effectively lapsed | `dismiss` | **propose** (never auto — it's an inference about your intent) |
| **Superseded / duplicate** — a newer reminder or a case now owns the same thing | CLOSE | `dismiss` | propose (auto only for an exact dup of one *you* made) |
| A **passed deadline you might still owe** (*"submit the meter readings by Fri", "retry the failed payment"*) that you **can't prove** is settled | KEEP-OPEN, flag it | — | **NEEDS-YOU** — never auto-close |
| **Awaiting the other side** (*"catch up with X — he'll confirm timing", "awaiting agency callbacks"*) and the window hasn't clearly lapsed | KEEP-OPEN — still live | — | leave; surface only if long-dead |
| Tied to a **starred / P0** node, or plainly still relevant | KEEP-OPEN | — | surface only if it looks stale |
| Genuinely **ambiguous** | KEEP-OPEN | — | **NEEDS-YOU** (surface, don't close) |

**`complete` vs `dismiss` — pick the honest verb.** **`complete_reminder`** = the thing
**got done or happened** (parcel delivered, event occurred, task finished); it stamps
`completedAt`. **`update_reminder {status:"dismissed"}`** = it's **off the list without
claiming completion** (a lapsed job-alert you're not pursuing, a cold FYI, a superseded
nudge); no `completedAt`. When torn between the two, **dismiss under-claims** and is the
safer choice.

## STEP 4 — Auto vs propose (the two-tier action policy)

**AUTO-CLOSE** — only when `autoSync` is **on**, and only the **PROVEN-done** rows:

- a `tasks` checklist that is **fully checked** → `complete_reminder`;
- a reminder whose **linked case is in a done/closed lane or archived** →
  `complete_reminder`;
- a **delivery/collection** nudge whose date is **unambiguously past** *and* a sibling
  shows the delivered→done pattern → `complete_reminder`.

Log each auto-close (STEP 7).

**PROPOSE** — **always**, regardless of the switch, for **every judgment call**:

- a **decision-window / cold FYI** lapse (job alerts, RSVPs, *"decide whether to"*,
  Discogs availability) → propose `dismiss`;
- a **past-dated event/plan** you can't prove happened → propose `complete`;
- **staleness inferred from age** alone rather than proven by concrete state;
- **anything tied to a starred / P0** node;
- any case where the honest verb (complete vs dismiss) is unclear.

Present proposals as **one consolidated batch** — `REM-<n> · "title" · created N days
ago · verdict · one-line reason` — not a stream of one-off prompts. Close only what the
user approves. In **approval mode**, *everything* (including the proven-done set) goes
into that batch. Route a **passed-deadline-you-might-owe** to **NEEDS-YOU**, not the
close batch.

The writes, and nothing else:

- **`complete_reminder {id}`** → flips `status:"done"`, stamps `completedAt`, logs
  `reminder_completed` on the linked case. The close-as-done.
- **`update_reminder {id, status:"dismissed"}`** → the close-as-not-relevant (no
  `completedAt`).
- **`resolve_triage_decision {id, resolution}`** → the filtered-mail digest's write (STEP 5),
  only ever following an explicit sender answer — never `block_sender`/trust ops.
- **Never `delete_reminder`.** Complete/dismiss drops it from the open view *and* stays
  reversible (Trash → restore for ~30 days). Hard-delete is out of scope.

## STEP 5 — The filtered-mail digest (first-time senders only)

`/mail-to-board`'s five-test gate DROPS a thread that fails it (a notification, a watch, a
no-stakes item, an open loop, a want/courtesy) and — since cos-ops#41 — leaves a **receipt**: a
per-`(sender, source, reason)` decision record on the board, upserted so hundreds of drops
compress into tens of rows. This STEP is the review channel for that receipt: it surfaces only
**senders being filtered for the FIRST time**, so the digest stays bounded by *new* senders, not
by mail volume, and never grows as the corpus grows. **Today this covers `source: "gmail"` only**
— `/whatsapp-triage` does not yet leave the same receipt (a named follow-on; see "What's Next"),
so the digest's scope is Gmail, stated as such below. Fully self-contained — no reference to
`/mail-to-board`'s own steps.

- **One call:** `list_triage_decisions({ source: "gmail" })`.
- **An empty digest has three meanings — branch on the numbers, never on `firstTime` alone:**
  - **Nothing new** — `firstTime` empty and `dropped > 0` → **one line**: *"nothing new was
    filtered from your mail."* — and move on (the genuine no-op: the ledger is live and no new
    sender came up).
  - **Zero drops ever** — `dropped` is `0` while `promoted > 0` (the tool answers *"No drop
    records…"*) → **report the anomaly, NOT the reassurance**: the filter's receipt has never been
    written, so "nothing new" is unverifiable. One line, both numbers, honest scopes — zero drops
    ever recorded, against `promoted` inbound Gmail threads currently on the board (a receipt
    count, never a drop rate — a dropped thread never becomes a board message, so the denominator
    counts what was kept, not what the gate faced). Then name the two candidate causes so the line
    is actionable: either the Cowork bundle for `/mail-to-board` predates the drop ledger (rebuilt
    zip never re-uploaded — the stale-bundle silent no-op), or the five-test gate has genuinely
    never fired since the ledger shipped. This branch stays a report — fix nothing, write nothing
    from here.
  - **Nothing swept yet** — `promoted` is `0` too → stay quiet; there is no sweep history to
    report on either way.
- **Otherwise**, the scale line — *"~`dropped` emails from `senders` senders filtered so far
  (promoted: `promoted`); K senders new since your last review:"* — then **one line per
  first-time sender**, never a per-email list: sender · reasons×counts · since `firstSeen` ·
  **keep or confirm?**
- **Answers, per sender** — resolve EVERY one of that sender's `ids` (from `firstTime[].ids`) the
  same way: a sender-scoped verdict, not a per-reason one.
  - **confirm** (keep filtering — the sweep is right) → `resolve_triage_decision({ id,
    resolution: "confirm" })` for each id.
  - **keep** (stop filtering — the sweep is wrong about this one) → `resolve_triage_decision({
    id, resolution: "reverse" })` for each id; the mail sweep stops dropping this sender from its
    next run.
  - **Never** write the guard's sender-trust store (`block_sender`/trust ops) from this digest —
    a keep/confirm is an **editorial** verdict about noise, not a **security** one; the two stay
    on separate axes.
- **Unanswered senders write nothing** and simply re-surface next run — idempotent, the same
  re-propose shape as this skill's own reminder batch (STEP 6). This holds in **both** auto-sync
  modes (STEP 0): the digest is conversational either way, and the *only* writes it ever makes are
  the `resolve_triage_decision` calls that follow an explicit answer.

## STEP 6 — Idempotency & re-run safety

- **A clean board no-ops.** The sweep only ever reads open reminders; a run with
  nothing stale writes nothing.
- **Closed stays closed.** `complete`/`dismiss` flips the status out of `open`, so a
  closed reminder never re-enters this sweep (it's gone from `list_reminders
  {status:"open"}`). Re-running only finds **newly** stale ones.
- **No thrash, no reopening.** This sweep **never reopens** a reminder — if the user (or
  a reconciler) deliberately keeps or re-opens one, you leave it. Convergent by design:
  each pass only *closes* the settled, so successive runs shrink the open set and then
  quiesce.

## STEP 7 — Report

When `autoSync` is **on**, append each auto-close to the matching domain log
(`work/log.md` or `life/log.md`), one line apiece:

    ## [YYYY-MM-DD] reminders-review
    Closed REM-168 (complete) — Geneva plate collected; linked CASE-26 now in Done.
    Dismissed REM-156 (proposed→approved) — AWS CSM job-alert, 15 days cold, not pursued.

Then **report** a consolidated tally:

- **Reviewed** — N open reminders.
- **Closed (auto)** — each `REM-<n>`, verb (completed/dismissed), and the one-line proof.
- **Proposed** — the batch awaiting your yes/no (or, in approval mode, everything), each
  tagged with its **reason code** (Notification · Watch · No-stakes · Open-loop ·
  Want/courtesy · done · moment-passed) so a glance shows *why*.
- **Needs you** — passed deadlines that might still be owed (e.g. the meter readings) —
  surfaced, **not** closed.
- **Kept open** — still-live nudges (awaiting the other side, future-dated, starred).
- **Filtered mail** (STEP 5) — *"K new senders surfaced (answered: X confirmed, Y kept)"*; or the
  one-line no-op (*"nothing new was filtered from your mail"*) when the ledger held drops but no
  new sender; or the zero-drops anomaly line when the ledger was empty while mail was promoted; or
  silence when nothing was ever swept.
- The board surface: **`<BOARD_URL>`** → the **Reminders** page.

---

## Board API operations — the reminder tools' contract

Every write goes **only** through the `board` MCP; here is the exact contract so a call
lands first try and you know how to react when it doesn't.

| Tool (params; `*` = required) | Route → success | Required, else **400** | Notes |
|---|---|---|---|
| `list_reminders([status],[caseId],[domain],[verbose])` | `GET /api/reminders` → **200** `{reminders[], version}` | — (read-only) | Pass **`status:"open"`** for the working set. **`verbose:true`** renders EACH reminder's full content (detail · created/updated · due · task checklist with done-flags · labels · caseId) in one call — triage the whole set without a `get_reminder` per reminder. Excludes Trash by default. |
| `get_reminder(id*)` | `GET /api/reminders/{id}` → **200** `{reminder, messages[], version}` | **`id`** | Full record: `detail`, `dueAt`, **`Created`/`Updated`**, the `tasks` checklist (done-flags), and linked emails. Does **not** expand the linked case — call `get_case` for that. |
| `get_case(id*)` | `GET /api/cases/{id}` → **200** | **`id`** | The linked matter's live **status / lane / tasks** — your proof of whether the nudge's job is done. |
| `get_priorities()` | `GET /api/priorities` → **200** | — (read-only) | Starred nodes + `PRI-…` notes = pinned intent; never auto-close against it. |
| `complete_reminder(id*)` | `PATCH /api/reminders/{id}` `{status:"done"}` → **200** `{reminder, version}` | **`id`** | The **close-as-done**. Stamps `completedAt`; logs `reminder_completed` on the linked case. |
| `update_reminder(id*, status:"dismissed")` | `PATCH /api/reminders/{id}` → **200** `{reminder, version}` | **`id`**; a bad `status`/`dueAt`/label → 400 | The **close-as-not-relevant** (no `completedAt`). Use `dismissed`, not `done`, when the thing didn't actually get done. |
| `list_triage_decisions(source*,[status])` | `GET /api/triage-decisions` → **200** `{decisions[], summary, version}` | **`source`** (read-only) | STEP 5's one read. Always pass `source:"gmail"`. `summary.firstTime` is the digest's list; `summary.dropped`/`.senders`/`.promoted` are the scale line. |
| `resolve_triage_decision(id*, resolution*)` | `PATCH /api/triage-decisions/{id}` → **200** `{decision, version}` | **`id`**, **`resolution`** (`confirm`\|`reverse`) | STEP 5's one write, only after an explicit sender answer. `confirm` keeps filtering; `reverse` = the human said keep. |

**Errors come back as an MCP `isError: true` text result — READ it, don't blindly retry:**

- **`Board returned 400: …`** — a malformed call (a `status` outside `open|done|dismissed`,
  an unparseable `dueAt`, an unknown label id, a `resolution` outside `confirm|reverse`). **Fix
  the call**, don't resend it byte-for-byte.
- **`Not found.` (404)** — a **stale `REM-<n>`** (already closed, or the id was guessed).
  Re-run `list_reminders {status:"open"}` for the **live** ids and retry. A stale `TD-<n>` from
  the digest is the same shape — re-run `list_triage_decisions` for live ids.
- **`Could not reach the board …` (network)** — the board or its bridge is down. **Stop
  and report**; write nothing. (Nothing to advance — this sweep keeps no watermark.)
- **No 409 to handle.** The `complete_reminder`/`update_reminder` tools don't send
  `expectedVersion`, so there's no optimistic-concurrency conflict — every failure is a
  400 / 404 / network case above.

## Conventions (guardrails recap)

- **BOARD-ONLY writes, and only three of them.** `complete_reminder`,
  `update_reminder {status:"dismissed"}`, and `resolve_triage_decision` (the filtered-mail
  digest, STEP 5) — never via `bash`/`curl`, never `create_reminder`/`link_*` (the reconcilers own
  creation), **never `delete_reminder`**, and never the guard's trust store.
- **Overdue ≠ done (Guardrail 1).** Auto-close only **PROVEN** completion (checklist
  done · linked case closed · one-shot delivery/event clearly past). A passed deadline
  you can't prove settled is **NEEDS-YOU**, surfaced — never flipped.
- **Reminders have no author (Guardrail 2).** You can't see who set one or whether the
  user is holding it open, so **inferred-stale closes are always proposed**, never auto.
- **complete vs dismiss — the honest verb.** `complete` = it happened / got done;
  `dismiss` = off the list without claiming completion. When torn, `dismiss`.
- **Approval is conversational.** The board `propose` queue is **case-only** (no reminder
  verb — it would 400), so "propose" = show the batch, get the go-ahead, then call the
  close tool. Present one consolidated batch, not a prompt per reminder.
- **Ground in priorities.** `get_priorities` first; a starred / `P0` / note-matched
  reminder is pinned — surface if stale, never auto-close.
- **Reversible, idempotent, non-reopening.** Complete/dismiss is restorable from Trash
  (~30 days). A closed reminder leaves the open set, so re-runs converge and never
  thrash; the sweep never reopens what someone keeps.

## Worked examples

> **1 — A delivery whose window has passed → complete (auto).** `REM-215` — *"Parcel
> from Digitec Galaxus in transit — will be delivered soon"*, **created 2026-07-03**, no
> `dueAt`. Today is several days later.

- **STEP 1** — the `list_reminders {status:"done"}` pass surfaces the sibling `REM-134`
  (*the June order, delivered 2026-06-19, now done*) — the **delivered→done pattern**.
- **STEP 3** — a *"will be delivered soon"* parcel created several days ago, with a
  sibling that followed exactly this arc, is a delivery whose window has **clearly
  passed** → **CLOSE / complete**. **STEP 4** — proven-enough by the passed window + the
  sibling pattern → **`complete_reminder("REM-215")`** (auto in auto mode). It **arrived**,
  so `complete`, not `dismiss`. *(If you truly can't tell the date passed, propose it.)*

> **2 — A job-alert decision-window gone cold → dismiss (propose).** `REM-156` — *"AWS —
> Customer Solutions Manager, Customer Migration Center (Zurich): review LinkedIn alert,
> decide whether to apply"*, **created 2026-06-21**, no `dueAt`, no application on file.

- **STEP 3** — this is a **decision-window** nudge: *~15 days* old, dateless, no action.
  The posting has almost certainly closed and the decision has defaulted to *no* — the
  window has **lapsed** → **CLOSE / dismiss** (you didn't apply; nothing was
  "completed"). But this is an **inference about your intent** (Guardrail 2), so **STEP 4
  — PROPOSE**: add it to the batch — *"REM-156 · AWS CSM job-alert · 15 days cold, no
  application → dismiss?"* — alongside its ~11 sibling job-alerts (`REM-155`, `-173`,
  `-176`, `-185`, `-194`, `-195`, `-197`, `-198`, `-214`, `-222`, …). Close the approved
  ones with **`update_reminder {status:"dismissed"}`**.

> **3 — A linked case is now Done → complete (auto).** `REM-168` — *"Geneva plate
> (rouge, porte-vélo) DELIVERED — collect at OCV guichet"*, linked `CASE-26`.

- **STEP 2** — `get_case("CASE-26")` shows the collection task closed / the matter in a
  done lane. The nudge's job is **finished** → **CLOSE / complete**, **auto**:
  **`complete_reminder("REM-168")`**. *(If `CASE-26` is still active — the plate not yet
  collected — it's **still live**: keep it.)*

> **4 — A passed deadline you might still owe → NEEDS-YOU, never auto-close.** `REM-192`
> — *"SIG — submit monthly meter readings by Fri 3 Jul 2026"*, `dueAt` now **overdue**.

- **STEP 3 — Guardrail 1.** Overdue is **not** proof of done. You either submitted the
  readings (closeable) **or** you missed the deadline and it's now **urgent** — and
  nothing in the reminder or its case proves which. So **do NOT close it**: surface it as
  **NEEDS-YOU** — *"REM-192: meter readings were due 3 Jul — did you submit them? If so
  I'll complete it; if not, it's overdue."* Let the user decide.

> **5 — Pinned by a star, looks stale → surface, don't touch.** A reminder about a
> **starred** initiative, past its `dueAt`.

- **STEP 1** — `get_priorities` shows the node is starred = **pinned intent**. Even
  though it looks stale, **never auto-close** it (Guardrail 2). At most **surface** it in
  the report — *"this starred reminder looks stale; close it?"* — and act only on an
  explicit yes.

## What's Next

After a sweep, the user can:

- **Open the Reminders page** (`<BOARD_URL>` → **Reminders**) to see the trimmed open
  list, or **Trash** to **restore** any reminder this sweep closed (reversible for ~30
  days) if a call was wrong.
- **Answer the batch** — approve/reject the proposed closes and the NEEDS-YOU questions;
  the next run acts on the decisions.
- **Re-run the sweep** — it's idempotent and non-reopening, so extra cycles that find
  nothing newly stale simply no-op. Good as a **scheduled** Cowork task (see the
  [skills README](../README.md)); a **daily / every-few-hours** cadence keeps the
  reminders list from ever rotting again.
- **Trust the source gate** — the reconcilers (`/mail-to-board`, `/whatsapp-triage`) now
  apply the **same five tests at *creation*** and DROP notifications / watches / wants,
  so the backlog is a **one-time cull**; going forward the open list stays commitments,
  not noise. (Mail drops now leave a per-sender decision record STEP 5 reviews;
  **WhatsApp drops are not yet recorded** — the named follow-on.)

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.