Worklog: Reconstructing Work from Evidence
- Team
- Solo
- My contribution
- Owner and principal engineer
- Outcome
- One deduplicated record now supports project timelines, reports, and evidence-backed portfolio claims.
- Status
- Production: Running on my home-lab hub
The Problem
I move between many repositories and a few computers. Some work lands on GitHub. Some commits stay local for a while. Tickets describe intent, pull requests describe integration, and git records what actually changed. None of those sources can tell the whole story alone.
The evidence existed, but it was scattered across repositories, local-only branches, pull requests, tickets, and several machines. Memory was not going to reconstruct it. Timesheets would only replace missing evidence with confident guesses. How could I answer the question, “What did I do this week?”, without actually keeping track of my time?
What I Built
A self-hosted Python service with four incremental harvesters, one SQLite store, a shared query core, and two interfaces: a CLI and a build-free web app. GitHub mirrors provide the durable baseline; SSH scans recover local-only work; commit SHAs keep the same history from counting twice across machines.
Tech Stack
- Python 3.13
- JavaScript
- SQL
- Bash
- FastAPI
- Uvicorn
- Vanilla JS with native ES modules
- SQLite with WAL
- bare Git mirrors
- TOML configuration
- GitHub REST API
- Plane REST API
- Git over SSH
- Proxmox / LXC
- systemd services and timers
- Cloudflare Tunnel
- pytest
- fixture-based acceptance oracle
- live multi-machine reconciliation gate
How It Works
Four harvesters collect GitHub repository mirrors, local git history over SSH, GitHub pull requests and issues, and Plane tickets. They feed one SQLite database in WAL mode: the portable artifact behind every query, report, and generated case study. Each harvest is incremental and idempotent, so a second run adds new evidence without duplicating the old record.
GitHub mirrors are the primary git source, so Worklog still functions when every development machine is powered off. SSH fills the gaps mirrors cannot see: unpushed branches, repositories that were never pushed, and which machine held a commit.
The same repository may exist on three machines. Counting each clone would turn ordinary redundancy into imaginary output.
Worklog deduplicates commits by SHA. A machine is provenance, not a multiplier. Repository identity comes from a normalized remote URL, with a root-commit fallback only when no remote exists. That distinction matters because several Loomwork-based sites share the same original root commit while remaining separate products.
Author identity is explicit too. The configuration defines which email addresses belong to me, keeps collaborators separate, and excludes upstream authors from forks. The totals come from declared rules rather than whatever a provider API happened to return.
The CLI and web application call the same Python query layer. There is no second implementation for the dashboard to slowly disagree with.
The shared core answers questions such as:
- which projects were active in a date range;
- what work overlapped;
- how a project’s history developed end to end;
- which commits and tickets mention a subject;
- what changed after a case study was published;
- which source records support a generated report.
The web interface adds timelines, project views, reports, and a case-study workflow. The CLI remains useful for automation and direct inspection.
A green test suite does not prove a historical reconstruction is correct. Worklog therefore has an acceptance oracle built from independently derived facts about my actual 2026 work history.
The hermetic gate runs against fixtures in CI. A live gate compares a real multi-machine harvest with the independently derived record. Adding a second clone of the same repository must not increase the totals. That test has caught real mistakes in deduplication, exclusions, and source precedence.
The current suite includes 512 tests. The important part is not the count. It is that the system tests both software behavior and the truth of the record it produces.
Worklog also generates project reports and case-study drafts. Before writing, it reconstructs a project from commits, tickets, pull requests, releases, and the current source tree. It records where evidence is incomplete and keeps revisions instead of overwriting the previous narrative.
That workflow produced a practical feedback loop: if a public claim cannot be traced to evidence, the claim gets narrowed or removed. The portfolio becomes another view over the engineering record rather than a separate marketing story.
Worklog runs on an always-on Proxmox container. Python harvesters run from systemd timers, the web application is published through an authenticated Cloudflare Tunnel, and the SQLite database is backed up as one file.
Secrets stay outside the repository in a root-owned environment file. The versioned configuration template contains machine names, author mappings, project mappings, and non-secret behavior. The public repository includes the provisioning scripts, service definitions, backup procedure, and deployment runbooks.
What Made It Hard
The hard part was not collecting more data. It was deciding when two records described the same work, preserving local-only history without double-counting clones, and proving the totals against an independently derived oracle. A second machine can add provenance, but it is not allowed to add imaginary output.
The Throughline
Latticeflow makes the development process deterministic. Worklog makes the result observable. One governs how work moves; the other preserves enough evidence to explain what happened afterward. Together, they turn the rest of this portfolio from a set of claims into an auditable engineering record.
Status
Worklog is running in production for one operator and is now public. It is intentionally not a turnkey multi-user product. The deployment assumes an always-on hub, SSH access to development machines, GitHub, and a self-hosted Plane instance.
The architecture, installation instructions, deployment runbooks, configuration template, tests, and MIT license are available in the public source repository.