This commit is contained in:
Tiara Rodney 2026-02-10 20:27:04 +01:00
parent 77ec8a2be2
commit b3aa59243a
No known key found for this signature in database
GPG key ID: 5CD8EC1D46106723
13 changed files with 887 additions and 3 deletions

292
dist/markdown/README.md vendored Normal file
View file

@ -0,0 +1,292 @@
# 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.