# KickflipOS — an operating system for solo client work, built on Claude + GitHub

*A shareable blueprint. Load this file into Claude and use the companion prompt to build your own version.*

---

## The problem this solves

If you're a freelancer or solo consultant working across several clients, your context lives everywhere: call notes in one tool, email threads in another, decisions buried in chat histories, deliverables scattered across folders. AI assistants make this worse before they make it better — every new chat starts from zero, and two concurrent sessions can silently overwrite each other's work.

KickflipOS is a set of conventions, skills, and light automation that turns Claude + GitHub into a client operating system:

- **Every client has a durable, versioned memory** that any Claude session can read and write safely
- **Multiple sessions can run concurrently** — across days, devices, and chats — without conflicts, duplicates, or lost work
- **Context lookups are cheap**: sessions read a generated index first, then only the files they need
- **Your task board maintains itself**: issues are created labelled, land on the board automatically, and get progress comments when you finish work
- **Everything is backed up daily** with one command, even half-finished work

## Core principles

**1. GitHub is the source of truth; your local folder is a working space.**
All durable state lives in private GitHub repos. Your local project folder is where you actively work — never the authority on what's true.

**2. One context repo per client; one repo per deliverable.**
Each client gets a private "context repo" holding their memory. Each substantial build (a pipeline, a dashboard, a site) gets its own repo, kept out of the context repo entirely.

**3. Two zones, two owners.**
*Context files* (call logs, decisions, contacts, the index) are machine-written: only your skills write them, via the GitHub API, so local copies can always be safely refreshed from remote. *Working files* (drafts, analyses, WIP) are yours: no automation ever overwrites them; they're backed up upward when you say so. This one split eliminates almost every sync conflict.

**4. All writes go through the authenticated GitHub connector — never local git.**
Sandboxed AI sessions have no git credentials, and you should never store tokens in plaintext to work around that. The GitHub MCP connector is already authenticated in every session, and its API has a property local git can't match here: every file update is SHA-checked. A session must fetch the file *immediately before* editing and pass the current version's SHA with the write — if another session changed the file in between, the write fails loudly instead of silently clobbering. Multi-file changes go up as one atomic commit. That's the entire concurrency story: fetch fresh, write checked, commit atomically.

**5. Generate what you'd otherwise maintain.**
The busiest file in any context repo is the index — a summary of every logged item, touched by every workflow. Hand-maintained, it's a merge-conflict magnet. So nothing maintains it: a small GitHub Action rebuilds it from the context files on every push. Hot files should be nobody's job.

**6. Skills encode the workflows, so every session behaves identically.**
The rules above only work if every session follows them. Claude skills (reusable instruction sets) make that automatic — you invoke `/client-sync` and the session follows the same protocol every time, in any chat, on any day.

**7. Conventions do the heavy lifting.**
Predictable filenames, commit message formats, and a per-client control file mean sessions can find, dedupe, and route everything without asking you.

---

## The blueprint

### Per-client project structure

```
<client-project>/
├── CLAUDE.md                  # the control file (see below)
├── .claude-sync.json          # local refresh state (machine-managed)
├── context/                   # ZONE 1 — machine-written, remote-authoritative
│   ├── _index.md              # AUTO-GENERATED summary of everything below
│   ├── calls/                 # YYYY-MM-DD_Short-description.md
│   ├── emails/                # YYYY-MM-DD_Subject_[thread-id].md
│   ├── messages/              # YYYY-MM-DD_Channel_Topic.md
│   ├── docs/                  # YYYY-MM-DD_Doc-title.md
│   ├── contracts/             # YYYY-MM-DD_Contract-description.md
│   ├── contacts.md            # who's who
│   ├── commercial.md          # fees, invoices, terms
│   ├── business.md            # what the client's business is/does
│   ├── <domain>.md            # your discipline's live state (e.g. marketing.md, tech-stack.md)
│   └── deliverables.md        # registry of builds and their repos
└── delivery/                  # ZONE 2 — yours, local-authoritative
    ├── <workstream>/          # working files, drafts, analyses
    │   └── <repo-clone>/      # a deliverable's own git repo, nested inside
    └── ...
```

Each item logged (a call, an email thread, a document) is one file with a consistent template: a heading, metadata lines, a `## Summary` section, key decisions, and action items. The templates matter — the index generator and every future lookup rely on them.

### The control file: CLAUDE.md

Every client project's `CLAUDE.md` holds three things — the client brief (who they are, what the engagement is), the **repos map**, and the **rules block**. Claude reads this automatically at session start, so it's where the whole system's behaviour is pinned down:

```markdown
## Repos

context_repo: <you>/<client>-context
client_label: <client-slug>              # the machine-readable client marker for issues

deliverables:
  delivery/pipeline/<client>-pipeline:   # exact clone path, never a parent folder
    repo: <you>/<client>-pipeline
    sync: mcp                            # or git — managed by native tooling; hands off

<!-- Rules:
- This folder is a PLAIN working folder for the context repo — never run git commands in it.
  Deliverable folders listed above ARE real git clones.
- Two zones: context files (context/**, CLAUDE.md, .github/**) are remote-authoritative —
  written only via the GitHub connector by skills, brought down locally by refresh.
  Everything else is the working zone — backed up upward by sync, never overwritten by refresh.
- At session start (and after long gaps), refresh so local context is current. Then: read
  context/_index.md to find relevant files and read only those — never scan the whole folder.
- All context writes go to context_repo only, via the GitHub connector with SHA-checked
  updates, written through to local files at the same time.
- context/_index.md is auto-generated; never edit it by hand.
- In long conversations, re-read files before acting on them — never trust content read
  earlier in the chat. -->
```

### The five skills

Each is a Claude skill — a markdown instruction file — encoding one workflow. Names are illustrative; the jobs are what matter:

**`client-context` — log inbound context.** "Log that call." Fetches the source (meeting transcription tool, email, chat, document), formats it to the template, saves it to the right `context/` folder — after checking the *remote* repo for a duplicate, in case another session already logged it. Then a side-effect scan: does this call mention a new contact, a fee change, a tool swap? Update the relevant living files in the same atomic commit. Finally, comment on any related board issues and offer to create issues for net-new tasks.

**`client-quick-context` — single-fact updates.** "Quick add: Sarah's new number is…" One fact, one file, one SHA-checked commit. No scanning, no ceremony. Exists as a separate skill so a one-line change never triggers the full logging process.

**`client-sync` — end-of-session backup and audit.** "Wrap up." Diffs the working folder against every mapped repo, shows you the plan (files per repo, anything unroutable, any context-zone conflicts), and on confirmation pushes one atomic commit per repo. Comments progress on related issues; offers issues for unmatched work. Run it daily even mid-WIP — these are private backup repos; work-in-progress commits are the point. A `check` mode does the full audit and pushes nothing.

**`client-refresh` — bring context down.** Run at session start. One API call lists commits since the last refresh; only changed context files are downloaded. Your working zone is never touched. This is what makes the local index a fast, free lookup rather than a staleness risk.

**`client-new-project-repo` — spin up a deliverable.** Creates the repo, registers it in the repos map / deliverables registry / .gitignore in one commit, clones it into a folder you confirm (the exact clone path is mapped — never a parent, so sibling working notes still route to the context repo), and optionally opens a tracking issue. Deliverables that use git-native tooling get `sync: git` — the sync skill reports on them but never pushes to them.

### The index

A GitHub Action in each context repo rebuilds `context/_index.md` on every push that touches `context/**`. It walks the folders, pulls each file's date and title from the filename convention and the first two sentences of its `## Summary` (falling back to the first prose paragraph for older, unstructured notes), and writes a reverse-chronological digest with links. Sessions read this ~1-page file first and then open only the two or three files that matter — instead of scanning an entire folder of transcripts every time. Cheap lookups are what make per-client memory actually usable.

### The task board

One private issues repo for all clients, fronted by a GitHub Projects board with a **Client** custom field.

The API can create and label issues, but it *cannot* add them to a Projects board or set custom fields (those need GraphQL, beyond most connectors). The fix is a relay:

1. **Skills apply a client label at creation** — resolved from `client_label` in CLAUDE.md, never guessed; applied in the creation call itself and verified afterwards. Mandatory, no exceptions: the label is the machine-readable marker everything else keys off.
2. **The board's built-in "Auto-add to project" workflow** sweeps every new issue onto the board.
3. **A small GitHub Action** (issues events + nightly, using a Projects-scoped token stored as an encrypted Actions secret) copies the label into the Client field — matching by name, only ever filling empty fields, never overwriting what you set by hand.

Issue conventions: only create issues for *your* tasks (not the client's or third parties'); group related tasks into one issue; standard body of Context / Tasks / References linking back to the context file that spawned it.

### Concurrency, spelled out

Why can you run three chats against one client for a week without chaos?

- Every write fetches fresh and passes a SHA → stale writes fail loudly, then retry on current content
- Every logging run dedupe-checks the remote first → two sessions can't log the same call twice
- Multi-file changes are one atomic commit → no half-applied state for another session to trip over
- The index has exactly one writer (the Action) → the hottest file can't conflict
- Long-conversation rule: re-read files before acting on them → a two-week-old chat never acts on two-week-old memory

The write path is stateless per operation, so session age is irrelevant. Fresh chats are a performance choice, not a safety requirement.

---

## The daily rhythm

1. **Open a client session → refresh.** Local context catches up on whatever other sessions logged.
2. **Work.** Your working zone, your rules.
3. **Log as you go.** Call ends → "log that call". Small fact → "quick add". Thirty seconds each.
4. **End of day → sync.** Review the plan, confirm, done: work backed up, board updated.
5. **Occasionally → sync check.** A no-push audit confirming local and GitHub agree everywhere.

## Lessons learned building this

- **Design for your most constrained environment.** Sandboxed AI sessions can't run git and shouldn't hold credentials. Building API-first from the start beats bolting on workarounds (we tried; every workaround was worse).
- **Never store tokens in plaintext** — not in git config, not in dotfiles, no matter how scoped. The two acceptable places for credentials here: the already-authenticated connector, and encrypted CI secrets.
- **Generate, don't maintain.** Anything derivable from other files (indexes, registries, digests) should be built by automation, not kept current by discipline.
- **Split by authority, not by topic.** "Who is allowed to write this file?" is the question that dissolves sync conflicts. Machine-written files can be freshly overwritten; human files must never be.
- **Make the marker mandatory at creation.** Anything applied "afterwards" (labels, fields, links) eventually gets skipped. Put it in the creation call and verify it stuck.
- **Never hand-copy what sync should move.** If content needs to travel between local and remote, it goes through the one sanctioned mechanism — shadow copies create the very conflicts the system exists to prevent.
- **Put the rules where the AI already looks.** Conventions live in each project's CLAUDE.md, so every session — new chat, new device, months later — behaves identically without being told.

## Adapting it

Swap the pieces, keep the shape: your transcription tool, email, and chat connectors feed `client-context`; your discipline's living file replaces `<domain>.md`; your task tool of choice replaces the Projects board (the relay pattern — machine marker at creation + automation that mirrors it — transfers to most tools). Start with **one pilot client**, run the rhythm for a fortnight, then migrate the rest with a repeatable prompt.

The companion prompt walks Claude through building your version: interviewing you about your tools and clients, then generating the repos, control files, skills, and automations to fit.
