Platform Guide
InnoDay is the hub every project reports to.
Tickets, boards, repositories, scope, and releases usually live in five different tools. InnoDay pulls them into one project-shaped record — and makes that record follow you into the directory where you actually write code.
What is InnoDay?
InnoDay is an AI-powered team-orchestration platform. Every significant event — ticket work, board syncs, repo additions, scope changes, releases — is recorded in one place, against one project, so a project's full history is always queryable instead of rebuilt from git logs.
A single, queryable record of truth
Development state scatters by default. The board knows what is planned, GitHub knows what shipped, the release tool knows the version, and the decisions from the last meeting live in someone's notes. Reconstructing “where is this project?” means stitching those together by hand, every time.
InnoDay's premise is that every significant event is recorded in one place, against one project. Skills, agents, and CLI tools all write back to it, so the history is always there to query. The rule of thumb: if you need to remember it across sessions or share it with the team, it belongs in InnoDay.
You don't self-host to use it. The common path is uv tool install innoday, then point the CLI at the shared, Railway-hosted environment. You only clone the repository to develop InnoDay itself.
Six problems it solves
The “record of truth” idea earns its keep by clearing six specific frustrations that show up on any multi-repo, multi-project software team.
Deploy internal resources into projects with Claude Code — efficiently
Old way — context rebuilt by hand every session
A new model for software development: skills, agents, and project context are packaged and dropped into a project so an AI teammate can start productive work immediately, instead of being re-briefed from scratch each time.
Manage many projects and their board activity in one place
Old way — one browser tab per board, per project
Every project's tickets and board movement roll up to a single hub, so a lead can see the whole portfolio without hopping between Linear, Jira, and Trello workspaces.
Collect timelines across every process
Old way — history scattered across tools & git logs
Ticket work, board syncs, scope changes, repo additions, and releases all land on one curated project timeline — a chronological record that stitches together events which normally live in separate systems.
Generate active, human-readable summaries
Old way — "what happened this week?" is a research task
Because the events are all in one place, InnoDay can synthesize them with Claude into plain-language updates — scrum reports, work summaries, assignment breakdowns — so anyone can understand what's going on without reading raw ticket data.
Organize releases across repositories
Old way — repos tagged one at a time, notes written later
A single release tags every repo in a project together — discovered by GitHub topic — and ships with an auto-generated, feature-level summary, so a version means the same thing across the whole codebase.
Greater transparency into the team deployed to an org
Old way — opaque — who's doing what, where?
The hub makes the shape of the work visible — which projects are active, who (human or agent) is on what, and how effort is distributed across an organization.
The project sits at the center of everything
InnoDay's data model is a strict hierarchy. An organization is the tenant and security boundary. Inside it, a project is the unit you actually work inside — and it is the join point that every other concept attaches to.
Why “project-centric” is more than a diagram: the database enforces it. A board can't exist without a project, a ticket can't exist without a project, and a release version is unique per project. There is no such thing as an org-only ticket floating outside a project.
The concepts, and the rule that binds each to a project
| Concept | What it is | The binding rule |
|---|---|---|
| Organization | The tenant and security boundary; holds members, license, and everything below. | alias is globally unique — used in config keys and API paths. |
| Project | The working unit. Carries goals, scope limits, spec, status, priority, tags. | alias (≤10 chars, e.g. PF) is the ticket prefix, unique per-org. |
| Board Registration | Links a project to one external board (Linear / Jira / Trello / Notion). | project_id is NOT NULL & unique — one board per project, enforced in the schema. |
| Ticket | A work item; gets a display ref like PF-42. Synced from a board or created directly. | project_id is required; denormalized onto the ticket at create/sync time. |
| Repository | A GitHub repo record, carrying an architectural layer (UI / API / DATA / AI). | Attached to a project only by topic-label discovery — no manual link command. |
| Scope Document | Versioned requirements: deliverables, success criteria, assumptions, exclusions. | Versioned per project; one row flagged is_current. |
| Release | A version record with status planned → released. | Version unique per project; created by the release mechanism, not by board sync. |
How planning reaches your working directory
The centerpiece
This is the part that makes InnoDay more than a tracker. Planning artifacts — tickets, boards, scope — live server-side. But the developer works in a folder full of repositories on their own machine. InnoDay closes that gap with one small file and one resolution rule.
The file: when you onboard a workspace, InnoDay writes a .innoday/project.yml into it. It records exactly which org and project this directory represents — by stable UUID, not just a name — plus the repos that belong to the project and the release state that blastoff owns.
# written by the workspace onboarder — schema v2
schema_version: 2
org:
alias: hs
name: Haviland Software
innoday_id: 2e2ffce7-… # org UUID — the source of truth
github_org: havilandsoftware
project:
alias: pf
name: PixelFuel
innoday_id: e52b7372-… # project UUID
github_topic: pixelfuel # repos are discovered by this label
repos:
- name: pixelfuel-blastoff
- name: pixelfuel-website
release_configs: # blastoff version state, preserved on refresh
pf: { next_version: … , last_released_version: … }The rule: every tool — the CLI, the MCP server, the release tool — walks up from wherever you are until it finds a .innoday/project.yml. It reads the org and project UUIDs out of that file and uses them for every API call. That's the whole trick: launching Claude Code or running innoday from inside a project folder “just works” with zero flags.
Resolution precedence
- Explicit override for a single call — a
--projectflag or aproject_idargument. - The project.yml found by walking up from the current directory. (This is the normal path.)
- A last-used org cached on the machine — a fallback only.
There is deliberately no persistent “switch project” command. The current org/project is never written to shared machine config — it's resolved per-invocation from your directory. Two shells in two different projects never clobber each other.
What a developer actually does
Because context is ambient, the daily loop is short. Everything below resolves the project automatically from the folder you're standing in:
# you are in ~/workspaces/hs/pf — org & project auto-resolve $ innoday tickets list --status TODO $ innoday tickets update --ticket-id <id> --status IN_PROGRESS # …work in the repos project.yml lists, in a git worktree… $ innoday sync # pull board tickets + repo discovery + release state
The planning side (a ticket on a Linear board) and the doing side (a repo on your disk) are now two ends of the same thread — and the project.yml is the knot in the middle.
Agents and the MCP server
InnoDay ships as a Claude Code plugin as well as a CLI. The plugin bundles an MCP server and a set of agents that operate the platform on your behalf — all of them talking to the same REST API through the same cwd-resolved context.
Claude Code spawns the InnoDay MCP server locally (via uvx --from innoday mcp-server-innoday). It exposes the platform as 43 tools — create_ticket, sync_board, create_release, get_scrum_summary, and so on. Crucially, it holds no business logic: each tool is a thin HTTP call to the same REST API the CLI uses. Change a ticket by CLI or by agent — it's the same endpoint, the same record.
Keeps the board honest
Grooms and triages tickets, reconciles status against activity, and runs on a schedule to sweep stale, duplicate, and orphaned work items so the backlog stays trustworthy.
Org & project lifecycle
Sets up organizations and projects, connects boards and repositories, and runs the onboarding flow end to end.
Environment bring-up
Bootstraps a working InnoDay environment — configuration, identity, and the connections a new project needs.
Data & migrations
Handles database concerns behind the API — schema state, migrations, and integrity checks.
Architecture alignment
Reviews changes against the project's established patterns so new work fits the system it lands in.
Verification
Exercises the platform's lifecycle flows and surfaces regressions before they reach a human reviewer.
The Project Manager agent is the piece that makes “the board is the truth” sustainable: unattended, on a cadence, it does the tidying a human PM would otherwise do by hand — closing what's done, flagging what's drifted, and clearing what's orphaned.
How it’s all deployed
InnoDay itself is a FastAPI service running on Railway, backed by Supabase Postgres. Everything a developer runs locally — the CLI, the MCP server, blastoff — is a client of that one deployed API.
Two deploy paths coexist right now — the platform is mid-migration from source builds to signed images.
Railway builds from source
Railway's GitHub App is connected to the repo and builds the Dockerfile server-side on every push to main. No CI image step involved.
Signed image, pulled by Railway
GitHub Actions builds the image once, pushes it to both AWS ECR (private, scanned) and GHCR (public), signs it with Cosign, verifies the signature as a deploy gate, then triggers Railway to pull the public GHCR image.
The switch to the target path is a one-time manual step: repointing Railway's service source from the connected repo to the GHCR image. Railway pulls the public GHCR copy (not ECR) because that avoids the paid private-registry requirement; ECR remains the private, scan-on-push canonical copy, and Cosign signature verification — not secrecy — guarantees integrity.
Getting a developer connected
For most people this is a five-minute install against the shared dev environment. You are configuring a client — you are not standing up a server.
# 1 · install the CLI (the MCP server ships in the same package) $ uv tool install innoday # 2 · initialize identity against the shared dev API $ innoday init --default # defaults to https://innoday-dev.up.railway.app $ innoday orgs list # verify the connection # 3 · seed the team secret (the gotcha) — the dev API is gated; without a # matching X-Team-Secret header every non-public route returns 401 $ innoday config set team-secret "<the dev team secret>" # 4 · onboard a workspace, then context resolves from the folder — no flags $ cd ~/workspaces/hs/pf $ innoday tickets list
If the CLI works but the MCP tools return 401, the MCP server cached the pre-seed config at startup — reconnect it (/mcp reconnect) so it re-reads the seeded config. A purely local API has no team secret.
The two config files — don’t confuse them
| File | Scope | Holds |
|---|---|---|
| ~/.innoday/config.json | Your machine, all projects | Identity: default profile, API URL, your user id, the team secret, a cached org map. Never stores integration secrets — only pointers. The current org/project is never persisted here. |
| <workspace>/.innoday/project.yml | One workspace folder | Which project this is: org & project UUIDs, the GitHub topic, the repo list, and blastoff's release state. |
That's the whole model: one project-shaped record in the cloud, a small file that binds a folder to it, and a handful of clients — CLI, MCP, blastoff — that all resolve the same context from wherever you happen to be working.