LLM + Text Files + Obsidian Kanban in git: Practical project management for devs

9 min read Original article ↗

In soft­ware projects, you keep run­ning into the same issue. Plan­ning lives in one place, imple­men­ta­tion in anoth­er, and con­text gets lost between ses­sions. When an LLM became a reg­u­lar col­lab­o­ra­tor, I need­ed a shared way of work­ing. Some­thing both I and the AI could read, write, and nav­i­gate with­out extra tools or integrations.

The solu­tion I have cur­rent­ly end­ed up with: plain text files, Obsid­i­an Kan­ban, and Git.


LLMs work best when con­text is explic­it and easy to read. A Mark­down file in ver­sion con­trol is a per­fect shared for­mat. It is human-read­able, ver­sioned, link­able, and the LLM can read and write it direct­ly with­out any APIs or spe­cial formats.

Each project has two core files:

  • research.md is about under­stand­ing the sys­tem. It cap­tures what actu­al­ly exists in the code­base, where edge cas­es are, and what archi­tec­tur­al con­straints affect imple­men­ta­tion. The LLM reads source code, migra­tions, tests, and docs, then writes down its find­ings before any­thing is changed. This step is crit­i­cal. With­out it, plans are based on assump­tions, and assump­tions break quickly.
  • plan.md is the imple­men­ta­tion plan. It is struc­tured into phas­es, backed by check­lists, and updat­ed as work pro­gress­es. It is not a spec or a design doc. It is a prac­ti­cal roadmap that evolves as you go.

Research before implementation

Before plan­ning any­thing, the LLM goes through the rel­e­vant code in detail. The goal is not to explain the code, but to under­stand con­tracts, incon­sis­ten­cies, and risks.

In prac­tice, you give it a con­crete ques­tion or goal, for example:

what pre­vents deter­min­is­tic syn­chro­niza­tion between a C++ code­base and a Djan­go database”

It then goes through the code and finds real issues such as schema mis­match­es, miss­ing dis­crim­i­na­tors, or side effects in export log­ic. These are writ­ten into research.md as struc­tured find­ings, not vague summaries.

The result is a doc­u­ment that describes what actu­al­ly exists, not what we assume exists. It becomes the foun­da­tion for plan­ning and lat­er a ref­er­ence when val­i­dat­ing cor­rect­ness and regressions.


Planning and phasing

Once the tech­ni­cal pic­ture is clear, imple­men­ta­tion is bro­ken into phas­es inside plan.md.

A phase is a con­crete unit of work. It has a clear out­come, it can be val­i­dat­ed, and it does not depend on unfin­ished work unless necessary.

Each phase gets its own file:

  • 1.1 Fix writer schema compatibility.md
  • 1.2 Pure pay­load export.md

These files con­tain the details: tasks, depen­den­cies, val­i­da­tion steps, and open ques­tions. plan.md links to them but does not dupli­cate their con­tent. This keeps plan.md read­able at a high lev­el, while the details stay in sep­a­rate files. In lat­er ses­sions, the LLM can load just one phase instead of the entire project.


Turning into a kanban view

Obsid­i­an Kan­ban turns this file struc­ture into some­thing easy to nav­i­gate. Cards are just links:

  • Metapro­jects link to research.md and plan.md
  • Phas­es link to their own files

The columns are simple:

  • High-Lev­el Metapro­jects: over­all project view
  • Plan­ning LLM: phas­es ready to be implemented
  • In Progress: active work
  • Com­plet­ed: fin­ished work in ver­sion control

Since cards are just links, updat­ing the board is the same as updat­ing files. The Git log becomes the project timeline.


Win: Continuity between sessions

This set­up solves one of the biggest prob­lems in LLM-assist­ed devel­op­ment: los­ing con­text between sessions.

When start­ing a new ses­sion, the LLM reads plan.md and the cur­rent phase file. It imme­di­ate­ly sees what has been done, what is left, and what deci­sions have already been made. There is no need to re-explain anything.

Git acts as long-term mem­o­ry when chat his­to­ry is gone. Com­mit mes­sages nat­u­ral­ly reflect progress because the struc­ture encour­ages it.


Why it works

  • No extra tools Every­thing is Mark­down and Git. Obsid­i­an is just a way to view it.
  • LLM is used where it works best Read­ing code, find­ing incon­sis­ten­cies, and struc­tur­ing infor­ma­tion. Once the plan is clear, imple­men­ta­tion is straightforward.
  • You stay in con­trol The Kan­ban board shows the state at a glance. Phas­es keep work scoped. Check­lists define what done actu­al­ly means.
  • It scales well The same struc­ture works for small fix­es and large projects. Num­ber­ing (N for projects, N.M for phas­es) keeps every­thing con­sis­tent as it grows.

How the Kanban board actually works

At this point, the Kan­ban board is not a sep­a­rate sys­tem. It is just a view into the same files.

There is one board, stored as obsid­i­an obsidian/[project]/devkanban.md in git. It is not regen­er­at­ed or replaced. It evolves as the repos­i­to­ry evolves. Updat­ing the board is the same as updat­ing the under­ly­ing Mark­down files. Of course there may be anoth­er kan­ban board for e.g. high­er lev­el project or busi­ness vision.

Each project appears once as a metapro­ject card. The nam­ing is sim­ple and con­sis­tent: N. Project Title. That num­ber is not cos­met­ic. It becomes the anchor for every­thing else. From that one card, you can jump straight into the project’s Research.md and Planning.md.

Projects can start as messy fold­ers or sin­gle files, but they all end up in the same shape. One research doc­u­ment that explains what is actu­al­ly going on, and one plan­ning doc­u­ment that defines what should hap­pen next. The struc­ture of the repos­i­to­ry is pre­served, but the nam­ing becomes explic­it so you can nav­i­gate it with­out guessing.

The real work, though, does not live at the project lev­el. It lives in phases.

Every action­able piece of work inside Planning.md is pulled out into its own unit. Each one gets a num­ber like N.M, a clear title, and its own file. The Kan­ban card links to that file, and the plan­ning doc­u­ment links to it as well. Instead of scrolling through a long plan, you jump direct­ly into the exact slice of work you care about.

Those phase files car­ry the weight of exe­cu­tion. They con­tain the check­list, the depen­den­cies, the val­i­da­tion steps, and what­ev­er open ques­tions still exist. The main plan stays read­able because it stops try­ing to hold all the details at once.

Not every­thing becomes a phase. Only work that can actu­al­ly be exe­cut­ed and ver­i­fied makes the cut. Gen­er­al notes, process instruc­tions, or vague ideas stay in the plan. The board reflects real work, not intent.

The sys­tem can also con­tain small­er TODO items. If some­thing is wait­ing to be done, it shows up in the plan­ning col­umn like every­thing else. If it turns into a con­crete phase, it gets a num­ber and a plan­ning file. If it is already done, it skips straight to com­plet­ed. The sys­tem does not care where some­thing came from, only what state it is in now.

Com­ple­tion is equal­ly straight­for­ward. When the check­list is done, or the work has clear­ly been imple­ment­ed and val­i­dat­ed, the card moves to Com­plet­ed. It does not stay dupli­cat­ed in mul­ti­ple places. The board shows the cur­rent truth, not history.

Under­neath all of this is a small set of con­straints that keep things from drift­ing. Projects have a sin­gle index. Phas­es derive from that index. Cards always point to real files. Files link back to their con­text when need­ed. Con­tent is moved rather than copied, so there is only ever one source of truth.

What you end up with is not a Kan­ban tool in the tra­di­tion­al sense. It is a thin lay­er over your repos­i­to­ry. The board shows you where things stand, the plan­ning files explain what should hap­pen, the phase files define what you are actu­al­ly doing.

All of it lives in the same place, changes togeth­er, and can be under­stood by both you and the LLM with­out translation.

Skill

You can add this to your SKILLS.md file:

---
name: obsidian-plan
description: Create or update Obsidian planning, research, and kanban entries for a new project or feature in obsidian/project/. Creates the top-level project entry, Research.md, Planning.md, and individual phase cards, then wires all links into Dev planning.md kanban board.
argument-hint: [project-number] [project-name] [brief-description]
---

You are creating or updating Obsidian planning documents for a new project or feature in this repo.

The Obsidian vault is at `obsidian/project/`. The kanban board is at `obsidian/project/Dev planning.md`.
All phase cards and top-level planning/research files live under `obsidian/project/LLM planning/`.

## Arguments

$ARGUMENTS

If a project number, name, and brief description are provided, use them.
If no arguments are given, ask the user what the project is about before proceeding.

## What to produce

### 1. Top-level kanban entry in `obsidian/project/Dev planning.md`

Add to the `## High-level metaprojectss` section (keep numeric order):
```
- [ ] NN. Project Name ([[NN. Project Name/Research|Research]] · [[NN. Project Name/Planning|Planning]])
```

### 2. Project folder and files

Create `obsidian/project/LLM planning/NN. Project Name/` with:

**Research.md** — frontmatter: `project`, `status: research complete`. Content:
- Problem statement / context
- Key architectural decisions and trade-offs
- Relevant existing code / systems involved
- Limitations and open questions

**Planning.md** — frontmatter: `project`, `status: planned`. Content:
- Goal paragraph
- `## Phases` section listing all phase cards as `- ⬜ [[NN. Project Name/NN.X Project Name — Phase Title|NN.X Phase Title]] — one-line description`
- Design principles (numbered list)
- Non-goals

### 3. Phase cards

One file per phase: `obsidian/project/LLM planning/NN. Project Name/NN.X Project Name — Phase Title.md`

Phase cards live **inside** the numbered project directory, not loose in `LLM planning/`.

Each card frontmatter:
```yaml
---
phase: "NN.X"
project: "NN. Project Name"
status: pending
---
```

Each card body:
- `# NN.X Project Name — Phase Title`
- Back-links: `Kanban: [[Dev planning]]` and `Planning: [[NN. Project Name/Planning]]`
- `## Goal` — one paragraph
- `## Context` — why this phase exists, what it depends on
- `## Files` — relevant files to create or modify (with paths)
- `## Tasks` — numbered implementation steps
- `## Done Criteria` — bullet list of verifiable exit conditions

### 4. Phase sub-tasks in kanban

Add to `obsidian/project/Dev planning.md` under `## planning LLM`, in numeric order after any existing entries for the same project:
```
- [ ] NN.X Project Name — Phase Title ([[NN.X Project Name — Phase Title]])
```

## Conventions to follow

- Phase cards live inside `NN. Project Name/` subdirectory, not loose in `LLM planning/`
- Links to Research/Planning use path: `[[NN. Project Name/Research|Research]]`
- Phase card links in Planning.md use path: `[[NN. Project Name/NN.X ...|display name]]`
- Kanban phase sub-task links use short `[[NN.X ...]]` — unique filename resolves correctly
- Phase card filenames use em-dash ` — ` between project name fragment and phase title
- `status` in frontmatter: `pending` for not started, `in progress`, `done`
- Number phases from 0; use 0 for any prerequisite/foundation phase
- Deferred or optional phases get `status: deferred` and a note explaining the condition
- Keep phase descriptions in Planning.md to one line; detail lives in the phase card

## After creating files

Confirm what was created and offer to commit with an appropriate message.