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)
- Structure:
Daily > YYYY > Month > Week > Day. The existing protected "Daily" container stays the root — no rename, container sentinel untouched.
- 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.
- 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).
- 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).
- 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.
- 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.
- 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.
- 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).
- 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.
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)
Daily > YYYY > Month > Week > Day. The existing protected "Daily" container stays the root — no rename,containersentinel untouched.daily-indexkv beside thecontainersentinel, 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).claimMappingget-or-create cascade. Pure structure, never seeded content.seedEntryLinestays day-only at the three write-intent surfaces.protectsto all scaffold nodes (same four rules +canonicalTextper node: "2026" / "July" / "Week 29"). Non-negotiable —removeNodecascades, so an unprotected week delete takes its days with it./weekcommand in v1.moveManyNodesdays into their weeks, reorder ascending — onerunStructuralbatch,runStructuralSlicedover 500 ops, one Cmd+Z, toast on completion. No prompt (a declined prompt leaves a permanently half-structured container).Implementation map
src/plugins/daily/index.tsx—ensureContainer/ensureDaygrow the chain (container→year→month→week→day claims); sorted insertion helper replacinginsertChildAtStartwithin 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-freesrc/data/date-links.tsnext tolocalDateKey.worker/outline-ops.tsplanEnsureDailyis a full second implementation of placement and must grow the identical chain + sorted insertion;worker/mcp-tools.tsclaimDailyIdcascade per level; server-side protection guards extended to scaffold nodes. MCP tools unchanged externally. Cover inworker/outline-ops.test.ts(e2e can't reach the Worker).e2e/daily-notes.spec.tsfixtures assume the flat shape — rework expected. Unit-test the pure ISO week math and the migration planner.Non-issues (checked)
goToDate: same get-or-create cascade, no UX change.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.