mime-todo-spec/dist/markdown/README.md
Tiara Rodney b3aa59243a
new
2026-02-10 20:27:04 +01:00

292 lines
6.2 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

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:
```default
--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:
```default
MIME-Version: 1.0
Content-Type: multipart/mixed; boundary="ISSUE"
```
Each raw `--ISSUE` boundary becomes a MIME boundary. The preprocessor
extracts each parts `Content-Type` and body, reorders parts, and emits a
final closing boundary:
```default
--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:
```default
Sprints:
```
followed by one or more sprint entries.
### Sprint Entry Forms
Both compact and expanded forms are valid.
Compact form:
```default
- Name: Sprint 1
Range: 2026-02-01..2026-02-14
```
Expanded form:
```default
-
Name: Sprint 1
Range: 2026-02-01..2026-02-14
```
### Sprint Entry Grammar
A sprint entry begins at a line matching:
```default
^\s*-\s*(Name:.*)?$
```
Keyvalue lines inside an entry match:
```default
^\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:
```default
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:
```default
Relationships:
```
* Or list:
```default
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:
```default
<Type>/<ID>
```
Examples:
```default
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:
```default
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 parts `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:
```default
--ISSUE
Content-Type: <type>
<body>
```
* Final boundary:
```default
--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:
```default
{
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:
```default
application/<subtype>
```
Examples:
* `application/metadata`
* `application/changelog`
* `application/epilog`
The preprocessor MUST preserve unknown part types but MUST NOT reorder them.