Onward — Devpost Project Description

Inspiration

Think about everything you're carrying in your head right now.

A school wants your daughter's birth certificate, vaccination records, and proof of residence by Thursday. Your car insurance runs out on Sunday. Your visa renewal is due at the end of the month, and it needs a police clearance, a support letter from someone who hasn't replied yet, and passport photos you keep meaning to take.

None of it is hard on its own. The hard part is holding all of it at once. Which documents do you already have? Which ones did you ask someone for, and who was it? Did they ever answer? What's due first, and what takes the longest to get? You rehearse the list in the shower. You wake up at 3 a.m. remembering something you forgot. You scroll through message threads and open five different apps just to rebuild the picture, and by tomorrow you'll have to do it again.

And the things that sink you are the ones that depend on other people. You can finish a form in an afternoon. You can't make an office answer faster. By the time you realize the transcript takes two weeks to arrive, or that there was a document you didn't even know you needed, it's too late to do anything about it. One dropped detail can cost you a visa, a school place, or a lapse in coverage.

The deadline was never the problem. The problem is that nobody is holding the whole picture, so you are, constantly, and the weight doesn't lift until every last piece is done.

And the worst part is when it hits. It never happens while you're sitting at a desk with a notebook open. It happens while you're cooking dinner, folding laundry, or getting the kids ready for school, with wet hands and no free thumb. By the time you could write it down, it's gone again.

What if you could just say it out loud? "I need to enroll my daughter by the 22nd." "The vaccination records just came in." "What's still outstanding for the visa?" No app to open, no form to fill, no list to rebuild. You say it in plain language while your hands are busy, and something else keeps track.

That's the idea behind Onward: an assistant that lives where you already talk while you're busy, and holds the whole picture for you.

Every goal has the same structure: a deadline, a set of requirements, and a few things that depend on someone else. Most tools help you remember individual tasks, but they don't help you see how those tasks fit together, or when you have to start something to finish on time.

That's what we built Onward for. Not another to-do list. Not another reminder app. A proactive assistant that understands what a goal requires, tracks every piece, and speaks up early enough for you to do something about it, so you can stop carrying it all in your head.

We talked to people while building it. A parent enrolling her child in a new school described what she wanted: "It reminds me of things I might have forgotten... I wouldn't have to keep everything in my head." Another user described what would make her abandon a tool: repeated reminders about things she already knew, irrelevant requirements, or having to update everything manually.

Those two perspectives shaped our design. Onward needed to take the load off without becoming another source of noise.

What it does

Onward is a proactive assistant for goals that share a specific structure: a deadline, a list of requirements, and at least one requirement that depends on another person or institution responding.

It supports ten goal types: graduate and scholarship applications, visa and permit applications, job applications with references, grant applications, signed-form returns, school enrollment, camp registration, doctor appointment paperwork, lease signing, and tax filing. Each type comes with a template of common requirements, so users have a starting point instead of a blank checklist.

You talk to it. Onward is voice-first. Tap the orb, say what you're working toward and when, and Onward answers out loud — in a real voice, with live captions on screen so the conversation stays readable with the sound off. A goals panel beside the orb is the itemized, always-current checklist for every active goal: deadlines, per-item status, progress bars, and dependency details, updated the moment anything changes.

Onward identifies the goal type, presents its typical requirements, and asks what the user already has. It tracks each requirement as not started, in progress, waiting on someone, or done. But tracking items is only the beginning.

Reminders that help you act before it's too late.

Onward schedules reminders around the deadline: seven days before, two days before, on the deadline, and after the deadline if work remains outstanding.

More importantly, it calculates when users need to request external documents. If a police clearance typically takes three weeks and the deadline is five weeks away, Onward can remind the user to request it two weeks from now. It works backward from the deadline and the expected turnaround time instead of waiting until the situation becomes urgent.

Natural-language updates.

Users can update their progress without navigating forms or selecting statuses manually. Saying "I sent the request to Prof. Lee" moves the recommendation letter to waiting on someone. Saying "the transcript came in" marks it as done. Saying "I filled out the visa form" marks the form as completed.

Onward interprets what users mean in context rather than requiring a specific command or exact phrase.

Multiple updates in one message.

A user can say, "I got the birth certificate and paid the visa fee," and Onward can update both requirements in one turn. It also supports adding a requirement to multiple goals at once.

Clarification instead of guessing.

If the user has both a job application and a scholarship application, each with a CV requirement, saying "I finished my CV" isn't enough to determine which item should change. Onward asks a short clarifying question rather than risking an update to the wrong goal.

Flexible deadlines and reminders.

Users can extend a deadline by voice. Onward updates the date and recalculates the reminder schedule. They can also snooze a reminder without repeatedly receiving the same notification at the same scheduled moment.

Support when deadlines are missed.

If a deadline passes while requirements remain incomplete, Onward acknowledges the situation and helps the user decide what to do next instead of simply abandoning the goal.

A real MCP server underneath. Below the voice interface is a self-hosted Model Context Protocol (MCP) server using Streamable HTTP. It exposes its tools to any MCP-compatible client, so the same functionality is available beyond a single conversational interface.

How we built it

Our most important architectural decision was simple: the AI decides what action to take; deterministic code decides what is true.

The core of Onward consists of independent services built around predictable, testable logic:

  • requirementService manages valid requirement status transitions.
  • completenessService compares a goal's requirements against its template to identify missing items.
  • riskService calculates deadline slack and evaluates outstanding work.
  • reminderService determines which reminders are due.
  • reportService renders progress reports.

These services don't call an LLM or access the database directly. They operate on data and return results that can be tested independently.

Above this core sits a single LLM interpreter, implemented in updateInterpreter.js. For each user message, it receives the message, the current state of active goals and requirements, recent conversation history, any pending clarification question, and relevant reminder context. It returns a structured action from a predefined set. The orchestrator validates and dispatches that action, keeping database writes in one place.

We deliberately avoided a chain of separate intent classifiers, extraction calls, regular-expression fallbacks, and fuzzy routers. When the interpreter cannot determine what the user means, it can ask a specific question instead of guessing.

The requirement state machine also enforces different rules for tasks users complete themselves and dependencies that involve other people. An external dependency can be marked done directly when an item arrives without a request ever being logged, and Onward records the received date. The waiting state tracks requests that are still out, so Onward can tell a document you asked for from one you already have.

The reminder engine is data-driven. For an external dependency, the request-by date is calculated as:

deadline − (typical turnaround days + 7 days)

Other reminder moments are calculated directly from the deadline. Fired reminders are recorded so the same scheduled moment doesn't repeatedly trigger. If several reminders become due on the same day, Onward combines them into one message.

The AI helps phrase those messages, but the underlying facts — completed requirements, outstanding work, overdue items, and request-by dates — come from deterministic code. If the AI phrasing step fails, a deterministic fallback still produces a useful message.

Voice. The interface is a single tap-to-talk orb. Its ring shows what it's doing at a glance: a steady pulse while listening, a travelling arc while thinking, a talking rhythm while speaking. Tapping while Onward talks cuts it off and hands the turn back. What Onward heard and what it said appear as live captions as it happens. Two quiet turns in a row end the conversation naturally.

Speech input uses the browser's SpeechRecognition. Speech output uses Groq's Orpheus voice through the server, with the browser's own voice taking over transparently whenever the voice service is unavailable — so the conversation never stalls on a voice failure. Dates are read the way a person says them ("October 23", not "2026-10-23"), and long replies are split into speech-sized chunks.

Turns are tuned for conversational latency: interpreter, phrasing, and suggestion calls each have their own timeout and fall back to deterministic, natural-sounding text rather than making the user wait on a slow model.

We built the backend with Node.js, used Groq's openai/gpt-oss-120b for the conversational interpreter and message phrasing, and used Supabase with PostgreSQL for persistent storage. The frontend uses plain HTML, CSS, and JavaScript. The MCP server uses the official @modelcontextprotocol/sdk and StreamableHTTPServerTransport.

Finally, the ten goal types and their requirement templates are seeded through a one-time script. Each requirement is classified as essential or helpful, allowing Onward to distinguish core requirements from those that depend on the user's circumstances.

Challenges we ran into

Making the assistant conversational instead of fragile.

Our first version used three separate LLM calls for each message: one to classify intent, one to extract details, and another to generate the reply. When these calls failed or misunderstood the user, regular-expression fallbacks attempted to guess what the user meant.

The result was brittle. Users had to phrase things in specific ways, and the system sometimes misunderstood their intentions.

We replaced that pipeline with a single interpreter call that receives the current state and relevant conversation context. This simplified the architecture and gave the model the information it needed to make better decisions.

Preventing updates to the wrong goal.

When two goals contain the same requirement, an update can be ambiguous. Our initial implementation let the model choose a matching item, which sometimes resulted in the wrong selection.

We added a deterministic collision check before accepting single-item updates. If multiple goals contain the same item, Onward asks the user to identify the intended goal. The next response resolves the ambiguity against actual candidate items rather than relying on a guess.

Handling multiple changes in one sentence.

Users naturally combine updates: "I sent the reference request and finished my CV." Our first implementation could process one change and silently miss the other.

We introduced a multi-update action and refined the interpreter using concrete examples of compound messages and their expected structured outputs. This taught us an important lesson: examples can communicate expected model behavior more effectively than abstract instructions alone.

Preventing contradictory reminders.

One early reminder said everything was on track immediately after listing several incomplete requirements. The model was following an instruction to end with a reassuring sentence, even when the facts didn't support it.

We removed that generic reassurance and made the closing message depend on the actual state. If work remains outstanding, the system cannot claim that everything is on track.

Fixing reminders that fired when nothing was wrong.

A goal with every requirement completed could still receive an at-risk warning because the risk calculation considered whether the remaining buffer was sufficient, even though no work remained.

We corrected the logic so that a goal with no outstanding requirements isn't considered at risk merely because of an unused buffer calculation.

Resetting reminders after a deadline extension.

After a deadline changed, previously fired reminders remained recorded, preventing the corresponding reminders from firing for the new deadline.

We fixed this by clearing the fired-reminder record when the deadline changes and recalculating the schedule. Extending a deadline now starts a new reminder cycle.

Working within LLM usage limits.

We hit Groq's daily token quota repeatedly during development. We reduced the conversation history passed to the interpreter, skipped unnecessary LLM phrasing for short updates, ran independent LLM calls in parallel with cancellable requests, and used deterministic fallbacks where appropriate.

The lesson was that an LLM call should earn its place in the architecture. Reasoning benefits from the model; routine formatting often doesn't need it.

Making it work out loud.

Voice introduces failure modes that text doesn't have: microphones get blocked, recognition needs a connection, the speech service can be rate-limited or unavailable. We made each of these recoverable — clear on-screen messages when the microphone or connection is the problem, and a transparent hand-off to the browser's own voice when the Groq voice isn't available — so a failure never leaves the conversation stuck.

We also learned to tune for latency. A spoken conversation has no patience for a slow model call, so every LLM step in the voice path has a timeout and a natural-sounding deterministic fallback, written to sound just as human as the generated version.

Accomplishments we're proud of

A focused solution to a real problem.

Onward doesn't try to manage every aspect of someone's life. It focuses on goals with deadlines, requirements, and external dependencies. That focus lets us build behavior around a concrete problem rather than offering a generic chat interface with a checklist attached.

Proactive reminders based on turnaround time.

Onward works backward from deadlines to calculate when external requests need to be started. This is more useful than simply reminding someone that a deadline is approaching: it helps them identify the action they need to take while there is still time.

Natural-language interaction backed by structured state.

Users can update one requirement, change several requirements at once, add items across goals, extend deadlines, or resolve ambiguous requests through conversation. The system maintains structured records instead of treating every interaction as an isolated exchange.

A deterministic foundation.

We built and tested the core requirement state machine, completeness checker, risk calculator, reminder scheduler, and report renderer independently of the LLM. All five deterministic test suites pass, giving us a foundation we can verify separately from the probabilistic conversational layer.

A voice interface that feels like an assistant, not a form.

A tap-to-talk orb with an animated state ring, live captions, spoken answers, interruption, and natural end-of-conversation — with a browser-voice fallback that keeps it working even when the voice service isn't. The same information is always visible in the goals panel, so nothing Onward says has to be taken on faith.

A real MCP server.

We implemented a self-hosted server using Streamable HTTP and the official MCP SDK, exposing tools for compatible clients. This makes Onward more than a browser-only assistant: its underlying capabilities can be accessed through the MCP ecosystem, and a real Alexa+ client could call it the same way our interface does.

User feedback that influenced the design.

Feedback about forgotten requirements and repetitive manual updates shaped concrete design decisions: proactive request-by reminders, natural-language status updates, and clarification when an action is ambiguous. We used those needs to guide implementation rather than treating user feedback as an afterthought.

What we learned

The AI should decide what to do, not what is true.

The most important lesson from Onward was knowing where AI belongs in the architecture. An LLM is useful for interpreting natural language, but facts such as item status, missing requirements, reminder dates, and deadline risk should be calculated by code whenever possible.

Separating these responsibilities made the system easier to test, debug, and reason about.

Trust depends on knowing when not to speak.

Users may appreciate a useful reminder, but irrelevant or contradictory reminders quickly undermine confidence. A reminder that repeats after being dismissed or warns about a goal with no outstanding work creates noise instead of value.

We learned to treat silence as part of the product design. Onward should speak when it has something relevant and accurate to say.

A narrow scope can produce deeper functionality.

Supporting ten defined goal types lets us provide useful starting templates and turnaround assumptions instead of pretending to understand every possible situation. That knowledge still needs to be adapted to each user's circumstances, but the templates give the system a meaningful foundation.

Conversation requires memory as well as interpretation.

A user might answer a clarification question with "the visa one" or refer to something mentioned earlier. Treating each message independently makes these interactions brittle.

Passing recent conversation history and preserving pending questions gave the interpreter the context needed to handle follow-up messages coherently.

Real testing reveals problems that code review misses.

The contradictory reminder, ambiguous item selection, and incomplete compound update all became obvious when we tested complete user flows. Each exposed a gap between what the system was technically doing and what a user reasonably expected.

Building the feature is only part of the work. Testing how people actually use it is what makes the feature dependable.

Voice changes what "fast enough" means.

In a chat window, a few seconds of waiting is tolerable. Out loud, it's dead air. Designing the voice path meant every LLM step had to justify its latency, have a timeout, and have a fallback worth hearing — which turned out to sharpen the text path too.

What's next for Onward

Actually sending follow-ups.

The current follow-up workflow can draft a message, but sending remains in sandbox mode. Our next step is to integrate a real messaging provider so users can move from identifying an overdue dependency to sending an appropriate follow-up.

Deeper voice integration.

Onward's conversational design is a natural fit for voice, and the voice interface is a first step. Registering the MCP server with the Alexa+ MCP Toolkit would let users create goals and check progress on the devices they already talk to, with no browser at all.

More goal types and better templates.

We plan to expand into areas such as apartment hunting, medical procedures, and immigration processes. New templates would broaden the system's usefulness while preserving the same underlying engine.

Long-running goals with dependent steps.

Some goals contain chains of dependencies rather than independent requirements. For example, a user may need to receive one document before requesting another. We want to represent those relationships explicitly and calculate the critical path across the dependency graph.

Learning from real turnaround times.

Typical turnaround estimates are useful starting points, but real institutions and individuals vary. Over time, Onward could use observed turnaround times to refine its estimates and help users plan more accurately.

Integrations with existing tools.

Email, calendars, and document-producing services could help Onward move beyond tracking and reminders toward completing actions. The MCP architecture provides a foundation for making these capabilities available across compatible tools and interfaces.

A broader MCP ecosystem.

We also want to make reminder schedules and goal information accessible to additional MCP-compatible clients, allowing users to interact with the same underlying system through different interfaces rather than being tied to one browser experience.

Our north star remains the same: make completing a goal less about remembering everything and more about knowing what to do next.

Built With

  • api
  • axios
  • css3
  • dotenv
  • es-modules
  • groq
  • html5
  • javascript
  • mcp-sdk
  • model-context-protocol
  • node.js
  • openai/gpt-oss-120b
  • orpheus-tts
  • postgresql
  • speech
  • speech-recognition
  • speech-synthesis
  • streamable-http
  • supabase
  • text-to-speech
  • vanilla-javascript
  • web
Share this project:

Updates

Submission history