Skip to content

feat(daily): calendar hierarchy — Daily > Year > Month > Week > Day #271

Description

@cameronapak

Origin

Alpha-user request: weekly ("sprint") grouping of daily notes, per Workflowy's calendar structure. Design fully grilled and settled 2026-07-16; this ticket is the record. Do not start without reading the Design decisions — they are final unless Cam reopens them.

Empirical reference: Workflowy's Google Calendar integration auto-builds Month > Week N > Day, weeks atomic (the Jun 28–Jul 4 straddle week lives whole under July), days lazy (no content = no node), order chronological ascending.

Design decisions (settled)

  1. Structure: Daily > YYYY > Month > Week > Day. The existing protected "Daily" container stays the root — no rename, container sentinel untouched.
  2. Week spec: ISO 8601. Monday start, ISO week numbers. Weeks are atomic; a week's Thursday decides which month AND year own it (ISO-consistent, equals majority-of-days). No week-start setting in v1 — changing week identity later is a migration, so keys are spec'd from day one.
  3. Identity: scaffold keys join the existing daily-index kv beside the container sentinel, as bare, shape-disambiguated keys: 2026 (year), 2026-07 (month), 2026-W29 (week), 2026-07-16 (day). No prefixes — the four shapes are mutually unambiguous, and ADR 0038's "token interior IS the index key" rule then extends to every level for free (see the period-token follow-up issue, which depends on this key shape).
  4. Ordering: chronological ascending at every level (years, months, weeks, days), replacing newest-first head-insertion inside the Daily subtree. Sorted insertion compares date keys via the index reverse map. This retires the known "out-of-order past day lands on top" caveat (src/plugins/daily/index.tsx:132-139).
  5. Lazy scaffold, seed-free (ADR 0041): year/month/week nodes are minted only when the first day in them is created, via the same claimMapping get-or-create cascade. Pure structure, never seeded content. seedEntryLine stays day-only at the three write-intent surfaces.
  6. Protection: extend the daily plugin's protects to all scaffold nodes (same four rules + canonicalText per node: "2026" / "July" / "Week 29"). Non-negotiable — removeNode cascades, so an unprotected week delete takes its days with it.
  7. Chrome: week node gets a Seam-F badge (date range + "This week"/"Last week" relative) and a Seam-J search alias so Cmd+K jumps to the current week. No new routes, header buttons, or /week command in v1.
  8. Migration: one-time, client-side, automatic on first daily-note touch after ship. Derivable from the daily-index (every day key→nodeId is known): build scaffold, moveManyNodes days into their weeks, reorder ascending — one runStructural batch, runStructuralSliced over 500 ops, one Cmd+Z, toast on completion. No prompt (a declined prompt leaves a permanently half-structured container).
  9. Friend's Shift+Tab ask is free: with real nesting, outdenting a bullet under a day makes it a child of the week — no new code (moves under protected nodes are already legal; Send to Today does it).

Implementation map

  • Client: src/plugins/daily/index.tsx — ensureContainer/ensureDay grow the chain (container→year→month→week→day claims); sorted insertion helper replacing insertChildAtStart within the Daily subtree; protects + badge + Seam-J extensions. src/plugins/daily/daily-index.ts — key helpers + reverse maps for scaffold keys. ISO week math (week number, week-year, Thursday rule) belongs in dependency-free src/data/date-links.ts next to localDateKey.
  • Worker (the lockstep cost — budget for it): worker/outline-ops.ts planEnsureDaily is a full second implementation of placement and must grow the identical chain + sorted insertion; worker/mcp-tools.ts claimDailyId cascade per level; server-side protection guards extended to scaffold nodes. MCP tools unchanged externally. Cover in worker/outline-ops.test.ts (e2e can't reach the Worker).
  • Tests: e2e/daily-notes.spec.ts fixtures assume the flat shape — rework expected. Unit-test the pure ISO week math and the migration planner.
  • ADR: write a new ADR (hierarchy + ordering flip + ISO choice + atomic-week Thursday rule all clear the bar), amending ADR 0041's structure description.

Non-issues (checked)

  • Free-tier node cap: ~65 scaffold nodes/year — negligible.
  • Date-chip click / goToDate: same get-or-create cascade, no UX change.
  • Quick-add Seam L / Send to Today / Mirror to Today: land under the day as before; day placement is the only thing that moved.

Follow-up (separate issue, blocked by this one)

Period tokens [[2026]] / [[2026-07]] / [[2026-W29]] — Cam wants these; designed and filed as a dependent issue. This ticket only has to deliver the bare key shape in decision 3.

Out of scope (v1)

Week-start display setting; "create my whole year" templates; custom recurring periods.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions