Issue Plan Tree
Plans live on disk as a tree of milestone folders and issue files that a planner reserves and syncs into Gitea, moving from slug-only drafts to ID-prefixed synced names.
- Kind
- Lifecycle
- Domain
- Documentation & Metadata
- Applies at
<root>/- Status
- Stable
- Source
docs/pdlc/ISSUES.md
01 Defines
A Markdown file tree for milestones and issues — its layout, naming, front matter, and dependencies — and the lifecycle by which gitea-planner turns draft items into reserved and synced Gitea milestones and issues.
02 Applies when
- Planning notes, roadmap text, or milestone outlines are being turned into trackable work.
- Milestones and issues should be reviewed as files before they exist remotely.
- A reusable template set of milestones and issues is maintained alongside live plans.
03 Boundaries
- Only
milestones/<folder>/andtasks/are recognised; no alternative folder names or extensions. - Remote-only values — milestone
id, issuenumber— are never invented locally. depends_onis the only dependency field;blocksorafterdo nothing.- Local-only metadata such as
issue_keynever reaches Gitea and can be lost when files are replaced from remote state.
Expected behaviour
- 01Each milestone folder holds exactly one
_milestone.mdand the issues that belong to it. - 02Names are slugs of titles; synced names gain a zero-padded four-digit ID or number prefix.
- 03An issue’s folder decides its milestone; issues without one live under
tasks/. - 04Every
depends_onentry is a realissue_keyor issue number, written as list items. - 05The body is plain Markdown that carries the meaning of the original plan on its own.
- 06Draft and synced modes are not mixed casually.
Behaviour#
A plan starts as files. gitea-planner reads the tree and mirrors it into
Gitea: reserve claims milestone IDs and issue numbers, and sync pushes
titles, states, labels, assignees, dates, bodies, and dependency edges. Two
things make a plan file good — it is structurally valid, or it will not sync,
and it is readable, because the body is what someone actually works from.
-
while planning
Draft
Slug-only names; no
idornumber;titleandstate: open - on `reserve` Reserved Gitea assigns milestone IDs and issue numbers
- on `sync` Synced Names carry the 4-digit prefix; front matter and edges are mirrored
-
on `pull`
Pulled
Remote state, including numeric
depends_on, is written back to disk
- Edit and re-syncSynced
A template set uses exactly the same layout as a live tree, in draft mode, so a reusable plan can be copied in and reserved like any other.
Layout#
- <root>/
- milestones/
- repository-health-baseline/ Synced: 0001-repository-health-baseline/
- _milestone.md title and state; id only once reserved
- ci-cd-workflow-validation.issue.md Synced: 0042-ci-cd-workflow-validation.issue.md
- tasks/ Issues with no milestone
- <slug>.issue.md
Names and dependencies#
Slugs lowercase the title, replace every non-alphanumeric character with -,
collapse repeats, and trim the ends: R&D / AI: phase 1 becomes
r-d-ai-phase-1. Keeping titles distinct keeps slugs stable.
Dependencies are depends_on list items naming local issue_key values,
issue numbers, or both, and they sync through Gitea’s native dependency API.
depends_on: a, b parses as one nonsense name. Priority is at most one
prio/p0–prio/p3 label, and an issue without one reads as prio/p2.
Examples#
---
number: 42
title: CI/CD workflow validation
state: open
issue_key: ci-cd-validation
depends_on:
- repo-bootstrap
- 41
labels:
- baseline
- prio/p1
assignees:
- aeydr
milestone: Repository Health Baseline
milestone_id: 1
due_date: 2026-05-14T23:59:59Z
template_id: baseline.cicd
---
A body that survives without the original plan usually has a Summary, Scope, Acceptance criteria, Definition of done, Out of scope, and Evidence. Headings can vary; compatibility depends on front matter and structure, not prose.
Connections