new
This commit is contained in:
parent
77ec8a2be2
commit
b3aa59243a
13 changed files with 887 additions and 3 deletions
292
dist/markdown/README.md
vendored
Normal file
292
dist/markdown/README.md
vendored
Normal 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 part’s `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:.*)?$
|
||||
```
|
||||
|
||||
Key–value 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 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:
|
||||
```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.
|
||||
Loading…
Add table
Add a link
Reference in a new issue