Skip to content

Repository files navigation


Kawan banner

Kawan

A skeptical AI accountability companion that holds you to one commitment and accepts only verified evidence, never self-report, as progress.
Live Demo Β» Β· Demo Video Β· Report a Bug

Python TypeScript React Vite Live2D FastAPI SQLAlchemy SQLite PostgreSQL Supabase Chutes Render Vercel uv pytest

Table of Contents

Expand
  1. About The Project
  2. Getting Started
  3. Roadmap
  4. Team
  5. License
  6. Acknowledgments

About The Project

"It doesn't believe you. Yet."

A skeptical accountability companion. Not a cheerleader. One commitment, verified evidence, no self-report. Earn the trust.

Most habit apps take you at your word. Tap a checkbox, keep the streak, lie to yourself for free. Kawan (Malay for "friend") is the opposite: a companion that holds you to one commitment, asks for real evidence, and only believes you once you've shown it.

You commit to a single deliverable with a deadline. Kawan checks in on a schedule, reviews the evidence you submit β€” a screenshot, a file, or commits in a GitHub repo β€” and returns a verdict: pass, fail, or unclear. Self-report is never accepted. Trust is earned check-in by check-in.

The catch that makes it work: Kawan can never change the terms of your deal. Your goal, deadline, and how you're verified are yours alone. The AI reads them, reasons about them, and nudges you β€” but it is structurally incapable of editing them. That guarantee is enforced in the schema, not just the prompt (see The trust boundary).

Built by Team CHJL with πŸ’–. Read the Pitch Deck and the design direction.

Built for Chutes Hack Malaysia 2026 (Corporate Track), where it placed 1st.

↑

Screenshots

Landing page
Landing Β· Kawan's pitch: one commitment, verified evidence, and no self-report.
Sign in with Chutes or as a guest
Sign In Β· Sign in with Chutes, or continue as a guest without an account.
Guided walkthrough
Guided Tour Β· An optional tour that teaches the commitment flow on real components.
Home dashboard
Home Β· The dashboard links your commitments, analytics, workspace and recent activity.
Commitments list
Commitments Β· Every commitment with its deliverable, status and deadline, active or finished.
Analytics & achievements
Analytics Β· A productivity meter, identity titles and 15 achievements that reward how you won.

↑

How It Works

A commitment moves through a single, deterministic lifecycle β€” from drafting the deal to a verified (or honestly un-verified) outcome.

  1. Compose β€” state the deal. I will [complete] [a deliverable] by [a deadline]. One goal, one deadline. No room to be vague.

    Compose your commitment
  2. Plan β€” set the terms. Choose your evidence source (a GitHub repo to watch, or screenshot/file uploads), optionally name a witness who gets emailed if you miss, and a reminder email. Only you can change these. Kawan reads them but never edits them.

    Set your plan and stakes
  3. Companion β€” pick who holds you to it. Three personalities, same backbone:

    Companion Archetype Tone
    Kawan Skeptical Concierge Candid, warm, slightly dry. Believes you because you proved it.
    Adik Gentle Cheerleader Encouraging and kind. Celebrates every step.
    Cik Maid Playful Taskmaster Brisk, playful, expects results β€” with a wink.
    Choose your companion
  4. Check in β€” answer to your companion. Your companion enters the workspace as a live, animated avatar. It gathers context (why, obstacles, time), then checks in on schedule and waits for evidence.

    Live2D check-in in the workspace
  5. Workspace β€” context, plan & evidence in one place. A focused room around the conversation: captured context, an advisory plan, recent activity, a live countdown to the next check-in, and the Submit final evidence action.

    The commitment workspace
  6. Track β€” overview, progress & terms. Every commitment has a detail page: verified count, check-ins, latest verdict and reasoning, the immutable terms, and a full timeline.

    Commitment detail page
  7. Finish β€” verified, and only then. When the evidence passes, the commitment is closed as done. No participation trophies β€” a win counts because it was shown.

    You did it β€” verified completion

↑

Features

  • One real commitment. A single action + deliverable + deadline. Hard fields you set and only you can change.
  • Evidence over self-report. Verdicts come from a GitHub repo's commits, an uploaded file, or a screenshot judged by a vision model. There is no "mark as done" button you can lie to.
  • Honest verdicts. Every check-in resolves to pass / fail / unclear. unclear never punishes; a flaky or slow model degrades to it instead of guessing.
  • Three Live2D companions. Kawan, Adik, and Cik Maid, each a stateless preset of tone + animated model + voice + inference model. Switching the companion changes the messenger, never your commitment.
  • TEE inference via Chutes. Real check-in lines and evidence judgments run on Chutes' Trusted Execution Environment chutes, with per-persona model routing and an automatic secondary judge on failure. A deterministic offline stub backend runs the whole app with zero keys.
  • Reliable delivery. Notifications walk a ladder: live WebSocket β†’ Web Push β†’ persisted in-app timeline, so a check-in is never lost.
  • Off-device reminders. Opt-in email (Resend), Web Push (VAPID), and a Telegram check-in channel.
  • Stakes & witnesses. Name someone who's emailed if you miss the deadline. That's the whole mechanism.
  • Analytics & achievements. A productivity meter, identity titles, and 15 behavioral achievements that reward how you won (verified without a skip-day, finished early, came back after a miss…).
  • Scheduled & on-demand check-ins. APScheduler drives the cadence; one code path serves both the cron tick and an instant "check now," and rebuilds its jobs from the DB after a restart.
  • Guided walkthrough. An optional tour that teaches the commitment flow on real components, not a fake demo.
  • Polished UX. Light/dark themes, responsive shell, optional Piper neural TTS with a WebSpeech fallback.

↑

Architecture

Kawan's architecture. The React SPA calls the FastAPI backend over /api. An on-demand check from the API and APScheduler's cadence and deadline ticks run one check-in pipeline. The pipeline judges evidence and writes the check-in line on Chutes TEE models, falls back to a secondary judge on a timeout or error, writes verdicts and check-ins to SQLite or Postgres, and delivers each check-in over the WebSocket first, then Web Push and reminders. The API signs users in with Chutes over OAuth2 PKCE and writes the hard fields.

The diagram is drawn with archify from architecture.json.

Kawan is a single-process FastAPI backend plus a React SPA. The frontend is organized in three zones: public pages (Zone 0), the SaaS shell (Zone 1 β€” home, commitments, analytics, settings), and the full-screen AI workspace (Zone 2 β€” the compose flow and live companion).

The trust boundary. The core idea is a hard separation between what you own and what the AI can touch β€” enforced in the data model, not just convention:

  • Hard fields (commitments table): action, deliverable, deadline, cadence, evidence type, stake. Written only by GUI handlers and the scheduler/verifier. No AI code path can update them.
  • Soft context (soft_context table): the why, obstacles, and constraints. The only table the AI is allowed to write.
  • Proposals: the AI can propose a change to a hard field, but only you can apply it.
  • Audit log: every hard-field mutation records an actor β€” and 'ai' is unrepresentable by a database CHECK constraint. The AI literally cannot be the author of a change to your deal.

That is why the UI can promise "Only you can change these. Kawan reads them but never edits them." and mean it.

The check-in pipeline. One code path (app/pipeline.py) runs for both a scheduled cadence tick and an on-demand check:

  1. Fetch new evidence through the adapter for the commitment's evidence type (github / screenshot / file).
  2. Judge it into a Verdict (pass / fail / unclear) β€” primary call on a Chutes TEE model, with a bounded timeout that fails fast to a secondary judge rather than hanging.
  3. Persist the evidence, check-in line, and escalation state.
  4. Deliver down the ladder: WebSocket β†’ Web Push β†’ in-app timeline.

A commitment's status machine (draft β†’ active β†’ verifying β†’ grace β†’ completed / missed, plus lapsed / returned) is the only thing that moves state β€” derived snapshots feed the AI as read-only prompt context and can never write back.

Project structure.

apps/
β”œβ”€β”€ backend/             # FastAPI single-process service
β”‚   β”œβ”€β”€ app/
β”‚   β”‚   β”œβ”€β”€ main.py      # app + lifespan (scheduler, telegram poller)
β”‚   β”‚   β”œβ”€β”€ models.py    # hard fields / soft context / audit log
β”‚   β”‚   β”œβ”€β”€ pipeline.py  # check-in + final verify (the one code path)
β”‚   β”‚   β”œβ”€β”€ personas.py  # Kawan / Adik / Cik Maid presets
β”‚   β”‚   β”œβ”€β”€ adapters/    # github Β· screenshot Β· file evidence
β”‚   β”‚   β”œβ”€β”€ routes/      # auth Β· commitments Β· push Β· telegram Β· voice Β· ws
β”‚   β”‚   └── …            # scheduler, chutes client, notify, state machine
β”‚   β”œβ”€β”€ render.yaml      # Render deploy
β”‚   β”œβ”€β”€ DEPLOY.md        # pooler, secrets and Vercel env notes
β”‚   └── .env.example     # backend settings with dev defaults
└── frontend/            # React + Vite SPA
    β”œβ”€β”€ src/
    β”‚   β”œβ”€β”€ shell/       # Zone 1 β€” SaaS shell + pages
    β”‚   β”œβ”€β”€ zone2/       # Zone 2 β€” workspace, Live2D, new-commitment flow
    β”‚   β”œβ”€β”€ timeline/    # analytics, achievements, productivity meter
    β”‚   └── …            # auth, notifications, ui, share
    └── public/          # Live2D models (Git LFS), banner, icons, service worker
scripts/                 # download_voices.sh Β· helpers
docs/                    # PRD, TRD, design, ADRs and the pitch deck
└── readme/              # the images in this README

↑

Tech Stack

  • Languages: Python and TypeScript.
  • Frontend: React 18, Vite, React Router v7, PixiJS v6 with pixi-live2d-display, Recharts and Lucide, with Live2D Cubism avatars (Haru, Hiyori, LiveroiD).
  • Backend: FastAPI, SQLAlchemy 2 (async), APScheduler, Pydantic Settings and httpx, delivering over WebSocket and Web Push (VAPID).
  • Data: SQLite (dev) and PostgreSQL via the Supabase pooler (prod).
  • AI and services: Chutes (OpenAI-compatible TEE inference) with Sign in with Chutes (OAuth2 PKCE), a deterministic stub backend, optional Piper neural TTS, the Telegram Bot API and email through Resend.
  • Infrastructure: Backend on Render and frontend on Vercel.
  • Tooling: uv, Biome and pytest.

↑

Getting Started

The app runs fully offline out of the box β€” the default AI backend is a deterministic stub, so you need no API keys to try it locally.

↑

Prerequisites

  • Python 3.12+ β€” runs the FastAPI backend.
  • uv β€” installs and runs the backend.
  • Bun β€” installs and runs the frontend; the frontend lockfile is bun.lock, and npm or pnpm also work.
  • Bash β€” runs the asset scripts, which are bash.

↑

Installation

  1. Configure the environment. Run each block from the repository root.

    cp apps/backend/.env.example apps/backend/.env  # sensible dev defaults are pre-filled

    The dev defaults use local SQLite, the Vite proxy, and KAWAN_AI_BACKEND=stub. No secrets required.

    All settings use the KAWAN_ prefix and load from apps/backend/.env. See .env.example for the full list. The most important knobs:

    Variable What it does
    KAWAN_AI_BACKEND stub (deterministic, offline β€” default) or chutes (real TEE inference)
    KAWAN_DATABASE_URL SQLite by default; a Supabase pooler URL in prod
    KAWAN_CHUTES_API_KEY Chutes token β€” enables guest-mode inference
    KAWAN_SIWC_* Sign in with Chutes (OAuth2 PKCE) client credentials
    KAWAN_SESSION_SECRET / KAWAN_FERNET_KEY Cookie signing + token-at-rest encryption (must be set in prod)
    KAWAN_VAPID_* Web Push keypair β€” blank disables push (delivery falls back to the timeline)
    KAWAN_RESEND_API_KEY Stake/reminder email β€” blank uses a log-only outbox so the miss path still runs
    KAWAN_TELEGRAM_BOT_TOKEN Telegram check-in channel β€” blank makes every send a no-op
    KAWAN_PIPER_VOICES_DIR Directory of Piper voice models β€” blank returns 204 and the client uses WebSpeech

    To use real inference, set KAWAN_AI_BACKEND=chutes and provide KAWAN_CHUTES_API_KEY (and the KAWAN_SIWC_* values for Sign in with Chutes).

  2. Fetch the Live2D companion models. They are stored in Git LFS; pull them once after clone.

    git lfs pull
  3. Run the backend. FastAPI on :8000.

    cd apps/backend
    uv sync
    uv run uvicorn app.main:app --reload
  4. Run the frontend. Vite on :5173, proxies /api and /ws to the backend.

    cd apps/frontend
    bun install
    bun dev

    Open http://localhost:5173 and choose Continue as guest to start.

    Optional β€” voices: run ./scripts/download_voices.sh to fetch the three Piper persona voices. Without them, the frontend falls back to the browser's WebSpeech voice.

  5. Deployment.

    • Backend β†’ Render. apps/backend/render.yaml defines the web service (uv sync β†’ uvicorn). Secrets and the cross-origin cookie settings (KAWAN_COOKIE_SAMESITE=none, KAWAN_COOKIE_SECURE=true) are set in the Render dashboard. Database notes (Supabase session vs. transaction pooler) live in apps/backend/DEPLOY.md.
    • Frontend β†’ Vercel. apps/frontend/vercel.json rewrites /api/* to the Render backend and serves the SPA. In production the WebSocket connects directly to Render, which is why prod runs SameSite=None; Secure cookies.
  6. Run the checks. From the repository root, lint the repository, run the backend tests, then build the frontend.

    bun install
    bun run check

↑

Roadmap

See open issues for a full list of proposed features (and known issues).

↑

Team

Team

Made with contrib.rocks.

↑

License

See LICENSE for more information.

↑

Acknowledgments

↑

About

A skeptical AI accountability companion that holds you to one commitment and accepts only verified evidence, never self-report, as progress.

Topics

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Contributors

Languages