Legal

Privacy Policy

Effective 14 September 2026

Who we are and what this covers

Kairoku is operated by OWDS Inc. You can reach us at support@owds.ca.

This policy covers the hosted service at kairoku.io and app.kairoku.io, this site, and the parts of the desktop app, its kairokud daemon and the orchestration runner the kairoku CLI installs that talk to it. What those keep on your machine, the vault under ~/.kairoku/daemon/ included, stays there. Editing from the web app is different: the automation and playbook forms send what you type, a webhook signing secret included, through us and our protocol gateway to that machine.

The CLI, that runner and the Claude Code plugin are public at https://github.com/owds-inc/kairoku; the hosted app is not.

What we collect

Account and identity data, held by Clerk

Clerk handles sign-up, sign-in, sessions and organisations, and holds your email address, first and last name, avatar, and a password, a Google sign-in, or both; an emailed code is always an alternative. Sign-up runs Clerk's CAPTCHA. Clerk records each session with the browser, device type and approximate city and country, revocable under Settings, Profile.

Our own database holds no Kairoku name, email address or avatar of yours, only Clerk's opaque user and organisation ids, as the owner of your rows and for attribution: who created a document, who set a secret, who ran a sync. The activity feed fetches display names and avatars from Clerk at render time; with no name set, what shows is the Clerk username or email address. Avatars appear in an organisation's feed only.

Workspace content you create

Everything you put into a workspace is stored in our database: projects, releases, plan items with their bodies and test notes, documents, comments, triage notes, todos, agent role prompts, dispatch briefs, run summaries and logs, and chats with their full message history, tool calls and results included. Document attachments go to a private Vercel Blob store over HTTPS, where unsigned fetches are refused.

Credentials you connect

If you connect a service we store what it needs to be called: your Atlassian site URL, account email and API token; your GitHub or GitLab personal access token and, for GitLab, the instance URL; your OpenRouter API key and model. Beside each we store the account it belongs to, such as your GitHub login. Project and organisation secrets for dispatched runs are stored the same way. A token from one of our hosted OAuth brokers is not kept here at all: it sits in an encrypted handoff row for ten minutes while your daemon collects it, and the row is deleted on collection.

Tokens, keys and secrets are encrypted at rest with AES-256-GCM under a server-held key. There is no KMS in front of it and no end-to-end encryption: the service decrypts to deliver, so a deployment can read what it holds. MCP and daemon tokens are stored only as SHA-256 hashes, shown once, and no page renders a stored credential back to you. We decrypt one whenever we call the service it belongs to. Beyond those calls, a stored credential is handed out in two places only: the run claim, which gives a registered machine that run's project secrets, and the OAuth handoff your daemon redeems.

Technical data

Our code writes no IP address, user agent, geolocation or device fingerprint. For each machine you register we store the name you give it, what the daemon reports about itself (host, version, capacity) and when we last heard from it. Our providers keep their own operational logs of the requests they serve, on their terms rather than ours: Vercel, Clerk, Cloudflare and Neon.

The app sets two first-party cookies: whether the navigation rail is collapsed, and that you hid the Try onboarding group. Clerk sets its own. Local storage holds your display settings and document drafts; session storage holds unsent issue and inline-field drafts and a sign-in handshake marker.

Deleting your account clears your drafts for that user id in the browser you delete from, best effort, and no other. Display settings and the handshake marker are per-browser, cleared with site data.

Analytics and error reports

Every page, including this one, loads Vercel Analytics. Vercel describes it as cookieless and says it does not identify you across sites; that is Vercel's characterisation, not something our code can establish. We set no identifier of our own and show no cookie consent banner.

When something breaks, the app sends an error report to Sentry: the stack trace, the route, the version deployed, and your Clerk user id so we can find the affected workspace. Reports carry no request or response bodies, no document content, no session recording. Warning-level log lines from our servers go to the same place with secrets removed. There is no Google Analytics or PostHog.

How we use it

We use your data to run the service: to authenticate you, show your workspace, call the services you connected, run the AI features you invoke, dispatch work to machines you register, and relay Slack events to your daemon. We do not sell personal data or use your content for advertising.

AI processing

Chat and document AI commands send content to an AI provider outside our systems. A chat turn sends a system prompt holding the project's name, one-liner and description, the agent's instructions, the release under discussion and the text of the documents you ticked, as many as fit a size budget, plus that chat's whole message history. Tools called mid-turn can add repository file contents, code search results, Jira statuses and Confluence page lists. A document AI command sends the selection, the document and your prompt, up to a request-size cap.

By default the provider is Anthropic, called with our key, and the model may use its server-side web search, up to five searches a turn. Turns on our key are counted, not read, per workspace per UTC day; at the cap the feature stops until the next day and tells you to add your own OpenRouter key. With a workspace's own key they go to OpenRouter and the provider selected there, with no web search, and are not counted.

Chat turns are stored in your workspace; document AI commands are not stored by the AI route.

What Anthropic does with what we send is governed by its own commercial terms of service at https://www.anthropic.com/legal/commercial-terms, which we do not control. For OpenRouter what applies are the terms you accepted there and with your chosen provider; we set no no-training flag and cannot say what a downstream provider does.

A dispatched run receives its brief and the plan item body; the coding tools on that machine use their own logins, which we never hold.

Sub-processors

These providers process data on our behalf:

  1. Clerk: identity, sessions, organisations, and the OAuth server for MCP sign-in.
  2. Neon: the Postgres database holding workspace content and encrypted credentials.
  3. Vercel: hosting, functions, durable sync workflows, Blob file storage and Analytics.
  4. Anthropic: default AI model and server-side web search.
  5. OpenRouter and the providers it routes to, only when your workspace supplies its own key.
  6. Cloudflare: two Workers. The Slack wake relay queues Slack events for up to 72 hours while your daemon is offline. The protocol gateway carries the web app's live calls to your daemon: the Floor and the automation and playbook forms. Dispatched work never reaches Cloudflare: we write it to our database and the machine collects it at check-in. Relay tickets name your Clerk user id and an install id; gateway tickets add the project and the machine. Both expire in a minute, authorise a session of at most five, and carry no Slack token.
  7. Sentry (Functional Software, Inc., US): error reports and server log lines.

Integrations you connect

Each integration is optional.

  • Atlassian Jira and Confluence: pushing a plan creates and updates Jira issues and refreshing reads their status back; publishing a document writes a Confluence page and pulling reads the space's page tree. Creating an issue or page is always a human push from the Sync tab; with auto-sync on, an agent's tool call can update ones already linked, logged as the agent. Those writes use the site URL and API token you paste into Settings; our hosted Atlassian broker asks only for read scopes and offline access.
  • GitHub and GitLab: we only ever read, with the token you paste into Settings. The app reads pull and merge requests with their reviews and CI status, branches and recent commits, file contents and code search, and the account login; it writes no pull request, branch or comment. Our hosted GitHub broker is a separate path: it asks for repo, because a classic OAuth App has no read-only equivalent for private repositories, so the token you issue there is write-capable. Our calls never use it; it travels through the handoff row to your daemon's vault. GitLab's grant is read-only.
  • Slack: connected on the desktop daemon or through our hosted OAuth broker. A bot token you paste into the desktop app never reaches us. Through the broker we ask Slack for app mentions, message posting, public channel history, direct message history and the user list; that grant is wider than reading mentions because the daemon replies in Slack. Its token set travels as the handoff row described under Retention.

While an organisation is active, everything you create or configure belongs to it and is visible to every member: the Atlassian, GitHub, GitLab and OpenRouter connections, the MCP access tokens, the machines and agent roles you configure, project and organisation secrets, and your chats with their full message history. Values are the exception: a stored secret or token is never rendered back to anyone, so what a member sees is the row and its name. Only your Clerk profile, email addresses and sessions stay yours. Nothing you connect through a hosted OAuth broker is on that list, Slack included: no such grant becomes a lasting row here, and its home is the vault on the daemon's machine, belonging to that installation rather than your workspace.

Sharing links

A share link lets anyone holding it read without signing in. A document link opens that document with its attachments. A release link opens the release record only: the release's scope note, its phases, plan item and document titles with their status, and the ship decision recorded against each item, but no document body or attachment. Share pages are noindex but crawlers are not blocked, so a link posted publicly can be found. Links do not expire; revoking one is immediate.

Retention

Retention differs per table:

  • Workspace content, chats, comments and encrypted credentials persist until you delete the object or its parent project.
  • The activity log, the record of your last visit, and the per-workspace daily count of AI turns on our key are never pruned; that count holds a workspace id, a date and a number, nothing else.
  • Dispatch run events older than 30 days and daemon commands older than 24 hours are deleted whenever a registered machine next checks in; there is no scheduled job, so with nothing checking in they wait.
  • An OAuth handoff row is usable for ten minutes and is deleted the moment your daemon redeems it. A flow nobody finishes leaves a row that the next hosted OAuth flow deletes; nothing sweeps on a schedule, and support@owds.ca can remove one sooner.
  • Run-scoped MCP tokens are deleted when the run ends; signed attachment URLs expire after 60 minutes, though the file stays with its document.
  • MCP personal access tokens and daemon tokens are kept as hashes until you revoke them; nothing expires them.
  • Uploaded files can outlive their rows: deleting a document deletes its stored files best effort, and a failure leaves one behind, while deleting a project deletes the attachment rows but not the files, which stay in the blob store until removed by hand.

We keep no archive of our own, but our providers hold operational copies, so a deleted row can persist for a time in a history we do not read back.

Deletion, and the absence of export

Deleting your account happens in Clerk, from Settings, Profile: profile, email addresses and sessions go. Nothing in our own database goes with it, because no purge job exists. Rows in your personal workspace, projects, documents, chats and encrypted tokens included, stay until someone deletes them; anything an organisation owns stays with it. Deleting a project cascades to its releases, documents, plan items, comments, triage, activity, sync mappings, secrets and dispatches; chats and todos outside a project survive it.

To have everything tied to your account removed, email support@owds.ca from the address on it. A person does it by hand, so allow time: we delete the rows keyed to your workspace, the credentials in them and the files in the blob store, and tell you when it is done. We cannot delete what you pushed to Jira, Confluence or a repository.

There is no data export and no tooling to build one, so copy out what you need before deleting anything; if you cannot, ask at the same address and we will do what we can.

Your rights

You can change your name, email addresses and avatar under Settings, Profile, revoke sessions there, and edit your workspace content in the app. For anything else, including correction or deletion, email support@owds.ca; we will ask you to verify you control the account.

Children

Kairoku is not directed at anyone under 16 and we do not knowingly collect their data. If you believe a child has an account, tell us at support@owds.ca and we will remove it.

Changes to this policy

When we change this policy we update the effective date at the top of this page. We publish no record of changes and send no announcement email, so that date is the whole notice; continued use means the new version applies. The terms governing your use of the service are at /terms.

Contact

OWDS Inc. support@owds.ca