From 0fbbe84bb382ea0bb5194d411d8cd1d4f3769439 Mon Sep 17 00:00:00 2001 From: Tiara Rodney Date: Sun, 15 Mar 2026 03:39:06 +0100 Subject: [PATCH] update --- AGENTS.md | 57 +++- dist/doctrees/AGENTS.doctree | Bin 31017 -> 53580 bytes dist/doctrees/README.doctree | Bin 44309 -> 112821 bytes dist/doctrees/environment.pickle | Bin 28086 -> 37074 bytes dist/markdown/AGENTS.md | 57 +++- dist/markdown/README.md | 432 +++++++++++++++++++++++++++++-- src/README.rst | 427 ++++++++++++++++++++++++++++-- 7 files changed, 940 insertions(+), 33 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index 475d30b..7a99c72 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -28,11 +28,66 @@ If `dist/markdown/` is not available locally, the specification - Issue part format (`application/issue`): field ordering, field semantics, valid values for Type, Status, Priority, and Relationships - Sprint part format (`application/sprints`): entry grammar, date ranges -- Description block and body grammar +- Module part format (`application/modules`): module names and paths +- Bugzilla tracker part format (`application/bugzilla`): product/component + mappings, sync model, comment format +- Description block and body grammar (80-column wrap, column 14 indent) +- Issue immutability rules +- Status transition state machine and commit conventions - Branch naming and lifecycle rules tied to issue Type and Status - Sprint membership logic - Preprocessor and parser requirements - Error handling requirements +- CLI reference for spec-compliant issue management + +## Interacting with the TODO File + +Agents MUST use the `@byteb4rb1e/mime-todo` CLI for all interactions +with the `TODO` file. Do NOT edit the file directly or construct +transition commits manually. + +### Issue Lifecycle + +```sh +# Create an issue (must be on develop) +todo create --type feature --title "Title" --plan "Description" + +# Start work (must be on develop) +todo start --plan "Planned approach" +# Then create the branch: git checkout -b / + +# Complete work (must be on /) +todo done --summary "What was delivered" + +# Hold or cancel +todo hold --reason "Why" +todo cancel --reason "Why" +``` + +### Querying + +```sh +todo list # list all issues +todo show # show issue details +todo sprints # list sprints +todo issues-in-sprint # issues in a sprint +``` + +### Bugzilla Integration + +```sh +todo init # check products/components exist +todo push # push commits to Bugzilla +todo push --dry-run # preview +``` + +### What Agents MUST NOT Do + +- Edit the `TODO` file directly. +- Construct `todo(): ` commits manually. +- Modify issue fields other than `Status` (and only via the CLI). +- Push to Bugzilla outside of `todo push`. +- Modify the specification files. ## Rules for Agents diff --git a/dist/doctrees/AGENTS.doctree b/dist/doctrees/AGENTS.doctree index dec042ee158190a9b5387d331040005bacfb7f5d..86dc549e23d113104a0bce000b421b048d250ed8 100644 GIT binary patch literal 53580 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 YW-+Hsl6o(c=|F(CAZX3d9v}Jt0aXNGJpcdz delta 8090 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 diff --git a/dist/doctrees/environment.pickle b/dist/doctrees/environment.pickle index df258b0f10ae2fb61150cb24ce960a5a3b5be0a6..449954cbb04d834ccf921d2f2565e5c00c4dc04e 100644 GIT binary patch literal 37074 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 diff --git a/dist/markdown/AGENTS.md b/dist/markdown/AGENTS.md index e3e2e27..f5c827f 100644 --- a/dist/markdown/AGENTS.md +++ b/dist/markdown/AGENTS.md @@ -28,11 +28,66 @@ If `dist/markdown/` is not available locally, the specification - Issue part format (`application/issue`): field ordering, field semantics, valid values for Type, Status, Priority, and Relationships - Sprint part format (`application/sprints`): entry grammar, date ranges -- Description block and body grammar +- Module part format (`application/modules`): module names and paths +- Bugzilla tracker part format (`application/bugzilla`): product/component + mappings, sync model, comment format +- Description block and body grammar (80-column wrap, column 14 indent) +- Issue immutability rules +- Status transition state machine and commit conventions - Branch naming and lifecycle rules tied to issue Type and Status - Sprint membership logic - Preprocessor and parser requirements - Error handling requirements +- CLI reference for spec-compliant issue management + +## Interacting with the TODO File + +Agents MUST use the `@byteb4rb1e/mime-todo` CLI for all interactions +with the `TODO` file. Do NOT edit the file directly or construct +transition commits manually. + +### Issue Lifecycle + +```sh +# Create an issue (must be on develop) +todo create --type feature --title "Title" --plan "Description" + +# Start work (must be on develop) +todo start --plan "Planned approach" +# Then create the branch: git checkout -b / + +# Complete work (must be on /) +todo done --summary "What was delivered" + +# Hold or cancel +todo hold --reason "Why" +todo cancel --reason "Why" +``` + +### Querying + +```sh +todo list # list all issues +todo show # show issue details +todo sprints # list sprints +todo issues-in-sprint # issues in a sprint +``` + +### Bugzilla Integration + +```sh +todo init # check products/components exist +todo push # push commits to Bugzilla +todo push --dry-run # preview +``` + +### What Agents MUST NOT Do + +- Edit the `TODO` file directly. +- Construct `todo(): ` commits manually. +- Modify issue fields other than `Status` (and only via the CLI). +- Push to Bugzilla outside of `todo push`. +- Modify the specification files. ## Rules for Agents diff --git a/dist/markdown/README.md b/dist/markdown/README.md index cf57e27..1d324f4 100644 --- a/dist/markdown/README.md +++ b/dist/markdown/README.md @@ -20,10 +20,14 @@ Content-Type: Valid part types are: * `application/sprints` — defines sprint metadata +* `application/modules` — defines the repository module structure +* `application/bugzilla` — defines Bugzilla product/component mappings * `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. +them so that `application/sprints` appears first, followed by +`application/modules`, then `application/bugzilla`, then all +`application/issue` parts in original order. ## MIME Envelope (Added by Preprocessor) @@ -99,6 +103,155 @@ Required keys: The `Range` defines a closed interval `[start, end]`. +## Part: `application/modules` + +This part defines the repository’s logical module structure. Each module maps +a name to an optional repository-relative path. + +At most one `application/modules` part MAY appear. Multiple +`application/modules` parts MUST be rejected. + +The body MUST begin with: + +```default +Modules: +``` + +followed by one or more module entries. + +### Module Entry Forms + +Compact form: + +```default +- Name: Specification + Path: src +``` + +Expanded form: + +```default +- + Name: Specification + Path: src +``` + +A module without a path (logical grouping): + +```default +- Name: Documentation +``` + +### Module Entry Grammar + +A module 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: ` — unique module identifier. + +Optional keys: + +* `Path: ` — path relative to repository root. + If omitted, the module is a logical grouping without a fixed location. + +## Part: `application/bugzilla` + +This part defines a unidirectional mapping from repository modules to +Bugzilla products and components. The `TODO` file is the source of truth; +Bugzilla is a downstream mirror. + +At most one `application/bugzilla` part MAY appear. Multiple +`application/bugzilla` parts MUST be rejected. + +An `application/bugzilla` part MUST NOT appear unless an +`application/modules` part is also present. + +### Required Fields + +```default +URL: +Mappings: + - Module: + Product: + Component: +``` + +* **URL**: the base URL to the Bugzilla REST API. +* **Mappings**: one or more entries mapping a module name to a Bugzilla + product and component. Every `Module` value MUST reference a module + defined in the `application/modules` part. + +Product and component names containing spaces or special characters are +permitted; tooling MUST URL-encode them when constructing API requests. + +### Mapping Entry Grammar + +A mapping entry begins at a line matching: + +```default +^\s*-\s*(Module:.*)?$ +``` + +Required keys: + +* `Module: ` — references a module name. +* `Product: ` — Bugzilla product name. +* `Component: ` — Bugzilla component name. + +### Sync Model + +Synchronization is unidirectional: `TODO` → Bugzilla. The `TODO` file is +the canonical source of truth. + +When a Bugzilla bug is created for a `TODO` issue, the bug’s `url` field +MUST be set to a resolvable URL pointing to the `TODO` file on the +integration branch. The URL format is host-dependent: + +* Bitbucket: `/src//TODO#` +* GitHub: `/blob//TODO#` +* GitLab: `/-/blob//TODO#` + +The branch in the URL MUST be the integration branch (`develop`), +regardless of which branch the push is initiated from. + +Transition commit messages are pushed as Bugzilla comments. Each comment is +tagged with `git-` (first 7 characters of the commit hash) to +prevent duplicate pushes. A comment tag is applied only after the comment +and any associated status update have both succeeded. + +Work commits from issue branches are also pushed as Bugzilla comments, +forming a threaded work log. Work comments: + +* MUST NOT be pushed unless the issue status is `in-progress`. +* MUST NOT follow a `done` transition comment. + +Comment format (Markdown): + +```default +**** + + + +[``]() +``` + +The commit URL format is host-dependent: + +* Bitbucket: `/commits/` +* GitHub: `/commit/` +* GitLab: `/-/commit/` + ## Part: `application/issue` Each issue is represented as a structured block with strict field ordering. @@ -114,9 +267,10 @@ Title: Status: Priority: Created: +Module: # OPTIONAL Relationships: -DueStart: # OPTIONAL -DueEnd: # OPTIONAL +DueStart: # OPTIONAL +DueEnd: # OPTIONAL Description: ``` @@ -130,6 +284,9 @@ Description: * **Status**: one of `open`, `in-progress`, `done`, `hold`, `cancelled`. * **Priority**: one of `low`, `medium`, `high`. * **Created**: ISO date. +* **Module**: optional. When present, MUST reference a module name defined in + the `application/modules` part. If no `application/modules` part exists, + the field is ignored. * **Relationships**: \* Empty: ```default @@ -140,7 +297,11 @@ Description: ```default Relationships: dependsOn:43, relatesTo:10 ``` - * Valid kinds: `dependsOn`, `relatesTo`, `blocks`, `causedBy`. + * Valid kinds: `dependsOn`, `relatesTo`, `blocks`. + * All relationship target IDs MUST reference existing issue IDs in the + same `TODO` file. A target that does not exist MUST be rejected. + * A relationship targeting a `cancelled` issue SHOULD produce a warning + (stale reference). * **DueStart / DueEnd**: \* Optional. \* If only one is present, the other is implicitly equal to it. @@ -148,9 +309,10 @@ Description: ### Description Block * The first line appears on the same line as `Description:`. -* Continuation lines: - \* Must begin with whitespace. - \* Must align indentation consistently. +* `Description:` occupies 13 characters. Content begins at column 14. +* Continuation lines MUST be indented with 13 spaces, aligning with column 14. +* Lines MUST NOT exceed 80 columns. Long text MUST be word-wrapped at the + 80-column boundary by the serializer. * No blank lines allowed inside the description block. ### Body @@ -158,6 +320,20 @@ Description: Any lines after the description block are considered free-form body text. The body MUST NOT contain another `ID:` field or a MIME boundary. +### Issue Immutability + +The `Description` field is immutable after the issue is created. To change +the scope of an issue, the issue MUST be cancelled and a new issue created. + +Fields that MAY change after creation: + +* `Status` (via transition commits) + +Fields that MUST NOT change after creation: + +* `ID`, `Type`, `Title`, `Priority`, `Created`, `Description`, + `Module` + ## Git Workflow Rules ### Branch Naming @@ -186,6 +362,83 @@ bugfix/7 * A branch MUST be named exactly `/`. * A branch MAY merge only when the issue status is `done`. +## Status Transition Rules + +### Valid Transitions + +Not all status changes are permitted. The following table defines the +complete set of valid transitions: + +| From | Allowed transitions | +|---------------|-------------------------------------| +| `open` | `in-progress`, `hold`, `cancelled` | +| `in-progress` | `done`, `hold`, `open`, `cancelled` | +| `hold` | `open`, `in-progress`, `cancelled` | +| `done` | `open` | +| `cancelled` | `open` | + +Any transition not listed MUST be rejected. A no-op transition (same status) +is permitted. + +### Transition Commits + +Each status transition MUST be recorded as a dedicated commit that modifies +only the `TODO` file. The commit message MUST follow this format: + +```default +todo(): + + +``` + +Where: + +* `` is the issue’s integer ID. +* `` is the new status value. +* `` is a required description whose content depends on the + transition. + +### Transition Details + +**\`\`todo(): open\`\`** — Issue creation. + +* Branch: MUST be on `develop`. +* Body: description of what needs to be done (becomes the issue’s + `Description` field). + +**\`\`todo(): in-progress\`\`** — Start work. + +* Branch: MUST be on `develop`. +* Body: high-level description of the planned approach. +* After this commit, the issue branch `/` may be created from + `develop`. + +**\`\`todo(): done\`\`** — Complete work. + +* Branch: MUST be on `/`. +* Body: high-level summary of what was delivered. +* After this commit, the issue branch may be merged into `develop` using + `--no-ff`. + +**\`\`todo(): hold\`\`** — Pause work. + +* Branch: MUST be on `/`. +* Body: reason for holding. + +**\`\`todo(): cancelled\`\`** — Cancel issue. + +* Branch: MUST be on `develop` or `/`. +* Body: reason for cancellation. +* If the issue is `open` (no branch exists), the commit is on `develop`. +* If the issue is `in-progress` or `hold` (branch exists), the commit + may be on the issue branch. + +### Transition-Only Constraint + +A transition commit MUST modify only the `TODO` file. No other files may +be included in the commit. This ensures that every transition is +independently auditable. + ## Sprint Membership Logic Given: @@ -222,7 +475,10 @@ The preprocessor MUST: * Extract each part’s `Content-Type` and body. * Reorder parts so that: \* `application/sprints` appears first (if present) + \* `application/modules` appears second (if present) + \* `application/bugzilla` appears third (if present) \* All `application/issue` parts follow in original order + \* Unknown part types are preserved in original order after issues * Emit a MIME message with: \* `MIME-Version: 1.0` \* `Content-Type: multipart/mixed; boundary="ISSUE"` @@ -246,17 +502,26 @@ The parser MUST: * Use a MIME parser to extract parts. * Dispatch based on `Content-Type`: \* `application/sprints` → sprint parser + \* `application/modules` → module parser + \* `application/bugzilla` → Bugzilla tracker parser \* `application/issue` → issue parser * Enforce: \* Field order \* Required fields - \* Description indentation rules + \* Description indentation and column rules \* Sprint entry grammar + \* Module entry grammar + \* Module references: if `application/modules` is present, every issue `Module` field MUST reference a defined module name + \* Bugzilla mapping references: if `application/bugzilla` is present, every mapping `Module` value MUST reference a defined module name + \* Relationship targets: every target ID MUST reference an existing issue ID + \* Stale relationships: a relationship targeting a `cancelled` issue SHOULD produce a warning * Produce a `TodoFile` object: ```default { sprints: Sprint[], - issues: Issue[] + issues: Issue[], + modules?: Module[], + bugzilla?: BugzillaTracker } ``` @@ -271,22 +536,159 @@ The parser MUST reject: * Invalid sprint ranges * Invalid date formats * Multiple `application/sprints` parts +* Multiple `application/modules` parts +* Multiple `application/bugzilla` parts +* `application/bugzilla` without `application/modules` +* Issue `Module` referencing undefined module +* Bugzilla mapping `Module` referencing undefined module +* Relationship target referencing non-existent issue ID +* Invalid status transition * Duplicate issue IDs +The parser SHOULD warn on: + +* Relationship targeting a `cancelled` issue (stale reference) + Errors SHOULD include line numbers when possible. +## CLI Reference + +The `@byteb4rb1e/mime-todo` CLI is the reference implementation of this +specification. It enforces all format, validation, transition, and commit +rules defined above. Both developers and automated agents MUST use the CLI +to interact with the `TODO` file rather than editing it manually. + +Install: + +```default +npm install -g @byteb4rb1e/mime-todo +``` + +### Issue Lifecycle + +Creating an issue (MUST be on `develop`): + +```default +todo create --type feature --title "Add login" --plan "Implement OAuth2 flow" +``` + +This produces a `todo(): open` commit modifying only the `TODO` file. +The `--plan` text becomes the issue’s `Description` field. + +Starting work (MUST be on `develop`): + +```default +todo start --plan "High-level approach description" +``` + +This produces a `todo(): in-progress` commit. The issue branch +`/` may then be created by the user: + +```default +git checkout -b feature/ +``` + +Completing work (MUST be on `/`): + +```default +todo done --summary "Summary of what was delivered" +``` + +This produces a `todo(): done` commit. The issue branch may then be +merged into `develop` using `--no-ff`. + +Holding an issue (MUST be on `/`): + +```default +todo hold --reason "Blocked on dependency" +``` + +Cancelling an issue (MUST be on `develop` or `/`): + +```default +todo cancel --reason "Superseded by issue #5" +``` + +The CLI validates the current branch and the status transition before +committing. Invalid transitions or wrong branches are rejected with an +error. + +### Read-Only Commands + +These commands do not modify the `TODO` file and may be run from any +branch: + +```default +todo list # list all issues +todo show # show full issue details +todo sprints # list all sprints +todo issues-in-sprint # list issues in a sprint +``` + +### Bugzilla Integration + +Initializing products and components: + +```default +todo init # check what exists +todo init --dry-run # preview changes +todo init --confirm --assignee user@example.com # create missing items +``` + +The `init` command reads the `application/bugzilla` part and ensures all +referenced products and components exist on the Bugzilla server. + +Pushing commits to Bugzilla: + +```default +todo push # push all unpushed commits +todo push HEAD~3 # push only the last 3 commits +todo push --dry-run # preview without pushing +todo push --strategy full # re-scan all bugs +``` + +On issue branches, `push` posts work commits as Bugzilla comments. Work +comments are only permitted when the issue is `in-progress` and no +`done` transition has been recorded. + +On `develop`, `push` posts transition commits as Bugzilla comments and +updates the bug’s status accordingly. + +Each comment includes a clickable link to the commit and is tagged with +`git-` for idempotency. Running `push` multiple times is +safe. + +### Agent Usage + +Agents MUST use the CLI for all `TODO` file interactions: + +* Creating issues: `todo create` +* Transitioning issues: `todo start`, `todo done`, `todo hold`, + `todo cancel` +* Querying: `todo list`, `todo show`, `todo sprints` +* Syncing to Bugzilla: `todo push` + +Agents MUST NOT: + +* Edit the `TODO` file directly. +* Construct transition commits manually. +* Modify issue fields other than `Status` (and only via the CLI). +* Push to Bugzilla outside of the CLI’s `push` command. + ## Extensibility +Defined part types: + +* `application/sprints` — sprint metadata +* `application/modules` — repository module structure +* `application/bugzilla` — Bugzilla product/component mappings +* `application/issue` — single issue + Future part types MAY be added using: ```default application/ ``` -Examples: - -* `application/metadata` -* `application/changelog` -* `application/epilog` - The preprocessor MUST preserve unknown part types but MUST NOT reorder them. +Unknown types are placed after all defined types. diff --git a/src/README.rst b/src/README.rst index 2ea57b5..a33a21b 100644 --- a/src/README.rst +++ b/src/README.rst @@ -27,10 +27,14 @@ The raw ``TODO`` file consists of a sequence of *parts*, each beginning with:: Valid part types are: * ``application/sprints`` — defines sprint metadata +* ``application/modules`` — defines the repository module structure +* ``application/bugzilla`` — defines Bugzilla product/component mappings * ``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. +them so that ``application/sprints`` appears first, followed by +``application/modules``, then ``application/bugzilla``, then all +``application/issue`` parts in original order. MIME Envelope (Added by Preprocessor) @@ -99,6 +103,148 @@ Required keys: The ``Range`` defines a closed interval ``[start, end]``. +Part: ``application/modules`` +============================== + +This part defines the repository's logical module structure. Each module maps +a name to an optional repository-relative path. + +At most one ``application/modules`` part MAY appear. Multiple +``application/modules`` parts MUST be rejected. + +The body MUST begin with:: + + Modules: + +followed by one or more module entries. + +Module Entry Forms +------------------ + +Compact form:: + + - Name: Specification + Path: src + +Expanded form:: + + - + Name: Specification + Path: src + +A module without a path (logical grouping):: + + - Name: Documentation + +Module Entry Grammar +-------------------- + +A module 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: `` — unique module identifier. + +Optional keys: + +* ``Path: `` — path relative to repository root. + If omitted, the module is a logical grouping without a fixed location. + + +Part: ``application/bugzilla`` +=============================== + +This part defines a unidirectional mapping from repository modules to +Bugzilla products and components. The ``TODO`` file is the source of truth; +Bugzilla is a downstream mirror. + +At most one ``application/bugzilla`` part MAY appear. Multiple +``application/bugzilla`` parts MUST be rejected. + +An ``application/bugzilla`` part MUST NOT appear unless an +``application/modules`` part is also present. + +Required Fields +--------------- + +:: + + URL: + Mappings: + - Module: + Product: + Component: + +* **URL**: the base URL to the Bugzilla REST API. +* **Mappings**: one or more entries mapping a module name to a Bugzilla + product and component. Every ``Module`` value MUST reference a module + defined in the ``application/modules`` part. + +Product and component names containing spaces or special characters are +permitted; tooling MUST URL-encode them when constructing API requests. + +Mapping Entry Grammar +--------------------- + +A mapping entry begins at a line matching:: + + ^\s*-\s*(Module:.*)?$ + +Required keys: + +* ``Module: `` — references a module name. +* ``Product: `` — Bugzilla product name. +* ``Component: `` — Bugzilla component name. + +Sync Model +---------- + +Synchronization is unidirectional: ``TODO`` → Bugzilla. The ``TODO`` file is +the canonical source of truth. + +When a Bugzilla bug is created for a ``TODO`` issue, the bug's ``url`` field +MUST be set to a resolvable URL pointing to the ``TODO`` file on the +integration branch. The URL format is host-dependent: + +* Bitbucket: ``/src//TODO#`` +* GitHub: ``/blob//TODO#`` +* GitLab: ``/-/blob//TODO#`` + +The branch in the URL MUST be the integration branch (``develop``), +regardless of which branch the push is initiated from. + +Transition commit messages are pushed as Bugzilla comments. Each comment is +tagged with ``git-`` (first 7 characters of the commit hash) to +prevent duplicate pushes. A comment tag is applied only after the comment +and any associated status update have both succeeded. + +Work commits from issue branches are also pushed as Bugzilla comments, +forming a threaded work log. Work comments: + +* MUST NOT be pushed unless the issue status is ``in-progress``. +* MUST NOT follow a ``done`` transition comment. + +Comment format (Markdown):: + + **** + + + + [``]() + +The commit URL format is host-dependent: + +* Bitbucket: ``/commits/`` +* GitHub: ``/commit/`` +* GitLab: ``/-/commit/`` + + Part: ``application/issue`` =========================== @@ -115,9 +261,10 @@ The following fields MUST appear in exactly this order:: Status: Priority: Created: + Module: # OPTIONAL Relationships: - DueStart: # OPTIONAL - DueEnd: # OPTIONAL + DueStart: # OPTIONAL + DueEnd: # OPTIONAL Description: @@ -131,6 +278,9 @@ Field Semantics * **Status**: one of ``open``, ``in-progress``, ``done``, ``hold``, ``cancelled``. * **Priority**: one of ``low``, ``medium``, ``high``. * **Created**: ISO date. +* **Module**: optional. When present, MUST reference a module name defined in + the ``application/modules`` part. If no ``application/modules`` part exists, + the field is ignored. * **Relationships**: * Empty:: @@ -140,7 +290,11 @@ Field Semantics Relationships: dependsOn:43, relatesTo:10 - * Valid kinds: ``dependsOn``, ``relatesTo``, ``blocks``, ``causedBy``. + * Valid kinds: ``dependsOn``, ``relatesTo``, ``blocks``. + * All relationship target IDs MUST reference existing issue IDs in the + same ``TODO`` file. A target that does not exist MUST be rejected. + * A relationship targeting a ``cancelled`` issue SHOULD produce a warning + (stale reference). * **DueStart / DueEnd**: * Optional. * If only one is present, the other is implicitly equal to it. @@ -149,9 +303,10 @@ Description Block ----------------- * The first line appears on the same line as ``Description:``. -* Continuation lines: - * Must begin with whitespace. - * Must align indentation consistently. +* ``Description:`` occupies 13 characters. Content begins at column 14. +* Continuation lines MUST be indented with 13 spaces, aligning with column 14. +* Lines MUST NOT exceed 80 columns. Long text MUST be word-wrapped at the + 80-column boundary by the serializer. * No blank lines allowed inside the description block. Body @@ -160,6 +315,21 @@ 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. +Issue Immutability +------------------ + +The ``Description`` field is immutable after the issue is created. To change +the scope of an issue, the issue MUST be cancelled and a new issue created. + +Fields that MAY change after creation: + +* ``Status`` (via transition commits) + +Fields that MUST NOT change after creation: + +* ``ID``, ``Type``, ``Title``, ``Priority``, ``Created``, ``Description``, + ``Module`` + Git Workflow Rules ================== @@ -190,6 +360,96 @@ Branch Lifecycle * A branch MAY merge only when the issue status is ``done``. +Status Transition Rules +======================= + +Valid Transitions +----------------- + +Not all status changes are permitted. The following table defines the +complete set of valid transitions: + +.. list-table:: + :header-rows: 1 + :widths: 20 50 + + * - From + - Allowed transitions + * - ``open`` + - ``in-progress``, ``hold``, ``cancelled`` + * - ``in-progress`` + - ``done``, ``hold``, ``open``, ``cancelled`` + * - ``hold`` + - ``open``, ``in-progress``, ``cancelled`` + * - ``done`` + - ``open`` + * - ``cancelled`` + - ``open`` + +Any transition not listed MUST be rejected. A no-op transition (same status) +is permitted. + +Transition Commits +------------------ + +Each status transition MUST be recorded as a dedicated commit that modifies +only the ``TODO`` file. The commit message MUST follow this format:: + + todo(): + + + +Where: + +* ```` is the issue's integer ID. +* ```` is the new status value. +* ```` is a required description whose content depends on the + transition. + +Transition Details +------------------ + +**``todo(): open``** — Issue creation. + +* Branch: MUST be on ``develop``. +* Body: description of what needs to be done (becomes the issue's + ``Description`` field). + +**``todo(): in-progress``** — Start work. + +* Branch: MUST be on ``develop``. +* Body: high-level description of the planned approach. +* After this commit, the issue branch ``/`` may be created from + ``develop``. + +**``todo(): done``** — Complete work. + +* Branch: MUST be on ``/``. +* Body: high-level summary of what was delivered. +* After this commit, the issue branch may be merged into ``develop`` using + ``--no-ff``. + +**``todo(): hold``** — Pause work. + +* Branch: MUST be on ``/``. +* Body: reason for holding. + +**``todo(): cancelled``** — Cancel issue. + +* Branch: MUST be on ``develop`` or ``/``. +* Body: reason for cancellation. +* If the issue is ``open`` (no branch exists), the commit is on ``develop``. +* If the issue is ``in-progress`` or ``hold`` (branch exists), the commit + may be on the issue branch. + +Transition-Only Constraint +-------------------------- + +A transition commit MUST modify only the ``TODO`` file. No other files may +be included in the commit. This ensures that every transition is +independently auditable. + + Sprint Membership Logic ======================= @@ -213,7 +473,7 @@ 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``. @@ -230,7 +490,10 @@ The preprocessor MUST: * Extract each part's ``Content-Type`` and body. * Reorder parts so that: * ``application/sprints`` appears first (if present) + * ``application/modules`` appears second (if present) + * ``application/bugzilla`` appears third (if present) * All ``application/issue`` parts follow in original order + * Unknown part types are preserved in original order after issues * Emit a MIME message with: * ``MIME-Version: 1.0`` * ``Content-Type: multipart/mixed; boundary="ISSUE"`` @@ -254,17 +517,26 @@ The parser MUST: * Use a MIME parser to extract parts. * Dispatch based on ``Content-Type``: * ``application/sprints`` → sprint parser + * ``application/modules`` → module parser + * ``application/bugzilla`` → Bugzilla tracker parser * ``application/issue`` → issue parser * Enforce: * Field order * Required fields - * Description indentation rules + * Description indentation and column rules * Sprint entry grammar + * Module entry grammar + * Module references: if ``application/modules`` is present, every issue ``Module`` field MUST reference a defined module name + * Bugzilla mapping references: if ``application/bugzilla`` is present, every mapping ``Module`` value MUST reference a defined module name + * Relationship targets: every target ID MUST reference an existing issue ID + * Stale relationships: a relationship targeting a ``cancelled`` issue SHOULD produce a warning * Produce a ``TodoFile`` object:: { sprints: Sprint[], - issues: Issue[] + issues: Issue[], + modules?: Module[], + bugzilla?: BugzillaTracker } @@ -280,22 +552,145 @@ The parser MUST reject: * Invalid sprint ranges * Invalid date formats * Multiple ``application/sprints`` parts +* Multiple ``application/modules`` parts +* Multiple ``application/bugzilla`` parts +* ``application/bugzilla`` without ``application/modules`` +* Issue ``Module`` referencing undefined module +* Bugzilla mapping ``Module`` referencing undefined module +* Relationship target referencing non-existent issue ID +* Invalid status transition * Duplicate issue IDs +The parser SHOULD warn on: + +* Relationship targeting a ``cancelled`` issue (stale reference) + Errors SHOULD include line numbers when possible. +CLI Reference +============= + +The ``@byteb4rb1e/mime-todo`` CLI is the reference implementation of this +specification. It enforces all format, validation, transition, and commit +rules defined above. Both developers and automated agents MUST use the CLI +to interact with the ``TODO`` file rather than editing it manually. + +Install:: + + npm install -g @byteb4rb1e/mime-todo + +Issue Lifecycle +--------------- + +Creating an issue (MUST be on ``develop``):: + + todo create --type feature --title "Add login" --plan "Implement OAuth2 flow" + +This produces a ``todo(): open`` commit modifying only the ``TODO`` file. +The ``--plan`` text becomes the issue's ``Description`` field. + +Starting work (MUST be on ``develop``):: + + todo start --plan "High-level approach description" + +This produces a ``todo(): in-progress`` commit. The issue branch +``/`` may then be created by the user:: + + git checkout -b feature/ + +Completing work (MUST be on ``/``):: + + todo done --summary "Summary of what was delivered" + +This produces a ``todo(): done`` commit. The issue branch may then be +merged into ``develop`` using ``--no-ff``. + +Holding an issue (MUST be on ``/``):: + + todo hold --reason "Blocked on dependency" + +Cancelling an issue (MUST be on ``develop`` or ``/``):: + + todo cancel --reason "Superseded by issue #5" + +The CLI validates the current branch and the status transition before +committing. Invalid transitions or wrong branches are rejected with an +error. + +Read-Only Commands +------------------ + +These commands do not modify the ``TODO`` file and may be run from any +branch:: + + todo list # list all issues + todo show # show full issue details + todo sprints # list all sprints + todo issues-in-sprint # list issues in a sprint + +Bugzilla Integration +-------------------- + +Initializing products and components:: + + todo init # check what exists + todo init --dry-run # preview changes + todo init --confirm --assignee user@example.com # create missing items + +The ``init`` command reads the ``application/bugzilla`` part and ensures all +referenced products and components exist on the Bugzilla server. + +Pushing commits to Bugzilla:: + + todo push # push all unpushed commits + todo push HEAD~3 # push only the last 3 commits + todo push --dry-run # preview without pushing + todo push --strategy full # re-scan all bugs + +On issue branches, ``push`` posts work commits as Bugzilla comments. Work +comments are only permitted when the issue is ``in-progress`` and no +``done`` transition has been recorded. + +On ``develop``, ``push`` posts transition commits as Bugzilla comments and +updates the bug's status accordingly. + +Each comment includes a clickable link to the commit and is tagged with +``git-`` for idempotency. Running ``push`` multiple times is +safe. + +Agent Usage +----------- + +Agents MUST use the CLI for all ``TODO`` file interactions: + +* Creating issues: ``todo create`` +* Transitioning issues: ``todo start``, ``todo done``, ``todo hold``, + ``todo cancel`` +* Querying: ``todo list``, ``todo show``, ``todo sprints`` +* Syncing to Bugzilla: ``todo push`` + +Agents MUST NOT: + +* Edit the ``TODO`` file directly. +* Construct transition commits manually. +* Modify issue fields other than ``Status`` (and only via the CLI). +* Push to Bugzilla outside of the CLI's ``push`` command. + + Extensibility ============= +Defined part types: + +* ``application/sprints`` — sprint metadata +* ``application/modules`` — repository module structure +* ``application/bugzilla`` — Bugzilla product/component mappings +* ``application/issue`` — single issue + Future part types MAY be added using:: application/ -Examples: - -* ``application/metadata`` -* ``application/changelog`` -* ``application/epilog`` - The preprocessor MUST preserve unknown part types but MUST NOT reorder them. +Unknown types are placed after all defined types.