| .. | ||
| AGENTS.md | ||
| LICENSE | ||
| README.md | ||
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 metadataapplication/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. *featureandbugfixissues target the integration branch (develop). *hotfixissues target the stable branch (mainormaster). -
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.
- Or list:
-
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
TODOMUST occur ondevelop. - 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
- All sprints where
S_start ≤ D ≤ S_end. - If multiple match, choose the one with the latest
S_start. - If none match, no active sprint.
Preprocessor Requirements
The preprocessor MUST:
-
Read the raw
TODOfile. -
Split into parts using
--ISSUE. -
Extract each part’s
Content-Typeand body. -
Reorder parts so that: *
application/sprintsappears first (if present) * Allapplication/issueparts 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--
- Final boundary:
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
TodoFileobject:{ sprints: Sprint[], issues: Issue[] }
Error Handling
The parser MUST reject:
- Missing or malformed
Content-Typeheaders - Unknown MIME types
- Missing required issue fields
- Incorrect field order
- Invalid sprint ranges
- Invalid date formats
- Multiple
application/sprintsparts - Duplicate issue IDs
Errors SHOULD include line numbers when possible.
Extensibility
Future part types MAY be added using:
application/<subtype>
Examples:
application/metadataapplication/changelogapplication/epilog
The preprocessor MUST preserve unknown part types but MUST NOT reorder them.