Slice 16 — weekly self-review scaffold.
Fires Sunday evening (UTC, configurable) via :class:AsyncCronScheduler.
Writes WeeklyReview/{iso_year}-W{iso_week:02d}.md summarising the
week's meetings, completed tasks, logged commitments, and chat
highlights.
Idempotency: the ISO week string (e.g. "2026-W17"). Re-runs within
the same week short-circuit inside :class:MemoryInformedWriter.
WeeklyReviewSkill
WeeklyReviewSkill(*, writer: MemoryInformedWriter, memory_store: MemoryStore, vault_client: VaultClient, connection: Connection, config: WeeklyReviewSkillConfig, user_id: str)
Compose a week's worth of memory context and delegate to the writer.
Source code in src/donna/capabilities/weekly_review_skill.py
| def __init__(
self,
*,
writer: MemoryInformedWriter,
memory_store: MemoryStore,
vault_client: VaultClient,
connection: aiosqlite.Connection,
config: WeeklyReviewSkillConfig,
user_id: str,
) -> None:
self._writer = writer
self._memory_store = memory_store
self._vault_client = vault_client
self._conn = connection
self._config = config
self._user_id = user_id
|
TEMPLATE
class-attribute
instance-attribute
TEMPLATE = 'weekly_review.md.j2'
TASK_TYPE
class-attribute
instance-attribute
TASK_TYPE = 'draft_weekly_review'
run_for_week
async
run_for_week(week_start: date) -> WriteResult
Source code in src/donna/capabilities/weekly_review_skill.py
| async def run_for_week(self, week_start: date) -> WriteResult:
week_start = _week_start_for(week_start)
_, iso_week = _iso_week_range(week_start)
target_path = f"WeeklyReview/{iso_week}.md"
async def context_gather() -> dict[str, Any]:
return await self._gather_context(week_start)
logger.info(
"weekly_review_triggered",
iso_week=iso_week,
user_id=self._user_id,
)
return await self._writer.run(
template=self.TEMPLATE,
task_type=self.TASK_TYPE,
context_gather=context_gather,
target_path=target_path,
idempotency_key=iso_week,
user_id=self._user_id,
autonomy_level=self._config.autonomy_level,
)
|