Daily cadence cards accumulate forever: add deadlines + a deterministic reaper cron #1

Open
opened 2026-08-02 05:17:55 +00:00 by alvis · 0 comments
Owner

Daily cadence cards accumulate forever: give them a deadline and let a deterministic cron reap the missed ones.

Problem

proactive-cadence.py (the Triggering layer, kb#124) creates one Kanboard Backlog card per day in the Adolf project and exits. Nothing drains them. They have no date_due, so nothing can ever decide they are stale, and they stay open indefinitely.

Observed today: #226 (2026-07-31) and #240 (2026-08-01) both open, un-actioned, and un-actionable — the audit window they describe ("calendar for the next 24-48h", "dates for today/tomorrow") has already passed. A card describing yesterday's 24h window is not work, it is litter.

At one card per day this puts ~365 permanent cards a year onto a board that is read by a human.

Why this is a design flaw, not just a missing feature

DESIGN-a2a-agents.md §2 states the granularity rule: a Task is a durable work item with a lifecycle worth auditing; anything else stays out of the KB-literal fabric. A recurring daily sweep is a scheduled routine, not a durable work item — it fails that rule, and the fabric is accumulating exactly the micro-churn the rule exists to prevent.

The KB-literal decision itself (§10.2, 2026-07-21) is fine. What is missing is the expiry half.

Proposed fix

Two parts, both deterministic — no LLM is needed or wanted here:

  1. Cadence cards get a deadline. proactive-cadence.py sets date_due on creation, sized to the tier: daily = end of the same day, weekly = end of that week, monthly = end of that month. A daily audit that has not run by midnight has missed its window by definition.

  2. A plain cron reaps expired cadence cards. Any card tagged cadence:* that is still open past its date_due is deleted (or closed with a missed note — see open question). This is a date comparison over a tag-filtered query. It needs no model, no quota, and no judgement.

This also aligns the implementation with the design: §6b already assigns deadline enforcement to the fabric-keeper (fabric-keeper.py, enforce_deadlines()), and §6b explicitly says missed cron windows are an operational fault, not something to retro-fire. Reaping a missed cadence card is the correct expression of that — the beat is skipped, not caught up.

Scope

  • Set date_due per tier in proactive-cadence.py at card creation.
  • Reap expired cadence:* cards from cron (preferably as a fabric-keeper duty rather than a new standalone script).
  • Reap the existing orphans: #226, #240.
  • Only ever touch cards carrying a cadence:* tag. Never a human-authored card.

Open questions

  • Delete or close-as-missed? Deleting keeps the board genuinely clean; closing preserves an audit trail of how often the cadence fired without being consumed — which is itself the signal that the executor is still missing. Suggest closing with a missed note initially, and revisiting once an executor exists.
  • Should reaping be silent, or should repeated misses raise something? A cadence that misses every single day means the triggering layer is running into a void; that is worth knowing about once, not 365 times.
  • kb#124 — the cadence task (in WIP, tagged blocked / needs-criteria)
  • kb#154 — fabric-keeper (A2A-22), the natural owner of this
  • kb#123 — impact/cost gate, sits between "candidate exists" and "send"
  • Cards #226, #240 — the current orphans

Note on the wider gap

Reaping fixes the accumulation, not the silence. Nothing consumes cadence cards at all, so no daily update ever reaches Matrix. That executor is separate work and is not in scope here — but if it never lands, this reaper is the only thing that will ever touch these cards.

Daily cadence cards accumulate forever: give them a deadline and let a deterministic cron reap the missed ones. ## Problem `proactive-cadence.py` (the Triggering layer, kb#124) creates one Kanboard Backlog card per day in the Adolf project and exits. Nothing drains them. They have no `date_due`, so nothing can ever decide they are stale, and they stay open indefinitely. Observed today: #226 (2026-07-31) and #240 (2026-08-01) both open, un-actioned, and un-actionable — the audit window they describe ("calendar for the next 24-48h", "dates for today/tomorrow") has already passed. A card describing yesterday's 24h window is not work, it is litter. At one card per day this puts ~365 permanent cards a year onto a board that is read by a human. ## Why this is a design flaw, not just a missing feature `DESIGN-a2a-agents.md` §2 states the **granularity rule**: a Task is a durable work item with a lifecycle worth auditing; anything else stays out of the KB-literal fabric. A recurring daily sweep is a scheduled routine, not a durable work item — it fails that rule, and the fabric is accumulating exactly the micro-churn the rule exists to prevent. The KB-literal decision itself (§10.2, 2026-07-21) is fine. What is missing is the expiry half. ## Proposed fix Two parts, both deterministic — **no LLM is needed or wanted here**: 1. **Cadence cards get a deadline.** `proactive-cadence.py` sets `date_due` on creation, sized to the tier: daily = end of the same day, weekly = end of that week, monthly = end of that month. A daily audit that has not run by midnight has missed its window by definition. 2. **A plain cron reaps expired cadence cards.** Any card tagged `cadence:*` that is still open past its `date_due` is deleted (or closed with a `missed` note — see open question). This is a date comparison over a tag-filtered query. It needs no model, no quota, and no judgement. This also aligns the implementation with the design: §6b already assigns deadline enforcement to the **fabric-keeper** (`fabric-keeper.py`, `enforce_deadlines()`), and §6b explicitly says missed cron windows are an operational fault, not something to retro-fire. Reaping a missed cadence card is the correct expression of that — the beat is skipped, not caught up. ## Scope - Set `date_due` per tier in `proactive-cadence.py` at card creation. - Reap expired `cadence:*` cards from cron (preferably as a `fabric-keeper` duty rather than a new standalone script). - Reap the existing orphans: #226, #240. - Only ever touch cards carrying a `cadence:*` tag. Never a human-authored card. ## Open questions - **Delete or close-as-missed?** Deleting keeps the board genuinely clean; closing preserves an audit trail of how often the cadence fired without being consumed — which is itself the signal that the executor is still missing. Suggest closing with a `missed` note initially, and revisiting once an executor exists. - Should reaping be silent, or should repeated misses raise something? A cadence that misses every single day means the triggering layer is running into a void; that is worth knowing about once, not 365 times. ## Related - kb#124 — the cadence task (in WIP, tagged `blocked` / `needs-criteria`) - kb#154 — fabric-keeper (A2A-22), the natural owner of this - kb#123 — impact/cost gate, sits between "candidate exists" and "send" - Cards #226, #240 — the current orphans ## Note on the wider gap Reaping fixes the accumulation, not the silence. Nothing consumes cadence cards at all, so no daily update ever reaches Matrix. That executor is separate work and is not in scope here — but if it never lands, this reaper is the only thing that will ever touch these cards.
Sign in to join this conversation.
No Label
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: alvis/adolf#1