Skip to content

Latest commit

 

History

History
424 lines (300 loc) · 14.1 KB

File metadata and controls

424 lines (300 loc) · 14.1 KB

Lockin Project Assessment Report

Date: January 2026 Version: 1.0.0 Status: Functional, Release Candidate


Executive Summary

Lockin is a macOS terminal-based focus timer with a persistent background engine. The project is functional and ready for public release with the understanding that it's macOS-only and has gaps in test coverage and CI infrastructure. The architecture is sound—using SQLite as a message bus between CLI and engine is a pragmatic choice that handles all edge cases well.

Strengths:

  • Clean architecture with clear separation of concerns
  • Robust state persistence (survives crashes, terminal closes)
  • Well-documented code and architecture
  • Polished terminal UI using Rich library

Weaknesses:

  • Limited test coverage (database only, no CLI/engine tests)
  • macOS-only (uses LaunchAgent and osascript)

1. Feature Completeness

Core Features — Complete

Feature Status Notes
Work sessions Start, quit, abandon tracking
Break sessions Short/long breaks, custom durations
Decision window 3-minute window to decide after session
Overtime/bonus time Configurable max overtime
Session persistence Survives terminal close, crashes
macOS notifications Uses osascript
Statistics Week/month/year views
Configuration 11 config options with validation
Session log View and delete recent sessions
Streak tracking Today's streak with 60-min gap rule

Interactive Controls — Complete

Context Controls
Running session q quit, d detach
Decision window q quit, b break, B custom break, c continue
Break session q quit, s switch short, l switch long, w start work

Configuration Options — All Implemented

  • short_break_minutes (default: 5)
  • long_break_minutes (default: 15)
  • long_break_every (default: 4)
  • work_default_minutes (default: 25)
  • min_work_minutes (default: 5)
  • min_break_minutes (default: 2)
  • work_decision_minutes (default: 3)
  • auto_attach (default: false)
  • work_overtime_enabled (default: true)
  • work_overtime_max_minutes (default: 60, 0=unlimited)
  • break_overtime_contributes (default: false)

2. Code Quality & Robustness

Architecture Quality: Good

The persistent engine + ephemeral CLI pattern is well-suited for this use case:

  • Engine runs as LaunchAgent, always available
  • CLI can start/stop without affecting timers
  • SQLite acts as both persistence and IPC

Component sizes (lines of code):

  • cli.py: 774 lines — Terminal UI, the largest module
  • engine.py: 353 lines — State machine
  • database.py: 342 lines — SQLite layer
  • __main__.py: 310 lines — CLI entry point
  • config.py: 135 lines — Configuration
  • Total: ~1,950 lines Python

Input Validation: Comprehensive

  • Duration validation (1-1440 minutes)
  • Config key validation against whitelist
  • Config value validation (type, range)
  • Session type validation
  • State corruption recovery (invalid states reset to idle)

Error Handling: Adequate

  • Database errors: Transaction rollback
  • Engine errors: 5-second backoff, continues running
  • Notifications: Silently fail (non-critical)
  • Invalid CLI args: User-friendly error messages

Potential Issues

  1. Race conditions: CLI can queue commands while engine processes others. Mostly harmless due to single-session constraint, but edge cases possible.

  2. Clock jumps: System sleep/wake or time changes could cause unexpected behavior. No explicit handling.

  3. Database locking: SQLite handles concurrency, but high-frequency polling (1 Hz from CLI + engine) could cause transient lock contention.


3. Documentation

User Documentation: Good

Document Status Quality
README.md Concise, covers all commands
CONTRIBUTING.md Clear dev setup, architecture overview
CLAUDE.md AI assistant context (unique to this project)
CHANGELOG.md Documents 1.0.0 features

Technical Documentation: Excellent

Document Status Quality
ARCHITECTURE.md Comprehensive, includes diagrams
Inline comments Docstrings on all public methods
Type hints Used throughout

Missing Documentation

  • User guide with screenshots
  • Troubleshooting guide (mentioned in ARCHITECTURE.md but doesn't exist)
  • Release notes / changelog entries

4. Testing

Current Coverage: Minimal

Unit Tests (test_database.py): 5 tests

  • Database initialization
  • Session logging
  • Streak calculation
  • Today's stats
  • Config management

Integration Tests (final_verification.py): 5 tests

  • Duration validation
  • State validation/corruption recovery
  • Config validation
  • Date parsing error handling
  • Complete workflow (start → quit → start new)

Test Gaps

Component Coverage Priority
Engine state machine None High
CLI rendering None Medium
Command processing Partial High
Break switching None Medium
Overtime logic None High
Midnight rollover None Low

Test Infrastructure

  • Uses pytest
  • Temporary databases for isolation
  • No mocking (tests use real DB operations)
  • GitHub Actions CI (runs on Python 3.9 and 3.12, macOS)
  • Ruff for linting and formatting

5. Installation & Deployment

Installation Process: Good

The install.sh script:

  1. Detects uv or falls back to pip
  2. Creates isolated venv in ~/.lockin/
  3. Installs as editable package
  4. Sets up LaunchAgent
  5. Adds to PATH

Issues:

  • Requires manual source ~/.zshrc after install
  • No update mechanism
  • No way to install specific version
  • macOS security warnings (see below)
  • Not on PyPI or Homebrew (shell script installation only)

Uninstallation: Good

The uninstall.sh script:

  • Stops LaunchAgent
  • Optionally preserves data
  • Reminds about PATH cleanup

Platform Support: macOS Only

Hard dependencies on:

  • launchctl / LaunchAgent
  • osascript for notifications
  • Paths like ~/Library/LaunchAgents

6. Known Issues & Limitations

Functional Limitations

  1. Single session only: By design, but could frustrate users wanting parallel tracking
  2. No data export: Stats are view-only, no CSV/JSON export
  3. No undo: Deleted sessions cannot be recovered
  4. No pause: Sessions can only be quit, not paused
  5. 60-minute streak gap: Hardcoded, not configurable

Technical Limitations

  1. macOS only: Architecture is portable, but system integrations are not
  2. No sync: Data is local only
  3. No backup: User must manually backup ~/.lockin/lockin.db
  4. Terminal required: No GUI, no menu bar app

UI Limitations

  1. No themes: Fixed color scheme
  2. No resize handling: Progress bar width is fixed at 40 chars
  3. No accessibility: No screen reader support

Security & Installation Friction

  1. macOS Gatekeeper warnings: Downloaded scripts are quarantined. Users must run xattr -r -d com.apple.quarantine install.sh or right-click → Open to bypass.

  2. Corporate endpoint protection: Security software (CrowdStrike, Jamf, etc.) may flag the LaunchAgent or Python process as suspicious. This is difficult to address without code signing.

  3. No code signing: The app is unsigned, which triggers macOS warnings and corporate security tools. Signing requires an Apple Developer account ($99/year) and adds build complexity.

Workaround documented: Users in restricted environments can skip the LaunchAgent and run lockin-engine manually in a terminal tab.


7. Technical Debt

Low Priority

  • Some duplicate code between CLI and engine for break recommendation
  • Magic numbers (60-minute streak gap, 40-char progress bar)

Medium Priority

  • No engine tests
  • No CLI tests
  • Hardcoded en-US strings (no i18n)

High Priority

  • No automated security scanning

8. AI-Assisted Development

This project is entirely AI-generated and managed (with human direction). This creates unique considerations for long-term maintainability.

Current State

What works well:

  • CLAUDE.md provides project context and development commands
  • ARCHITECTURE.md documents design decisions and patterns
  • Consistent commit message format ([component] description)
  • Clear module separation makes targeted changes easier
  • Tests verify core functionality works

What's missing:

Gap Risk Solution
No release process documentation AI won't know how to version/tag releases Document in CLAUDE.md
No CI operation guide AI won't know how to interpret/fix CI failures Document expected CI behavior
No PyPI publishing guide AI won't know how to publish new versions Document publishing steps
CHANGELOG not maintained AI has no record of what changed when Keep CHANGELOG updated
No "how to debug" guide AI may struggle with production issues Document common debugging steps

The Context Loss Problem

When a new AI session starts, context is empty. The AI must reconstruct understanding from:

  1. Source code
  2. Documentation (README, CLAUDE.md, ARCHITECTURE.md)
  3. Git history
  4. Test output

Current gaps that cause friction:

  • No documented release/versioning procedure
  • No guide for "how to ship a fix to PyPI" (once published)
  • No incident response guide ("user reports X, here's how to debug")
  • Test coverage is low, so AI can't verify changes don't break things

Recommendations for AI Maintainability

  1. Expand CLAUDE.md with operational procedures:

    • How to create a release (version bump, tag, publish)
    • How to interpret and fix CI failures
    • How to debug common issues
  2. Keep CHANGELOG.md updated — serves as institutional memory

  3. Increase test coverage — gives AI confidence that changes work

  4. Document "recipes" for common tasks:

    • Adding a new CLI command
    • Adding a new config option
    • Debugging engine state issues
  5. Use descriptive commit messages — AI can learn from git history


9. Prioritized Roadmap

Phase 1: Release Readiness (High Priority)

Tasks to prepare for public release and community contributions.

Task Effort Impact
Add CI with GitHub Actions ✅ Done High
Create first versioned release (v1.0.0) ✅ Done High
Add engine unit tests 1-2 days High
Add issue templates (bug report, feature request) ✅ Done Medium
Populate CHANGELOG.md ✅ Done Medium
Document release process in CLAUDE.md ✅ Done Medium
Document CI expectations in CLAUDE.md ✅ Done Medium

Phase 2: Distribution (Medium-High Priority)

Make the tool easier to install for a wider audience.

Task Effort Impact
Add lockin setup command (replace install.sh logic) 1 day High
Publish to PyPI 0.5 day High
Add lockin setup --uninstall 0.5 day Medium

Why lockin setup? The current install.sh works but isn't compatible with standard Python distribution (pip/PyPI). Refactoring LaunchAgent installation into a CLI command enables pip install lockin && lockin setup — cleaner and more portable.

PyPI benefits:

  • pip install lockin is familiar to Python users
  • Enables pipx install lockin for isolated installs
  • Automatic dependency resolution
  • Version management via pip

Phase 3: Polish (Medium Priority)

Quality-of-life improvements.

Task Effort Impact
Export stats to CSV 0.5 day Medium
Configurable streak gap 0.5 day Low
Responsive progress bar width 0.5 day Low
Add lockin pause command 1 day Medium

Phase 4: Platform Expansion (Lower Priority)

Broaden user base.

Task Effort Impact
Linux support (systemd + notify-send) 2-3 days High
Windows support (Task Scheduler) 2-3 days Medium
Docker/container support 1 day Low

Phase 5: Additional Distribution & Features (Future)

Nice-to-have features and broader distribution.

Task Effort Impact
Homebrew tap 1 day Medium
Data backup/restore commands 1 day Medium
Import from other timers 1-2 days Low
Custom notification sounds 0.5 day Low
Pomodoro preset mode 1 day Medium
Menu bar status (macOS) 2-3 days Medium

Homebrew tap: Once PyPI distribution is working, a Homebrew tap (brew install tomhilder/tap/lockin) provides a more native macOS installation experience. Lower priority than PyPI since it's macOS-only and Homebrew users can still use pip.


10. Summary Metrics

Metric Value
Lines of Python ~1,950
Lines of docs ~1,500
Unit tests 5
Integration tests 5
Config options 11
CLI commands 8
Supported platforms 1 (macOS)
Human-written code 0%

11. Recommendations for Future Development

  1. Set up GitHub Actions first — Done. CI runs pytest and ruff on push/PR.

  2. Tag a release — Done. v1.0.0 released.

  3. Write engine tests — The state machine is the heart of the app. Tests catch regressions and document expected behavior for contributors.

  4. Document operational procedures — Every new system (CI, PyPI, versioning) needs a corresponding update to CLAUDE.md so future AI sessions know how to operate it.

  5. Keep CHANGELOG.md current — This is institutional memory. When context is lost, the changelog tells the story of what changed and why.

  6. Don't over-engineer — The current architecture handles its scope well. Resist adding complexity unless there's clear user demand.

  7. Linux support is high-value — Many terminal-focused developers use Linux. The architecture is portable; only LaunchAgent and osascript need platform alternatives.


This report assesses the Lockin project as of January 2026. It is intended to guide development prioritization and inform potential contributors (human or AI) about the project's current state.