This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
############
Introduction
############
This document defines the canonical format, semantics, and processing rules
for the repository-root ``TODO`` file. The file is a human-friendly,
append-only (allowing modifications) issue tracker that is parsed by TypeScript tooling using a MIME
envelope added at parse time.
The raw ``TODO`` file is not a MIME document. A preprocessor wraps it into a
valid ``multipart/mixed`` MIME message before parsing.
Raw File Structure
==================
The raw ``TODO`` file consists of a sequence of *parts*, each beginning with::
--ISSUE
Content-Type: <mime-type>
Valid part types are:
* ``application/sprints`` — defines sprint metadata
* ``application/issue`` — defines a single issue
Parts may appear in any order in the raw file. The preprocessor will reorder
them so that the ``application/sprints`` part appears first.
MIME Envelope (Added by Preprocessor)
=====================================
Before parsing, the preprocessor wraps the raw file into a MIME multipart
message.
Prolog added by the preprocessor::
MIME-Version: 1.0
Content-Type: multipart/mixed; boundary="ISSUE"
Each raw ``--ISSUE`` boundary becomes a MIME boundary. The preprocessor
extracts each part's ``Content-Type`` and body, reorders parts, and emits a
final closing boundary::
--ISSUE--
The resulting MIME message is parsed using a standard MIME parser.
Part: ``application/sprints``
=============================
This part defines sprint metadata.
The body MUST begin with::
Sprints:
followed by one or more sprint entries.
Sprint Entry Forms
------------------
Both compact and expanded forms are valid.
Compact form::
- Name: Sprint 1
Range: 2026-02-01..2026-02-14
Expanded form::
-
Name: Sprint 1
Range: 2026-02-01..2026-02-14
Sprint Entry Grammar
--------------------
A sprint entry begins at a line matching::
^\s*-\s*(Name:.*)?$
Key–value lines inside an entry match::
^\s+[A-Za-z][A-Za-z0-9]*:\s*(.*)$
Required keys:
* ``Name: <string>``
* ``Range: <YYYY-MM-DD>..<YYYY-MM-DD>``
The ``Range`` defines a closed interval ``[start, end]``.
Part: ``application/issue``
===========================
Each issue is represented as a structured block with strict field ordering.
Required Field Order
--------------------
The following fields MUST appear in exactly this order::
ID: <integer>
Type: <feature|bugfix|hotfix>
Title: <short title>
Status: <open|in-progress|done|hold|cancelled>
Priority: <low|medium|high>
Created: <YYYY-MM-DD>
Relationships: <comma-separated list or empty>
DueStart: <YYYY-MM-DD> # OPTIONAL
DueEnd: <YYYY-MM-DD> # OPTIONAL
Description: <first line>
<continuation lines>
Field Semantics
---------------
* **ID**: unique integer, strictly increasing.
* **Type**: one of ``feature``, ``bugfix``, ``hotfix``.
* ``feature`` and ``bugfix`` issues target the integration branch (``develop``).
* ``hotfix`` issues target the stable branch (``main`` or ``master``).
* **Status**: one of ``open``, ``in-progress``, ``done``, ``hold``, ``cancelled``.
* **Priority**: one of ``low``, ``medium``, ``high``.
* **Created**: ISO date.
* **Relationships**:
* Empty::
Relationships:
* Or list::
Relationships: dependsOn:43, relatesTo:10
* Valid kinds: ``dependsOn``, ``relatesTo``, ``blocks``, ``causedBy``.
* **DueStart / DueEnd**:
* Optional.
* If only one is present, the other is implicitly equal to it.
Description Block
-----------------
* The first line appears on the same line as ``Description:``.
* Continuation lines:
* Must begin with whitespace.
* Must align indentation consistently.
* No blank lines allowed inside the description block.
Body
----
Any lines after the description block are considered free-form body text.
The body MUST NOT contain another ``ID:`` field or a MIME boundary.
Git Workflow Rules
==================
Branch Naming
-------------
Branches for issues MUST follow::
<Type>/<ID>
Examples::
feature/12
bugfix/7
Modification Rules
------------------
* All edits to ``TODO`` MUST occur on ``develop``.
* Feature/bugfix/hotfix branches MUST rebase changes from ``develop``.
Branch Lifecycle
----------------
* A branch MUST NOT exist before its issue is created.
* A branch MUST be named exactly ``<Type>/<ID>``.
* A branch MAY merge only when the issue status is ``done``.
Sprint Membership Logic
=======================
Given:
* Sprint interval ``[S_start, S_end]``
* Issue interval ``[I_start, I_end]``
Normalization
-------------
* Only ``DueEnd`` → ``I_start = I_end = DueEnd``
* Only ``DueStart`` → ``I_start = I_end = DueStart``
* Neither → issue is not sprint-bound
Membership Condition
--------------------
An issue belongs to a sprint if::
I_start ≤ S_end AND I_end ≥ S_start
Current Sprint for Date D
-------------------------
1. All sprints where ``S_start ≤ D ≤ S_end``.
2. If multiple match, choose the one with the latest ``S_start``.
3. If none match, no active sprint.
Preprocessor Requirements
=========================
The preprocessor MUST:
* Read the raw ``TODO`` file.
* Split into parts using ``--ISSUE``.
* Extract each part's ``Content-Type`` and body.
* Reorder parts so that:
* ``application/sprints`` appears first (if present)
* All ``application/issue`` parts follow in original order
* Emit a MIME message with:
* ``MIME-Version: 1.0``
* ``Content-Type: multipart/mixed; boundary="ISSUE"``
* Each part wrapped as::
--ISSUE
Content-Type: <type>
<body>
* Final boundary::
--ISSUE--
Parser Requirements
===================
The parser MUST:
* Use a MIME parser to extract parts.
* Dispatch based on ``Content-Type``:
* ``application/sprints`` → sprint parser
* ``application/issue`` → issue parser
* Enforce:
* Field order
* Required fields
* Description indentation rules
* Sprint entry grammar
* Produce a ``TodoFile`` object::
{
sprints: Sprint[],
issues: Issue[]
}
Error Handling
==============
The parser MUST reject:
* Missing or malformed ``Content-Type`` headers
* Unknown MIME types
* Missing required issue fields
* Incorrect field order
* Invalid sprint ranges
* Invalid date formats
* Multiple ``application/sprints`` parts
* Duplicate issue IDs
Errors SHOULD include line numbers when possible.
Extensibility
=============
Future part types MAY be added using::
application/<subtype>
Examples:
* ``application/metadata``
* ``application/changelog``
* ``application/epilog``
The preprocessor MUST preserve unknown part types but MUST NOT reorder them.