Snapshot
Preserve project context continuously so new and returning developers do not have to reconstruct repository history manually.
Generate useful explanations without asking an LLM to rediscover deterministic facts that Git already knows.
A published Python package with working checkpoints, catch-ups, PR summaries and onboarding context, plus a 29.9% observed successful-run runtime reduction after an optimization period.
Checkpoint came from having to reconstruct old project context before I could even begin contributing.
01.1The internship problem
At the beginning of my internship I was assigned older projects that had not been maintained particularly well. Before I could contribute, I first had to reconstruct what the project was, how it worked, why it looked the way it did and what had changed before I arrived.
The frustrating part was that Git history existed. The information was technically present, but not in a form that helped a new or returning developer understand the project quickly.
ee814c033cf8bc277188eb9d8436ef1521b24153c13894c30af60d81b26f83cf15c0aeMaster Context
Sprout is a small, read-only plant-watering reminder API. It loads plant records and reminder settings from local files, calculates which plants are due, and exposes the results over HTTP. It does not send notifications or update watering dates. Its checked-in plant data is a sample, not a production database.
The repository also serves a second purpose: it is a public demo of Checkpoint running in GitHub Actions. Checkpoint produces commit and PR summaries in checkpoints/, returning-author briefings in catchups/, and this onboarding guide in MASTER_CONTEXT.md. The README says the October 2026 project history is fictional; the generated documents come from live Checkpoint runs. Treat the service and its history as a demo, and use the current README and upgrade notes when operating it.
01.2Three different context moments
I started thinking about developer context as three related but different moments.
Those moments need different levels of detail, but they can all be built from the same preserved history if context is captured continuously.
ee814c033cf8bc277188eb9d8436ef1521b24153c13894c30af60d81b26f83cf15c0aeWhile You Were Gone — Since October 02, 2026
Since October 2, Sprout’s reminder API and configuration changed, and existing plant data now needs a one-time migration before reminders can load it. You also have a lightweight health endpoint, stronger reminder and migration tests, and updated docs that frame the repository as a Checkpoint demo. The latest changes mostly update documentation and allow generated Checkpoint files to be tracked in Git; they do not change application behavior.
Master Context
Sprout is a small, read-only plant-watering reminder API. It loads plant records and reminder settings from local files, calculates which plants are due, and exposes the results over HTTP. It does not send notifications or update watering dates. Its checked-in plant data is a sample, not a production database.
01.3The success condition
The goal was not to create another documentation dashboard. I wanted context to live close to the repository and be updated as work happened.
A developer returning after time away should be able to understand the important changes without manually reading every file and every commit. A new developer should be able to get an architecture and decision overview without depending on someone who still remembers the project.
Checkpoint became better as I removed AI and framework complexity from the parts Git already solved deterministically.
02.1The first version was heavier than the problem
The first architecture used DSPy and Gemini, LangGraph and ChromaDB. At that stage I was still exploring both the problem and the frameworks, so a more agentic/vector-heavy architecture seemed reasonable.
Once I understood the workflow better, it felt overbuilt. I did not need a vector database to rediscover which commit changed a file. I did not need a graph framework to determine a commit range.
That realization became the most important architecture change in the project.
feat: remove DSPy, replace with direct LiteLLM calls
Gagan N Bangaragiri committed on 2026-03-06 · 49dc5e5
-import dspy+import litellm-class UnifiedCheckpointSignature(dspy.Signature): feat: remove ChromaDB dependency
Gagan N Bangaragiri committed on 2026-03-06 · 315073c
-.chroma_db/ - vector_db_path: str = Field(default=".chroma_db", description="ChromaDB storage path") - vector_db: bool = Field(default=True, description="Enable ChromaDB semantic search") feat: remove LangGraph and questionary to reduce install size
Gagan N Bangaragiri committed on 2026-03-06 · 8af0051
-from langgraph.graph import StateGraph, END -import questionary- provider = questionary.select( 02.2Let Git do deterministic work
Git already knows who changed something, when they changed it, which commits are relevant and what the exact diff is. Checkpoint therefore lets Git handle those facts and sends only the context that still needs interpretation to the model.
That makes the model input smaller and the behaviour easier to reason about. The model explains change; it does not reconstruct version control.
The best architecture was not the one with the most AI in it.
02.3Why Markdown became the memory layer
The generated context is stored as Markdown in the repository. That was deliberate. A developer can open it without another tool, Git can version it, a pull request can review it and a future model can consume the same file as context.
That gives me one source of project context that is readable by both people and models instead of separate human docs and machine memory.
## Commit `33cf8bc` — 2026-10-08 ## ContextThe commit adds a health endpoint that can respond without reading plant storage. Previously, `Handler.do_GET` only accepted `/api/reminders`; other paths returned 404. The new route exits before reminder handling. ## Changes- `sprout/server.py` — `Handler.do_GET` now recognizes `/health`, sends HTTP 204, ends the response, and returns. The route does not call `due_plants`, `load_plants`, or `load_settings`. ## Impact- Confirmed: `GET /health` returns 204 with no response body and bypasses the reminder route’s storage-related work.Commit 33cf8bc — 2026-10-08
Context
The commit adds a health endpoint that can respond without reading plant storage. Previously, Handler.do_GET only accepted /api/reminders; other paths returned 404. The new route exits before reminder handling.
Changes
sprout/server.py—Handler.do_GETnow recognizes/health, sends HTTP 204, ends the response, and returns. The route does not calldue_plants,load_plants, orload_settings.
02.4Why GitHub Actions became the default trigger
The project initially supported local hooks, but GitHub Actions became the natural primary path because the development events already happen there. A push, PR or merge is the moment context should be captured.
That also removes a behavioural dependency on the developer remembering to run a command. The workflow can derive the relevant commit range, generate the context artifact and commit the result back into the repository.
The difficult edge is making sure the automation does not summarize its own generated files or bot-authored commits and create a feedback loop.
02.5Keep model choice configurable
The later architecture uses LiteLLM so the model layer is not hard-coded to one provider. Mistral was the model I used in practice, but the case study is not a claim that every provider was tested equally.
The useful abstraction is that Git/context preparation is stable while the interpretation model can be changed through configuration.
The system turns normal Git events into a small set of durable Markdown artifacts: checkpoints, catch-ups, PR summaries and master context.
03.1Commit checkpoints
On a push, the workflow derives the human commit range, filters bot/config-only work, gets the deterministic diff and metadata, and sends the bounded change context to the Checkpoint generator.
The generated checkpoint is prepended to a stable per-author Markdown file. The checkpoint is the smallest unit in the system: a dated explanation of what changed at that moment and why it matters.
Generated Checkpoint paths are excluded from the diff so the tool does not continuously summarize itself.
feat: add health endpoint without reading plant storage
Ben committed on 2026-10-08 · 33cf8bc
+ if self.path == '/health':+ self.send_response(204) + self.end_headers() Commit 33cf8bc — 2026-10-08
Context
The commit adds a health endpoint that can respond without reading plant storage. Previously, Handler.do_GET only accepted /api/reminders; other paths returned 404. The new route exits before reminder handling.
Changes
sprout/server.py—Handler.do_GETnow recognizes/health, sends HTTP 204, ends the response, and returns. The route does not calldue_plants,load_plants, orload_settings.
03.2Personalized catch-up
Catch-up starts from a developer rather than a commit. The system finds that developer's last activity, reads checkpoint entries since then and excludes the requesting author's own changes.
That produces a briefing of what other people changed while the developer was away. When the developer contributes again, the stale catch-up can be removed because the context gap has closed.
Some of the trickier bugs here were ordinary temporal edge cases - identity, self-inclusion and date/timezone behaviour - rather than dramatic AI failures.
ee814c033cf8bc277188eb9d8436ef1521b24153c13894c30af60d81b26f83cf15c0aeCritical Changes (Must-Read)
Migrate plant data before starting reminders. Plant storage is now schema v2: the top-level data must have schema_version: 2, and each plant’s watering date uses last_watered instead of watered_at. load_plants() rejects data that hasn’t been migrated. Stop the service and run python -m sprout.migrate once. The migration backs up the original as .json.bak and uses a temporary file before replacing it. It accepts v1 or unversioned data, returns False for data already at v2, and raises ValueError for other schema versions. It will not overwrite an existing backup.
03.3PR summaries
For pull requests, Checkpoint combines PR metadata, the base-to-head diff and the commit-level checkpoint walkthrough into a higher-level review artifact.
The goal is to give a reviewer architectural impact, important changes and review context without losing the connection to the individual commits underneath.
I do not claim a measured review-time reduction; the value here is the implemented workflow and the structure of the context it preserves.
test: cover an empty plant collection #2
open · 0335036
Overview
This PR adds a regression test for reminder generation when the plant collection is empty. It checks that due_plants returns no reminders for that input, extending the existing reminder tests without changing production code.
Changes by Area
- Reminder tests —
tests/test_reminders.py- Adds
ReminderTests.test_empty_collection_has_no_reminders. - The test calls
due_plantswith an empty list, the fixed date2026-10-09, and a watering interval of seven days. - It asserts that the result is exactly
[]. The assertion covers both the absence of reminder entries and the expected empty-list result. - The existing tests in this file cover non-empty collections with different watering schedules. This addition puts the empty-collection case alongside those examples, using the same reminder function and a fixed date.
- Adds
03.4Master Context for onboarding
The onboarding path builds a broader project view. It can combine the repository tree, recent checkpoints, README/dependency context and generated architecture diagrams into MASTER_CONTEXT.md.
For Python projects, some diagrams can be produced deterministically from AST analysis. For multi-language projects, selected files can be passed to the model for a language-agnostic diagram. The point is orientation, not perfect reverse-engineering.
This artifact is the answer to the original internship problem: a new developer gets the project mission, architecture, decisions, gotchas and starting point without reconstructing everything manually.
Architecture Overview
The source package is sprout/. Its responsibilities are split across three modules:
sprout/reminders.pyowns data loading and reminder calculation. The checkpoint history namesload_settings()andload_plants()as the loaders, anddue_plants()as the function that selects records due for watering. Keeping these operations outside the HTTP handler gives the calculation and file-loading logic a place to be tested independently of HTTP.
Key Decision Log
-
Keep reminder logic separate from HTTP handling.
sprout/reminders.pycontains loading and due-date logic;sprout/server.pyhandles requests. The checkpoint describes this separation as the structure of the service. It makes the HTTP layer a consumer of the reminder logic rather than the owner of it. Rationale for this separation is documented as separating reminder logic from HTTP handling.
Gotchas & Tech Debt
-
Old plant files will not load until migrated.
load_plants()requiresschema_version == 2. Older v1 or unversioned files needpython -m sprout.migratebefore the reminder service can use them. The migration changeswatered_attolast_watered.
Getting Started
-
Check the project instructions. Read
README.mdanddocs/upgrade.mdbefore running or changing an existing installation. The README identifies the service as a demo and points maintainers to the upgrade guide.
03.5From experiment to installable tool
Checkpoint was published to PyPI as checkpoint-agent, with a setup guide and GitHub Actions templates. That forced the project to become more than a repo-specific experiment: configuration, packaging, release workflows and backwards compatibility all became part of the product.
The release workflow builds the package, verifies the version and uses trusted publishing rather than embedding long-lived PyPI credentials.
v1.2.6v1.2.5v1.2.4v1.2.3v1.2.2v1.2.1v1.2.0v1.1.1v1.1.0v1.0.6v1.0.5v1.0.4v1.0.3v1.0.2v1.0.1v1.0.0id-token: write # For trusted publishing (OIDC)uses: pypa/gh-action-pypi-publish@release/v103.6Observed workflow optimization
I also went back through the GitHub Actions history around the 29fd5bf "Optimised Checkpoints" period to get a defensible runtime comparison.
54 seconds, or 29.9% faster on average
Checkpoint reached a working core and public package, then paused while I started extending it toward more repository environments.
04.1What worked
I used Checkpoint myself during its initial development. The automatic checkpoint, catch-up, PR summary and onboarding/master-context flows worked, and the package was published to PyPI.
That is the result I am comfortable presenting: a working developer-context tool with repository-native artifacts and automated GitHub workflows.
994999fb4bac27b6db70f02658d304.2How I judged the output
The generated Markdown was meant for humans, so I judged it by reading it. I looked for whether the explanation was useful, whether it reflected the real diff and whether the document made the repository easier to understand.
There was no formal evaluation dataset or quality harness. I do not claim factuality scores or measured onboarding-time savings.
04.3Current status
The project is paused, with a working core. The newest work was moving toward support for cloud-hosted repository environments, including Azure/GCP/AWS-shaped workflows, but that path has not been fully tested.
I still want to finish it. The pause is a project-state description, not a claim that the earlier workflows stopped working.
04.4What I learned
Checkpoint is where I learned a principle that shows up in my newer projects too: deterministic systems should do deterministic work, and models should be used where interpretation is actually useful.
It also changed how I think about AI memory. The most useful memory is often not a hidden vector store. Sometimes it is a clear, versioned artifact that a human can read and a model can reuse.
Context is more useful when it is preserved as part of the work, not reconstructed after the fact.
04.5Next
When I return to Checkpoint, the roadmap is focused: finish cloud-hosted repository support, add Bitbucket, add configurable sensitive-context controls for files/paths/patterns/content, and experiment with Simplified Technical English as a writing standard for generated documentation.
The STE direction is especially interesting to me because the output should read like project documentation, not generic AI prose. I would treat formal ASD-STE100 compliance as a separate future validation question rather than claim it today.
