Daily & Weekly Objectives
The Objectives system provides structured daily and weekly planning with automatic carry-forward, progress tracking, and Telegram integration. Unlike long-term goals, objectives are short-term commitments - what you're actually trying to accomplish today and this week.
Overview
Design Philosophy: Objectives are intentionally constrained. Max 5 daily, max 3 weekly. This forces prioritization and prevents overwhelm.
Key features: - Daily Objectives - What you're trying to accomplish today (max 5) - Weekly Objectives - What you're trying to accomplish this week (max 3) - Carry-forward - Incomplete daily objectives surface the next morning - Daily-Weekly Linking - Daily objectives can "touch" weekly goals for progress tracking - Telegram Integration - Morning, midday, and evening conversational prompts via bot - Draft Mode - Objectives start as draft until confirmed - Analytics - Completion-rate, day-of-week, completion-time, deferred-pattern, and sleep-correlation analysis
System Architecture
Objectives Data Flow
+-----------------------------------------------------------------------------+
| USER INTERFACES |
| /day (CLI) /week-plan (CLI) Telegram Bot Web UI |
+-----------------------------------------------------------------------------+
|
v
+-----------------------------------------------------------------------------+
| API LAYER |
| GET /api/v1/objectives/today - Daily objectives with stats |
| GET /api/v1/objectives/week - Weekly objectives with daily summary |
| POST /api/v1/objectives/today - Create daily objective |
| POST /api/v1/objectives/week - Create weekly objective |
| PATCH /api/v1/objectives/{id}/complete - Mark complete |
| PATCH /api/v1/objectives/{id}/defer - Mark deferred |
| PATCH /api/v1/objectives/week/{id} - Update weekly status/priority |
| GET /api/v1/objectives/carry-forward - Yesterday's incomplete |
| GET /api/v1/objectives/history - Date-range history |
+-----------------------------------------------------------------------------+
|
v
+-----------------------------------------------------------------------------+
| STORAGE LAYER |
| data/objectives/daily/YYYY-MM-DD.json - Daily objectives |
| data/objectives/weekly/YYYY-Www.json - Weekly objectives |
| data/objectives/conversations/*.json - Telegram state |
+-----------------------------------------------------------------------------+
CLI Commands
Daily Objectives (/day)
| Command | Description |
|---|---|
/day |
Show today's objectives, offer to add/edit |
/day add <text> |
Add objective (medium priority) |
/day done [id] |
Mark complete |
/day drop [id] |
Mark deferred |
/day note <id> <text> |
Add note (e.g., "blocked on X") |
/day rm <id> |
Delete |
/day reopen <id> |
Reopen completed/deferred |
Weekly Objectives (/week-plan)
| Command | Description |
|---|---|
/week-plan |
Show this week's objectives |
/week-plan add <text> |
Add weekly objective (max 3) |
/week-plan done [id] |
Mark completed |
/week-plan drop [id] |
Mark dropped |
Data Models
Daily Objective
{
"id": "obj-a1b2c3d4",
"text": "Review quarterly metrics",
"original_text": "review quarterly metrics",
"why": null,
"priority": "high",
"status": "pending",
"notes": "Blocked on finance team",
"weekly_objective_id": "wobj-x1y2z3",
"linked_task_key": null,
"source": "cli",
"created_at": "2026-01-09T08:00:00",
"updated_at": "2026-01-09T14:30:00",
"completed_at": null,
"outcome_note": null
}
| Field | Type | Description |
|---|---|---|
id |
string | Unique identifier (obj-{hex8}) |
text |
string | Cleaned objective text (3-200 chars) |
original_text |
string | Preserved user input for analytics |
why |
string | Optional reason/motivation |
priority |
enum | high, medium, low |
status |
enum | pending, in_progress, completed, deferred |
notes |
string | Mid-day context (e.g., blockers) |
weekly_objective_id |
string | Link to weekly objective |
linked_task_key |
string | Soft link to Precedent task |
source |
enum | telegram, web, cli (default telegram) |
created_at |
datetime | When created |
updated_at |
datetime | Last modification |
completed_at |
datetime | When marked complete |
outcome_note |
string | How it went (added on completion) |
Weekly Objective
{
"id": "wobj-x1y2z3a4",
"text": "Ship dashboard feature",
"priority": "high",
"status": "in_progress",
"precedent_project": "growth",
"daily_touches": ["2026-01-06", "2026-01-07", "2026-01-08"],
"created_at": "2026-01-06T09:00:00"
}
| Field | Type | Description |
|---|---|---|
id |
string | Unique identifier (wobj-{hex8}) |
text |
string | Objective text (3-200 chars) |
priority |
enum | high, medium, low |
status |
enum | not_started, in_progress, completed, dropped |
precedent_project |
string | Optional Precedent project path |
daily_touches |
array | Dates this objective was worked on |
created_at |
datetime | When created |
Container Files
Daily Container (data/objectives/daily/YYYY-MM-DD.json):
{
"schema_version": 1,
"date": "2026-01-09",
"objectives": [...],
"carried_from": "2026-01-08",
"draft": false,
"confirmed_at": "2026-01-09T08:30:00"
}
Weekly Container (data/objectives/weekly/YYYY-Www.json):
{
"schema_version": 1,
"week": "2026-W02",
"start_date": "2026-01-06",
"end_date": "2026-01-12",
"objectives": [...]
}
Display Format
Daily View
π Today's Objectives (2/3)
1. [β
] Review quarterly metrics (high) - obj-a1b2
β Done at 2:30pm
2. [β³] Finish API endpoint (medium) - obj-c3d4
β Working on auth validation
3. [β¬] Workout (low) - obj-e5f6
βββββββββββββββββββββββββ
Yesterday's incomplete (carry forward?):
- Review PRs - obj-x1y2
Status indicators:
- [β
] completed
- [β³] in_progress
- [β¬] pending
- [β©οΈ] deferred
Weekly View
π
Week 2026-W02 (Jan 6 - Jan 12)
1. [β³] Ship dashboard feature (high) - wobj-x1y2
Touched: Mon, Wed, Fri (3 days)
2. [β¬] Improve test coverage (medium) - wobj-z3a4
Not touched yet
3. [β
] Complete code review (medium) - wobj-b5c6
Touched: Mon, Tue (2 days)
βββββββββββββββββββββββββ
Last week's incomplete:
- Document API endpoints - wobj-d7e8
Constraints
| Constraint | Value | Rationale |
|---|---|---|
| Max daily objectives | 5 | Forces prioritization |
| Max weekly objectives | 3 | Keeps focus |
| Text length | 3-200 chars | Brief but meaningful |
| Carry-forward lookback | 7 days | Handles weekends/holidays |
API Endpoints
Daily Objectives
| Method | Endpoint | Description |
|---|---|---|
| GET | /api/v1/objectives/today?date=YYYY-MM-DD |
Get today's objectives with stats |
| POST | /api/v1/objectives/today?date=YYYY-MM-DD |
Create single objective |
| POST | /api/v1/objectives/today/batch?date=YYYY-MM-DD |
Create multiple (transactional, all-or-nothing if >5) |
| POST | /api/v1/objectives/today/confirm?date=YYYY-MM-DD |
Confirm draft objectives |
| GET | /api/v1/objectives/carry-forward |
Get yesterday's incomplete |
The ?date= parameter is optional on all daily endpoints; defaults to today.
Individual Operations
| Method | Endpoint | Description |
|---|---|---|
| PATCH | /api/v1/objectives/{id}?date=YYYY-MM-DD |
Update status/priority/notes (text not updatable) |
| PATCH | /api/v1/objectives/{id}/complete?note=...&date=YYYY-MM-DD |
Mark complete with optional outcome note |
| PATCH | /api/v1/objectives/{id}/defer?date=YYYY-MM-DD |
Mark deferred |
| PATCH | /api/v1/objectives/{id}/reopen?date=YYYY-MM-DD |
Reopen to in_progress |
| DELETE | /api/v1/objectives/{id}?date=YYYY-MM-DD |
Delete objective (204 No Content) |
Weekly Objectives
| Method | Endpoint | Description |
|---|---|---|
| GET | /api/v1/objectives/week?week=YYYY-Www |
Get weekly objectives with daily summary |
| POST | /api/v1/objectives/week?week=YYYY-Www |
Create weekly objective |
| PATCH | /api/v1/objectives/week/{id}?week=YYYY-Www |
Update weekly objective status/priority |
The ?week= parameter is optional; defaults to current ISO week. The PATCH body accepts status and priority only (text is not updatable). Both POST and PATCH invalidate the calendar-aggregate cache so downstream summaries reflect the change.
History
| Method | Endpoint | Description |
|---|---|---|
| GET | /api/v1/objectives/history?from=YYYY-MM-DD&to=YYYY-MM-DD |
Get objectives for date range (both params required) |
Daily-Weekly Linking
When creating a daily objective, it can be linked to a weekly objective:
- User creates daily objective: "Work on dashboard charts"
- Claude asks: "Does this relate to any weekly objectives?"
- User confirms link to "Ship dashboard feature"
- Daily objective gets
weekly_objective_idset - When daily is completed, weekly gets a "touch" for that date
This enables: - Progress tracking toward weekly goals - Visibility into how days contribute to week - Analytics on weekly objective completion patterns
Telegram Integration
The objectives system integrates with Telegram via proactive messages. A single
proactive builder, build_objectives_prompt in scripts/proactive/builders.py,
is registered as the objectives message source (category reflection,
priority=0.9, max_per_week=21, min_hours_between=4). It selects one of
three prompts based on the current hour in America/Los_Angeles β there is
no fixed 7am/8pm cron; the scheduler ticks and the builder gates on a time
window plus state, returning None when no prompt is appropriate.
| Prompt | Window (PT) | Condition | Builder |
|---|---|---|---|
| Morning | 6 <= hour < 11 |
Always | build_morning_prompt() |
| Midday | 11 <= hour < 18 |
Objectives exist AND none completed yet | build_midday_prompt() |
| Evening | 18 <= hour < 22 |
Always | build_evening_prompt() |
Note: The midday window only fires when the day already has objectives and not a single one is marked
completedβ a gentle "still working on these?" nudge that stays silent on days with progress or no plan.
Morning Prompt
Good morning! What are your objectives for today?
Yesterday's incomplete:
- Review PRs
- Call insurance
Reply with today's objectives (one per line) or "carry" to bring forward yesterday's.
Midday Progress Check
Mid-day check: still working through today's objectives?
- β¬ Finish API endpoint
- β¬ Workout
Any progress? (e.g., "done 1", "drop 2", or a quick note)
Evening Review
π Daily Review
Completed: 2/4
- β
Review quarterly metrics
- β
Team standup
Still open:
- β¬ Finish API endpoint
- β¬ Workout
Quick update? (e.g., "done 3", "drop 4", or notes)
Note: The morning/midday/evening example payloads above are illustrative. The real text is generated by the
build_*_promptfunctions inscripts/objectives/prompts.py, which inject live carry-forward candidates, weekly context, and current status.
Conversation State
Telegram flow state is persisted per chat in a ConversationState model
(scripts/objectives/models.py):
| Field | Values | Purpose |
|---|---|---|
state |
idle, awaiting_input, awaiting_confirm |
Where the conversation is in the extractβconfirm flow |
last_prompt_type |
morning, midday, evening, null |
Which proactive prompt opened the current exchange |
pending_objectives |
list | Extracted objectives awaiting confirmation |
chat_id |
string | Telegram chat the conversation belongs to |
The state field drives the bot's reply handling; last_prompt_type records
which of the three prompts (including midday) started the conversation so the
response handler can tailor its behavior.
File Structure
scripts/objectives/
βββ __init__.py # Public exports
βββ models.py # Pydantic models (Objective, DailyObjectives, etc.)
βββ storage.py # Data layer with atomic writes/file locking
βββ extractor.py # Extract objectives from natural language
βββ prompts.py # Morning/midday/evening + confirmation prompt builders
βββ analytics.py # Completion patterns, sleep correlation, insights
βββ telegram.py # Telegram bot integration
api/src/
βββ routers/objectives.py # API endpoints
βββ services/objectives.py # Business logic
βββ schemas/objectives.py # Request/response schemas
web/src/components/objectives/
βββ ObjectiveItem.tsx # Single objective row
βββ ObjectivesCard.tsx # Daily objectives card
βββ WeeklyPlanCard.tsx # Weekly objectives card
data/objectives/
βββ daily/YYYY-MM-DD.json # Daily objectives per day
βββ weekly/YYYY-Www.json # Weekly objectives per ISO week
βββ conversations/*.json # Telegram conversation state
Storage Layer
The storage layer provides:
- Atomic writes - Temp file + rename pattern prevents corruption
- File locking - Concurrent access protection (3 retries, 100ms delay)
- Graceful degradation - Missing files return empty containers
from scripts.objectives import (
get_daily, add_objective, mark_complete,
get_weekly, add_weekly_objective,
MaxObjectivesError
)
# Daily operations
daily = get_daily() # Today's objectives
obj = add_objective("Review PRs", priority="high")
mark_complete(obj.id, note="All approved")
# Weekly operations
weekly = get_weekly() # This week
wobj = add_weekly_objective("Ship dashboard feature")
Analytics
scripts/objectives/analytics.py derives patterns from the stored daily
objectives (via get_daily_range) and, for one function, the Garmin sleep
files. All functions take a days lookback window and are exported from the
package. None of them write state β they are pure read-side analysis.
| Function | Window default | What it computes |
|---|---|---|
get_completion_rate(days=7) |
7 | Rolling fraction of objectives marked completed (0.0β1.0) |
get_deferred_patterns(days=30) |
30 | Recurring deferred items grouped by text similarity (SequenceMatcher > 0.6), top 10 by count |
get_day_of_week_stats(days=30) |
30 | Completion rate per weekday (None for days with no data) |
get_completion_time_distribution(days=30) |
30 | Counts of completions by morning / afternoon / evening (bucketed from completed_at hour) |
correlate_with_sleep(days=30) |
30 | Completion rate on low-sleep (<6h) vs. normal days, and the difference |
generate_insights(days=30) |
30 | Natural-language insight strings synthesized from the above |
The sleep correlation reads data/garmin/YYYY-MM-DD.json for each day in the
window and pulls sleep.duration_hours; days with no Garmin file are skipped.
generate_insights thresholds the raw stats (e.g. only flags a deferred item
seen 3+ times, a weekday gap > 0.20, or a sleep-completion gap > 0.15) so it
emits only signal, not noise. See Garmin for the source data
shape.
from scripts.objectives import correlate_with_sleep, generate_insights
corr = correlate_with_sleep(days=30)
# {'low_sleep_days_count': N, 'normal_sleep_days_count': N,
# 'low_sleep_completion_rate': 0.42, 'normal_completion_rate': 0.71,
# 'difference': 0.29} # illustrative values
for line in generate_insights(days=30):
print(line)
Web UI
The web dashboard renders objectives through three React components in
web/src/components/objectives/:
| Component | Role |
|---|---|
ObjectiveItem.tsx |
A single objective row (status icon, text, priority) |
ObjectivesCard.tsx |
Daily card: lists today's objectives + completion stats, with complete/refresh actions |
WeeklyPlanCard.tsx |
Weekly card: lists weekly objectives with per-objective daily_touches counts |
The cards consume the REST API via React Query hooks (e.g.
useTodayObjectives, useCompleteObjective). The daily card surfaces the
stats block returned by GET /api/v1/objectives/today (completed/total/
percentage); the weekly card shows the length of each objective's
daily_touches array as an N days touched badge. Mutations (mark complete,
etc.) hit the corresponding PATCH endpoints and invalidate the query so the
view refreshes. Source field for objectives created here is web.
Best Practices
Daily Objectives
- Keep them actionable - "Review PRs" not "Think about code"
- One day's worth - If it spans multiple days, make it weekly
- Use notes for context - "Blocked on X" helps tomorrow-you
- Defer intentionally - Don't delete things you'll do later
Weekly Objectives
- Broad enough to span days - "Ship dashboard feature" not "Write function X"
- Max 3 keeps focus - If you need more, some aren't weekly
- Review on Monday - Set the week's direction early
- Link daily to weekly - Builds progress visibility
Carry-Forward
- Review each morning - Don't auto-carry everything
- Drop stale items - If it's been deferred 3+ days, reconsider
- Convert to weekly - Persistent dailies might be weekly objectives
Known Limitations
- No recurring objectives - Each day/week starts fresh
- Single user - No collaboration or delegation features
- No time estimates - Objectives don't have duration
- Limited history search - History endpoint is date-range only
- No mobile app - Telegram or web only for now
Improvement Opportunities
- Objective Templates - Pre-defined objectives for common patterns
- Time Blocking - Link objectives to calendar slots
- Energy Matching - Suggest high-priority for high-energy times
- Completion Streaks - Gamification for consistency
- Weekly Reviews - Automated end-of-week summaries
- Goal Integration - Link objectives to long-term goals (not just weekly)
File Locations
| Path | Purpose |
|---|---|
scripts/objectives/models.py |
Pydantic models (Objective, WeeklyObjective, containers, ConversationState) |
scripts/objectives/storage.py |
Atomic-write/file-lock data layer; MAX_DAILY_OBJECTIVES=5, MAX_WEEKLY_OBJECTIVES=3 |
scripts/objectives/prompts.py |
Morning/midday/evening + confirmation prompt builders |
scripts/objectives/analytics.py |
Completion patterns, sleep correlation, insights |
scripts/objectives/telegram.py |
Telegram conversation handling |
scripts/proactive/builders.py |
build_objectives_prompt β time-gated proactive prompt selector |
api/src/routers/objectives.py |
REST endpoints |
web/src/components/objectives/ |
ObjectiveItem / ObjectivesCard / WeeklyPlanCard |
.claude/commands/day.md, .claude/commands/week-plan.md |
CLI command definitions |
data/objectives/{daily,weekly,conversations}/ |
Persistent state |
Where to go next
- Goals β long-term goals, distinct from short-term objectives
- Garmin β the sleep data backing
correlate_with_sleep - Precedent β the task system objectives soft-link to via
linked_task_key - Proactive Messages β how the morning/midday/evening prompts are scheduled and delivered
- Telegram β the conversational interface for the objectives flow