Inspiration

Every focus tool we tried could measure time or block websites, but none understood context. A phone glance might be a distraction or part of the work. Leaving the desk might mean losing focus or grabbing a notebook. Tools that react instantly interrupt too often; ordinary timers never respond.

That led to GoalKeeper's central question:

Can an AI accountability partner accumulate uncertain evidence over time and intervene only when speaking is more helpful than staying silent?

GoalKeeper protects a commitment chosen by the user. You define the goal, visible behaviors that may justify a check-in, and sensitivity. The system is designed to support rather than police you.

What it does

GoalKeeper is an AI accountability app for focused work. You create a goal, choose how long you want to work, and select the visible behaviors you want help avoiding, such as sustained phone use or staying away from your workspace. Together, these choices form the session contract. Before the session begins, a camera preflight shows exactly what the room-facing camera can see and asks you to confirm the view.

During the session, GoalKeeper runs a focus timer and checks periodic still images for the patterns you selected. It does not react to a single ambiguous moment. If you briefly check your phone and return to work, the timer continues without interruption. If several consecutive observations show sustained phone use, GoalKeeper pauses the focus timer, marks the recent interval as unresolved, and starts a supportive voice or text check-in explaining what it observed.

You can explain that the phone was part of your work, acknowledge that you drifted and recommit, ask for brief coaching, override the check-in, or end the session. Based on your response, GoalKeeper restores or excludes the unresolved time, then resumes or ends the session. The user always has the final say.

Scheduled breaks pause the focus timer and keep break snapshots out of AI perception and behavioral evidence. If the camera, network, or model fails for too long, GoalKeeper pauses the timer instead of treating the technical problem as something the user did wrong.

When the session ends, GoalKeeper asks whether you fulfilled the goal and whether its check-ins were helpful. The history page shows the session contract, outcome, review, retained snapshot count, and storage use. Users can delete individual sessions or entire goals.

How we built it

We built GoalKeeper as a .NET 10 Blazor application. SQLite stores session data locally, OpenCV captures periodic still images, and hosted OpenAI models handle perception, reasoning, and voice recovery.

The app has four main parts:

  • Perception (GPT-5.6 Luna): reports visible facts without seeing the goal.
  • Reasoning (GPT-5.6 Luna): looks at evidence across time and recommends whether GoalKeeper should continue observing or start a check-in. It cannot change the session itself.
  • Recovery (GPT-5.6 Luna): maps a check-in conversation to an allowed outcome. GPT-4o Transcribe and TTS-1 provide optional voice interaction; raw audio is discarded.
  • Local controller: checks each recommendation and is the only part allowed to change the timer or session state.

Before GoalKeeper acts, it checks that the model response belongs to the current session, is recent, follows the expected format, and refers to observations that actually exist. Invalid or outdated responses are ignored. If an image arrives while reasoning is already running, the processing queue keeps only the newest pending image. This prevents a late interruption about behavior that has already ended.

A recorded hosted acceptance run exercised the complete workflow using GPT-5.6 Sol for reasoning. The current build now configures GPT-5.6 Luna for both the isolated perception and reasoning roles; a new hosted end-to-end run with Luna reasoning has not yet been documented.

Session records are stored locally, and each hosted model receives only the information needed for its assigned role.

How we collaborated with Codex

We broke the project into sixteen focused tasks. For each one, we told Codex which part of the application to work on, what behavior we expected, and how we would test the result. Codex helped implement the session state machine, timer rules, test doubles, automated tests, concurrency handling, Blazor screens, hosted adapters, and model-response schemas.

The most important exchange was not code generation. When the offline suite turned green, we stopped Codex from moving on: "No, it's time to test it." Using the real application exposed two issues the deterministic suite missed: Session Setup crashed for a new user who had not created a focus profile yet, and two pages rendered duration as "1:g min." Codex traced both, fixed them, and added regression coverage. We then completed the first live workflow using the reasoning configuration active at that time.

We still made the key product decisions. The camera description had to remain neutral, only application code could change the timer, and technical failures could never count as evidence against the user.

Challenges we ran into

Keeping the camera from becoming a judge

An early design allowed perception to produce conclusions such as "the user is distracted," giving one uncertain frame too much power. We made perception goal-blind and limited it to visible facts. Only the reasoning role may connect accumulated evidence to the user's commitment.

Handling a room-facing camera responsibly

GoalKeeper uses periodic stills, explicit camera-view confirmation for each session, local session storage, raw-audio disposal, and log redaction. During breaks, snapshots may still be retained locally, but they are excluded from Perception and behavioral evidence.

Fixing an underspecified schema

A GPT-5.6 Luna smoke test produced a people-count observation that the original schema allowed to contradict itself. The adapter safely treated it as technical failure. We redesigned counted, not-visible, and unknown states to be mutually consistent and reran the inputs successfully.

Accomplishments that we're proud of

  • A recorded hosted run completed the entire user workflow, including an intervention grounded in three consecutive observations and voice recovery.
  • Validation includes a 250-capture pipeline soak, 250-snapshot SQLite persistence run, repeated worker cleanup and leak tests with retained managed-memory growth below 8 MiB, and dedicated camera and transient-audio disposal coverage.
  • The deterministic eight-state focus machine makes every intervention reconstructable from stored observation references.

What we learned

We learned that detection was not the hard part. The difficult part is deciding whether it matters: was it one quick glance, or did several observations show that the user had actually drifted?

We also learned not to give the model direct control of the timer. GPT-5.6 can recommend what should happen, but ordinary .NET code checks the response and makes the change. That separation made problems easier to reproduce and test. Codex was most effective when we gave it one focused task at a time, identified the relevant files and expected behavior, and defined a result we could test. That made its changes easier to review and kept the different parts of the application consistent.

What's next for GoalKeeper

  • Evaluate intervention quality across more environments, lighting conditions, camera placements, and focus activities.
  • Build replay tooling for comparing reasoning changes against the same approved observation sequences.
  • Add user-approved cross-session personalization without silently rewriting an active Session Contract.

Built With

Share this project:

Updates