ticket: use base32 project record ids
This commit is contained in:
@@ -0,0 +1,152 @@
|
||||
# Delegation intent: Ticket local files backend
|
||||
|
||||
## Classification
|
||||
|
||||
`implementation-ready` with a constrained design boundary.
|
||||
|
||||
The Ticket concept, split, and terminology have been accepted in the parent umbrella. This ticket should implement the first layer only: a typed Rust Ticket domain/backend and a LocalTicketBackend over the current `work-items/` files.
|
||||
|
||||
## Intent
|
||||
|
||||
Add a code-facing Ticket domain model and local files backend so yoi can read and mutate the current repository Ticket records without shelling out to `tickets.sh` or ad hoc parsing.
|
||||
|
||||
The durable orchestration concept is named `Ticket`. The current local storage directory remains `work-items/` for compatibility.
|
||||
|
||||
## Worktree / branch
|
||||
|
||||
- worktree: `/home/hare/Projects/yoi/.worktree/ticket-local-files-backend`
|
||||
- branch: `work/ticket-local-files-backend`
|
||||
|
||||
## Requirements
|
||||
|
||||
- Add a new backend-shaped Rust layer for Tickets.
|
||||
- Use `Ticket`, not `WorkItem`, as the public/domain concept name.
|
||||
- Prefer a new lower-level workspace crate such as `crates/ticket` unless current code mapping reveals a better fit.
|
||||
- Keep this crate independent from `pod` and `tui`.
|
||||
- Implement `LocalTicketBackend` over current `work-items/` storage.
|
||||
- Preserve compatibility with `tickets.sh` and existing `work-items/{open,pending,closed}/<id>/` layout.
|
||||
- Preserve these local files:
|
||||
- `item.md` with YAML-ish frontmatter and Markdown body;
|
||||
- `thread.md` append-only event-ish log;
|
||||
- `artifacts/` directory;
|
||||
- `resolution.md` for closed tickets.
|
||||
- Implement typed operations equivalent to:
|
||||
- list;
|
||||
- show;
|
||||
- create;
|
||||
- add event/comment for roles `comment`, `plan`, `decision`, `implementation_report`;
|
||||
- review approve/request-changes;
|
||||
- status transition across open/pending/closed;
|
||||
- close with resolution;
|
||||
- doctor/consistency check.
|
||||
- Provide a thin typed envelope around Markdown/freeform content.
|
||||
- Include fields useful for later Orchestrator/TUI/tool layers where practical:
|
||||
- id / slug / title;
|
||||
- status;
|
||||
- kind / priority / labels;
|
||||
- created_at / updated_at;
|
||||
- readiness / needs_preflight / risk flags / action_required if present, while tolerating old tickets without them;
|
||||
- event kind / review result.
|
||||
- Keep unknown/extension values parseable rather than failing unnecessarily.
|
||||
- Implement safe local mutation:
|
||||
- path containment under configured root;
|
||||
- atomic replace for file rewrites where practical;
|
||||
- basic backend lock/conflict handling for concurrent Pod/tool callers;
|
||||
- no writes outside the configured local ticket root except controlled temp files.
|
||||
- Add focused tests using temp directories/fixtures; do not mutate real `work-items/` in tests.
|
||||
- Keep `tickets.sh` command behavior intact.
|
||||
|
||||
## Non-goals
|
||||
|
||||
- Pod tools / built-in feature integration.
|
||||
- Intake workflow/profile implementation.
|
||||
- Orchestrator routing implementation.
|
||||
- TUI UI changes.
|
||||
- Renaming `work-items/` to `tickets/`.
|
||||
- Removing or replacing `tickets.sh`.
|
||||
- External tracker backends.
|
||||
- Scheduler/lease/automatic maintainer behavior.
|
||||
- Changing the session-local Task tool.
|
||||
|
||||
## Current code map
|
||||
|
||||
- `tickets.sh`
|
||||
- Current authoritative mechanical behavior for local ticket creation/list/show/comment/review/status/close/doctor.
|
||||
- Use it as compatibility reference, not as a runtime dependency for the Rust backend.
|
||||
- `work-items/{open,pending,closed}/<id>/item.md`
|
||||
- Ticket frontmatter and Markdown body.
|
||||
- Required existing fields: `id`, `slug`, `title`, `status`, `kind`, `priority`, `labels`, `created_at`, `updated_at`, `assignee`, `legacy_ticket`.
|
||||
- `work-items/{open,pending,closed}/<id>/thread.md`
|
||||
- Current event log format uses HTML comments like `<!-- event: ... author: ... at: ... -->`, heading/body, and `---` separators.
|
||||
- `work-items/{open,pending,closed}/<id>/artifacts/`
|
||||
- Controlled artifact directory for a ticket.
|
||||
- `work-items/closed/<id>/resolution.md`
|
||||
- Resolution body for closed tickets.
|
||||
- root `Cargo.toml`
|
||||
- Add the new crate to workspace members.
|
||||
- `work-items/open/20260601-031252-builtin-work-item-intake-routing/artifacts/ticket-definition-and-api-shape-20260605.md`
|
||||
- Current conceptual Ticket definition/API direction.
|
||||
|
||||
## Suggested API shape
|
||||
|
||||
The exact API may be adjusted, but keep the layer backend-shaped:
|
||||
|
||||
```rust
|
||||
trait TicketBackend {
|
||||
fn list(&self, filter: TicketFilter) -> Result<Vec<TicketSummary>>;
|
||||
fn show(&self, id: TicketIdOrSlug) -> Result<Ticket>;
|
||||
fn create(&self, input: NewTicket) -> Result<TicketRef>;
|
||||
fn add_event(&self, id: TicketIdOrSlug, event: NewTicketEvent) -> Result<()>;
|
||||
fn review(&self, id: TicketIdOrSlug, review: TicketReview) -> Result<()>;
|
||||
fn set_status(&self, id: TicketIdOrSlug, status: TicketStatus) -> Result<()>;
|
||||
fn close(&self, id: TicketIdOrSlug, resolution: MarkdownText) -> Result<()>;
|
||||
fn doctor(&self) -> Result<TicketDoctorReport>;
|
||||
}
|
||||
```
|
||||
|
||||
It is acceptable to expose concrete `LocalTicketBackend` methods first if trait object design becomes premature, but the code should not bake local paths into the Ticket concept types.
|
||||
|
||||
## Compatibility details to preserve
|
||||
|
||||
- `tickets.sh create` id format is `<YYYYMMDD-HHMMSS>-<slug>`.
|
||||
- Status directories are `open`, `pending`, `closed`.
|
||||
- `status` frontmatter must match containing directory.
|
||||
- `doctor` checks required fields, id/directory match, duplicate ids/slugs, required files/directories, and legacy `tickets/*.md` references.
|
||||
- `close` moves the ticket to `closed`, writes `resolution.md`, and appends a close event.
|
||||
- `review` appends a review event with `status: approve` or `request_changes` in the event comment.
|
||||
|
||||
## Escalate if
|
||||
|
||||
- Preserving compatibility requires changing existing `tickets.sh` behavior.
|
||||
- A strict typed schema would reject many existing tickets.
|
||||
- The lock/atomic write approach requires a new dependency with license/packaging implications.
|
||||
- The new crate needs to depend on `pod`, `tui`, or other high-level crates.
|
||||
- Implementing all operations in one commit becomes too large; prefer a clean subset and report what remains.
|
||||
|
||||
## Validation
|
||||
|
||||
Run at least:
|
||||
|
||||
- new crate unit tests;
|
||||
- compatibility tests that create/comment/review/status/close in temp dirs and verify `doctor` behavior;
|
||||
- `cargo test -p ticket` or the chosen crate package name;
|
||||
- `cargo check --workspace --all-targets`;
|
||||
- `cargo fmt --check`;
|
||||
- `git diff --check`;
|
||||
- `./tickets.sh doctor`.
|
||||
|
||||
If feasible, run `nix build .#yoi` after the workspace check passes.
|
||||
|
||||
## Completion report
|
||||
|
||||
Report:
|
||||
|
||||
- worktree path / branch;
|
||||
- commit hash;
|
||||
- chosen crate/module name;
|
||||
- public API summary;
|
||||
- changed files;
|
||||
- compatibility with `tickets.sh`;
|
||||
- tests/validation run;
|
||||
- unresolved risks/follow-ups;
|
||||
- whether ready for external review.
|
||||
@@ -0,0 +1,98 @@
|
||||
# Implementation report: ticket-local-files-backend
|
||||
|
||||
## Worktree / branch
|
||||
|
||||
- Worktree: `/home/hare/Projects/yoi/.worktree/ticket-local-files-backend`
|
||||
- Branch: `work/ticket-local-files-backend`
|
||||
|
||||
## Commit
|
||||
|
||||
- `740b017 feat: add local ticket backend`
|
||||
|
||||
## Summary
|
||||
|
||||
Added a new low-level `ticket` workspace crate that exposes a typed Ticket domain, `TicketBackend` trait, and `LocalTicketBackend` over the existing `work-items/` local markdown storage.
|
||||
|
||||
The implementation preserves the current local file layout and `tickets.sh` compatibility while making Ticket operations available as Rust API for later built-in tools, Intake workflow, and Orchestrator routing work.
|
||||
|
||||
## Public API / module summary
|
||||
|
||||
- `Ticket`, `TicketSummary`, `TicketMeta`, `TicketEvent`, `TicketReview`, `TicketArtifactRef`
|
||||
- `TicketStatus`, `TicketEventKind`, `TicketReviewStatus`, `TicketKind`, `TicketPriority`
|
||||
- `TicketIdOrSlug`, `TicketFilter`, `NewTicket`, `NewTicketEvent`
|
||||
- `TicketBackend` trait
|
||||
- `LocalTicketBackend`
|
||||
- `TicketDoctorReport` / `TicketDoctorDiagnostic`
|
||||
|
||||
Implemented backend operations:
|
||||
|
||||
- `list`
|
||||
- `show`
|
||||
- `create`
|
||||
- `add_event`
|
||||
- `review`
|
||||
- `set_status`
|
||||
- `close`
|
||||
- `doctor`
|
||||
|
||||
## Changed files
|
||||
|
||||
- `Cargo.lock`
|
||||
- `Cargo.toml`
|
||||
- `package.nix`
|
||||
- `crates/ticket/Cargo.toml`
|
||||
- `crates/ticket/src/lib.rs`
|
||||
|
||||
## Compatibility
|
||||
|
||||
- Keeps `work-items/{open,pending,closed}/<id>/item.md`, `thread.md`, `artifacts/`, and closed `resolution.md` layout.
|
||||
- Rust-created tickets pass `tickets.sh doctor` in tempdir tests.
|
||||
- `tickets.sh`-created tickets are readable by the Rust backend in tempdir tests.
|
||||
- `tickets.sh` can mutate Rust-created tickets in tempdir tests.
|
||||
- Real repository `./tickets.sh doctor` passed.
|
||||
|
||||
## Safety / scope
|
||||
|
||||
- New crate is lower-level and independent of `pod`, `tui`, Intake, Orchestrator routing, and scheduler code.
|
||||
- No Pod tools or UI were added.
|
||||
- No storage directory rename was introduced.
|
||||
- Writes are constrained to configured backend root paths.
|
||||
- Local backend uses a `.ticket-backend.lock` file for Rust backend caller coordination.
|
||||
- File rewrites use temp files in the destination directory followed by rename where practical.
|
||||
|
||||
## Validation
|
||||
|
||||
Coder-reported validation passed:
|
||||
|
||||
- `cargo test -p ticket`
|
||||
- `cargo check --workspace --all-targets`
|
||||
- `cargo fmt --check`
|
||||
- `git diff --check`
|
||||
- `git diff --cached --check`
|
||||
- `./tickets.sh doctor`
|
||||
- `nix build .#yoi`
|
||||
|
||||
Reviewer-rerun validation passed:
|
||||
|
||||
- `cargo test -p ticket --no-run`
|
||||
- `cargo test -p ticket`
|
||||
- `cargo fmt --check`
|
||||
- `git diff --check develop...HEAD`
|
||||
- `./tickets.sh doctor`
|
||||
- `cargo check --workspace --all-targets`
|
||||
- `nix build .#yoi --no-link`
|
||||
|
||||
## Review status
|
||||
|
||||
External sibling reviewer approved with no blockers.
|
||||
|
||||
Non-blocker follow-ups:
|
||||
|
||||
- Event references are modeled but not persisted/parsed in `thread.md` yet.
|
||||
- Extension enum variants should remain read-tolerant, while local write paths should avoid emitting values that `tickets.sh doctor` rejects unless the format is intentionally extended.
|
||||
- Backend locking coordinates Rust backend callers, not concurrent direct `tickets.sh` writes.
|
||||
- The inherited `thread.md` `---` separator remains ambiguous for event bodies containing standalone `---` lines.
|
||||
|
||||
## Ready for merge
|
||||
|
||||
Yes.
|
||||
@@ -0,0 +1,66 @@
|
||||
# Review: ticket-local-files-backend
|
||||
|
||||
## 1. Result
|
||||
|
||||
approve
|
||||
|
||||
## 2. Summary of implementation
|
||||
|
||||
The implementation adds a new low-level `ticket` workspace crate with a typed Ticket domain, `TicketBackend` trait, and a filesystem-backed `LocalTicketBackend` for the existing `work-items/` directory layout. The crate is independent of `pod`, `tui`, scheduler/orchestrator, and intake UI/runtime code. It models tickets, events, reviews, statuses, artifacts, and doctor diagnostics, and provides operations for list/show/create/add_event/review/set_status/close/doctor.
|
||||
|
||||
The local backend writes the same file names and status directories used by `tickets.sh`:
|
||||
|
||||
- `work-items/{open,pending,closed}/<id>/item.md`
|
||||
- `thread.md`
|
||||
- `artifacts/`
|
||||
- closed `resolution.md`
|
||||
|
||||
## 3. Requirement-by-requirement assessment
|
||||
|
||||
- Public/domain naming uses `Ticket`, not `WorkItem`: satisfied. Public names are `Ticket`, `TicketBackend`, `LocalTicketBackend`, `TicketStatus`, `TicketEvent`, etc.
|
||||
- Crate/module placement: satisfied. `crates/ticket` is a low-level workspace crate and does not depend on `pod`, `tui`, or other high-level crates.
|
||||
- Backend-oriented API shape: satisfied for this ticket. Local path concepts are mostly confined to `LocalTicketBackend`, `TicketArtifactRef`, and filesystem operations; core ticket/status/event metadata remains backend-neutral.
|
||||
- Current layout compatibility: satisfied. The implementation preserves the status directories and expected markdown files, including `resolution.md` on close.
|
||||
- Operation coverage: satisfied for this ticket. The backend covers list/show/create/add_event/review/set_status/close/doctor and includes diagnostics rather than hard failures for malformed existing records.
|
||||
- Existing old/minimal frontmatter readability: satisfied. Parsing tolerates missing optional readiness/action-required/risk fields and unknown/extension metadata values.
|
||||
- Markdown/freeform bodies: satisfied for `item.md` bodies and normal event/resolution bodies. See residual risk for the inherited `thread.md` delimiter limitation.
|
||||
- Path containment/id safety/atomic-ish writes/locking: acceptable for a local-files MVP. IDs are validated as path components, writes are staged through temp files in the destination directory then renamed, and backend operations take an exclusive backend lock.
|
||||
- Tests do not mutate real `work-items/`: satisfied. Tests use temp directories and pass an explicit `WORK_ITEMS_DIR` to `tickets.sh` compatibility checks.
|
||||
- Tests exercise `tickets.sh` compatibility: satisfied. The tests create and mutate temp work item trees through both the Rust backend and `tickets.sh`, then run/show/doctor against the same layout.
|
||||
- `Cargo.lock` / `package.nix`: acceptable. The new crate and `fs4` lock dependency require workspace/package metadata updates; `nix build .#yoi --no-link` passed.
|
||||
- Scope control: satisfied. I did not find Pod tools, intake workflow routing, orchestrator scheduling, TUI UI, storage rename, or unrelated refactors in the implementation.
|
||||
|
||||
## 4. Blockers
|
||||
|
||||
None.
|
||||
|
||||
## 5. Non-blockers / follow-ups
|
||||
|
||||
- `NewTicketEvent.references` / event references are modeled but not visibly persisted into or parsed from `thread.md`. That is acceptable for this backend MVP, but follow-up work should either define a compatible markdown representation or keep references as higher-level metadata outside the shell-compatible thread format.
|
||||
- Extension/unknown enum variants are useful for reading older/future files, but local write paths should remain careful not to emit values that `tickets.sh doctor` would reject unless the file format is intentionally extended.
|
||||
- The backend lock coordinates Rust backend callers, but it cannot coordinate concurrent direct `tickets.sh` writes. That is acceptable for this compatibility bridge, but users should not assume cross-tool transactional safety yet.
|
||||
|
||||
## 6. Validation assessed or rerun
|
||||
|
||||
Reviewed:
|
||||
|
||||
- Ticket item, delegation intent, parent Ticket definition/API shape, and `tickets.sh` compatibility reference.
|
||||
- Diff against `develop...HEAD` for the implementation branch.
|
||||
- New crate placement and workspace/package metadata.
|
||||
- Local backend read/write, parser, status transition, close, doctor, and tests.
|
||||
|
||||
Reran from `/home/hare/Projects/yoi/.worktree/ticket-local-files-backend`:
|
||||
|
||||
- `cargo test -p ticket --no-run`
|
||||
- `cargo test -p ticket`
|
||||
- `cargo fmt --check`
|
||||
- `git diff --check develop...HEAD`
|
||||
- `./tickets.sh doctor`
|
||||
- `cargo check --workspace --all-targets`
|
||||
- `nix build .#yoi --no-link`
|
||||
|
||||
All commands completed successfully.
|
||||
|
||||
## 7. Residual risk
|
||||
|
||||
The `thread.md` format still uses plain `---` event separators, so an event body containing a standalone `---` line remains ambiguous. This appears inherited from the current shell-compatible storage format rather than introduced by the new crate, and should be handled deliberately if future typed consumers require lossless arbitrary markdown event bodies.
|
||||
@@ -0,0 +1,98 @@
|
||||
---
|
||||
title: "Ticket local files backend"
|
||||
state: "closed"
|
||||
created_at: "2026-06-05T04:01:04Z"
|
||||
updated_at: "2026-06-05T04:45:46Z"
|
||||
---
|
||||
|
||||
## Background
|
||||
|
||||
The first step toward Ticket-driven multi-agent orchestration is to make the current `work-items/` + `tickets.sh` file format accessible through a typed Rust API.
|
||||
|
||||
The product/code concept name is **Ticket**. The current directory name `work-items/` remains the LocalTicketBackend storage path for now; do not rename it in this ticket.
|
||||
|
||||
This ticket should produce a backend-shaped domain layer that future Pod tools, Intake workflows, Orchestrator routing, TUI views, and external tracker integrations can use without depending on `tickets.sh` shell execution or ad hoc markdown parsing.
|
||||
|
||||
## Requirements
|
||||
|
||||
- Add a code-facing Ticket domain/backend layer.
|
||||
- Preferred crate: `crates/ticket` or `crates/tickets`; choose the name that reads best in Rust and avoids collision with `tickets.sh` scripts.
|
||||
- The public concept/type names should use `Ticket`, not `WorkItem`.
|
||||
- Implement `LocalTicketBackend` over current `work-items/` storage.
|
||||
- Preserve the current markdown + frontmatter + `thread.md` + `artifacts/` layout.
|
||||
- Preserve compatibility with `tickets.sh`; existing script operations should continue to work on files written by the Rust backend.
|
||||
- Keep git history and repository files authoritative.
|
||||
- Implement typed operations equivalent to at least:
|
||||
- list;
|
||||
- show;
|
||||
- create;
|
||||
- comment / plan / decision / implementation_report events;
|
||||
- review approve/request-changes;
|
||||
- status transition;
|
||||
- close with resolution;
|
||||
- doctor/consistency check.
|
||||
- Use a thin typed envelope with Markdown/freeform bodies.
|
||||
- Include machine-readable fields needed by Orchestrator/TUI/policy:
|
||||
- id / slug / title;
|
||||
- kind / priority / labels;
|
||||
- status;
|
||||
- readiness;
|
||||
- needs-preflight;
|
||||
- risk flags;
|
||||
- action-required state;
|
||||
- event kind;
|
||||
- references to files, branches, commits, Pods, artifacts, URLs where practical.
|
||||
- Keep enums extensible where backend compatibility needs raw values.
|
||||
- Implement safe local-file mutation:
|
||||
- atomic writes where files are replaced;
|
||||
- lock/conflict handling sufficient for multiple Pod/tool users;
|
||||
- no writes outside the configured local ticket root except controlled temp files.
|
||||
- Provide bounded errors/diagnostics suitable for later tool output.
|
||||
|
||||
## Suggested API shape
|
||||
|
||||
The exact API can be adjusted during implementation, but should remain backend-shaped:
|
||||
|
||||
```rust
|
||||
trait TicketBackend {
|
||||
fn list(&self, filter: TicketFilter) -> Result<Vec<TicketSummary>>;
|
||||
fn show(&self, id: TicketIdOrSlug) -> Result<Ticket>;
|
||||
fn create(&self, input: NewTicket) -> Result<TicketRef>;
|
||||
fn add_event(&self, id: TicketIdOrSlug, event: NewTicketEvent) -> Result<()>;
|
||||
fn review(&self, id: TicketIdOrSlug, review: TicketReview) -> Result<()>;
|
||||
fn set_status(&self, id: TicketIdOrSlug, status: TicketStatus) -> Result<()>;
|
||||
fn close(&self, id: TicketIdOrSlug, resolution: MarkdownText) -> Result<()>;
|
||||
fn doctor(&self) -> Result<TicketDoctorReport>;
|
||||
}
|
||||
```
|
||||
|
||||
## Non-goals
|
||||
|
||||
- Exposing Pod tools.
|
||||
- Implementing Intake Pod behavior.
|
||||
- Implementing Orchestrator routing or scheduling.
|
||||
- Renaming `work-items/`.
|
||||
- Removing `tickets.sh`.
|
||||
- Integrating GitHub Issues, Linear, Jira, MCP, or other external backends.
|
||||
- Building a scheduler/lease system.
|
||||
- Changing the session-local Task tool.
|
||||
|
||||
## Acceptance criteria
|
||||
|
||||
- Rust code can read existing open/pending/closed tickets from `work-items/`.
|
||||
- Rust code can create a ticket equivalent to `tickets.sh create`.
|
||||
- Rust code can append typed thread events equivalent to `tickets.sh comment` roles.
|
||||
- Rust code can record approve/request-changes reviews equivalent to `tickets.sh review`.
|
||||
- Rust code can close a ticket with a `resolution.md` equivalent to `tickets.sh close`.
|
||||
- Rust doctor catches the same core consistency failures as `tickets.sh doctor` or clearly documents any remaining gaps.
|
||||
- Files written by the Rust backend pass `./tickets.sh doctor`.
|
||||
- Existing `tickets.sh` can still read/mutate tickets written by the Rust backend.
|
||||
- Unit tests cover parsing, create, event append, review, status transition, close, doctor, lock/conflict handling, and corrupt input diagnostics.
|
||||
- `cargo test` for the new crate passes.
|
||||
- `cargo check --workspace --all-targets`, `cargo fmt --check`, `git diff --check`, and `./tickets.sh doctor` pass.
|
||||
|
||||
## Follow-up tickets
|
||||
|
||||
- `ticket-built-in-feature-tools`
|
||||
- `ticket-intake-workflow`
|
||||
- `ticket-orchestrator-routing`
|
||||
@@ -0,0 +1,34 @@
|
||||
Ticket local files backend is complete and merged.
|
||||
|
||||
Implementation:
|
||||
|
||||
- `740b017 feat: add local ticket backend`
|
||||
- merge commit: `1041cdb merge: add local ticket backend`
|
||||
|
||||
Summary:
|
||||
|
||||
- Added a new low-level `ticket` workspace crate.
|
||||
- Added typed Ticket domain types and `TicketBackend` trait.
|
||||
- Added `LocalTicketBackend` over the current `work-items/` storage.
|
||||
- Implemented list/show/create/add_event/review/set_status/close/doctor operations.
|
||||
- Preserved current local storage layout and `tickets.sh` compatibility.
|
||||
- Kept the implementation independent from `pod`, `tui`, Intake, Orchestrator routing, and scheduler code.
|
||||
- Did not rename `work-items/` or remove `tickets.sh`.
|
||||
|
||||
Review:
|
||||
|
||||
- External sibling reviewer approved with no blockers.
|
||||
- Non-blocker follow-ups recorded in the implementation report/review:
|
||||
- event references are modeled but not persisted/parsed in `thread.md` yet;
|
||||
- write paths should avoid emitting extension values that `tickets.sh doctor` rejects unless the format is intentionally extended;
|
||||
- backend lock coordinates Rust callers but not direct concurrent `tickets.sh` writes;
|
||||
- inherited `thread.md` `---` separator ambiguity remains.
|
||||
|
||||
Post-merge validation passed:
|
||||
|
||||
- `cargo test -p ticket`
|
||||
- `cargo fmt --check`
|
||||
- `git diff --check`
|
||||
- `./tickets.sh doctor`
|
||||
- `cargo check --workspace --all-targets`
|
||||
- `nix build .#yoi --no-link`
|
||||
@@ -0,0 +1,252 @@
|
||||
<!-- event: create author: tickets.sh at: 2026-06-05T04:01:04Z -->
|
||||
|
||||
## Created
|
||||
|
||||
Created by tickets.sh create.
|
||||
|
||||
---
|
||||
|
||||
<!-- event: plan author: hare at: 2026-06-05T04:24:20Z -->
|
||||
|
||||
## Plan
|
||||
|
||||
Preflight result: `implementation-ready`.
|
||||
|
||||
The Ticket naming and umbrella split are accepted. This ticket is scoped to the first implementation layer only: typed Ticket domain/backend code and LocalTicketBackend compatibility with current `work-items/` files.
|
||||
|
||||
Key decisions for implementation:
|
||||
|
||||
- Use `Ticket` as the public/domain concept name.
|
||||
- Keep `work-items/` as the current local storage path.
|
||||
- Add a lower-level Rust crate for the Ticket backend layer; do not put this in `pod` or `tui`.
|
||||
- Preserve `tickets.sh` compatibility and do not remove or replace the script in this ticket.
|
||||
- Treat readiness/action-required/risk fields as optional/extensible because existing tickets do not have a fully normalized schema.
|
||||
- Keep Markdown/freeform bodies; enforce mechanical consistency and safe mutation, not rigid body sections.
|
||||
- No Pod tools, Intake workflow, Orchestrator routing, TUI UI, external tracker backend, or scheduler in this ticket.
|
||||
|
||||
The detailed delegation intent is recorded in `artifacts/delegation-intent.md`.
|
||||
|
||||
|
||||
---
|
||||
|
||||
<!-- event: review author: hare at: 2026-06-05T04:44:08Z status: approve -->
|
||||
|
||||
## Review: approve
|
||||
|
||||
# Review: ticket-local-files-backend
|
||||
|
||||
## 1. Result
|
||||
|
||||
approve
|
||||
|
||||
## 2. Summary of implementation
|
||||
|
||||
The implementation adds a new low-level `ticket` workspace crate with a typed Ticket domain, `TicketBackend` trait, and a filesystem-backed `LocalTicketBackend` for the existing `work-items/` directory layout. The crate is independent of `pod`, `tui`, scheduler/orchestrator, and intake UI/runtime code. It models tickets, events, reviews, statuses, artifacts, and doctor diagnostics, and provides operations for list/show/create/add_event/review/set_status/close/doctor.
|
||||
|
||||
The local backend writes the same file names and status directories used by `tickets.sh`:
|
||||
|
||||
- `work-items/{open,pending,closed}/<id>/item.md`
|
||||
- `thread.md`
|
||||
- `artifacts/`
|
||||
- closed `resolution.md`
|
||||
|
||||
## 3. Requirement-by-requirement assessment
|
||||
|
||||
- Public/domain naming uses `Ticket`, not `WorkItem`: satisfied. Public names are `Ticket`, `TicketBackend`, `LocalTicketBackend`, `TicketStatus`, `TicketEvent`, etc.
|
||||
- Crate/module placement: satisfied. `crates/ticket` is a low-level workspace crate and does not depend on `pod`, `tui`, or other high-level crates.
|
||||
- Backend-oriented API shape: satisfied for this ticket. Local path concepts are mostly confined to `LocalTicketBackend`, `TicketArtifactRef`, and filesystem operations; core ticket/status/event metadata remains backend-neutral.
|
||||
- Current layout compatibility: satisfied. The implementation preserves the status directories and expected markdown files, including `resolution.md` on close.
|
||||
- Operation coverage: satisfied for this ticket. The backend covers list/show/create/add_event/review/set_status/close/doctor and includes diagnostics rather than hard failures for malformed existing records.
|
||||
- Existing old/minimal frontmatter readability: satisfied. Parsing tolerates missing optional readiness/action-required/risk fields and unknown/extension metadata values.
|
||||
- Markdown/freeform bodies: satisfied for `item.md` bodies and normal event/resolution bodies. See residual risk for the inherited `thread.md` delimiter limitation.
|
||||
- Path containment/id safety/atomic-ish writes/locking: acceptable for a local-files MVP. IDs are validated as path components, writes are staged through temp files in the destination directory then renamed, and backend operations take an exclusive backend lock.
|
||||
- Tests do not mutate real `work-items/`: satisfied. Tests use temp directories and pass an explicit `WORK_ITEMS_DIR` to `tickets.sh` compatibility checks.
|
||||
- Tests exercise `tickets.sh` compatibility: satisfied. The tests create and mutate temp work item trees through both the Rust backend and `tickets.sh`, then run/show/doctor against the same layout.
|
||||
- `Cargo.lock` / `package.nix`: acceptable. The new crate and `fs4` lock dependency require workspace/package metadata updates; `nix build .#yoi --no-link` passed.
|
||||
- Scope control: satisfied. I did not find Pod tools, intake workflow routing, orchestrator scheduling, TUI UI, storage rename, or unrelated refactors in the implementation.
|
||||
|
||||
## 4. Blockers
|
||||
|
||||
None.
|
||||
|
||||
## 5. Non-blockers / follow-ups
|
||||
|
||||
- `NewTicketEvent.references` / event references are modeled but not visibly persisted into or parsed from `thread.md`. That is acceptable for this backend MVP, but follow-up work should either define a compatible markdown representation or keep references as higher-level metadata outside the shell-compatible thread format.
|
||||
- Extension/unknown enum variants are useful for reading older/future files, but local write paths should remain careful not to emit values that `tickets.sh doctor` would reject unless the file format is intentionally extended.
|
||||
- The backend lock coordinates Rust backend callers, but it cannot coordinate concurrent direct `tickets.sh` writes. That is acceptable for this compatibility bridge, but users should not assume cross-tool transactional safety yet.
|
||||
|
||||
## 6. Validation assessed or rerun
|
||||
|
||||
Reviewed:
|
||||
|
||||
- Ticket item, delegation intent, parent Ticket definition/API shape, and `tickets.sh` compatibility reference.
|
||||
- Diff against `develop...HEAD` for the implementation branch.
|
||||
- New crate placement and workspace/package metadata.
|
||||
- Local backend read/write, parser, status transition, close, doctor, and tests.
|
||||
|
||||
Reran from `/home/hare/Projects/yoi/.worktree/ticket-local-files-backend`:
|
||||
|
||||
- `cargo test -p ticket --no-run`
|
||||
- `cargo test -p ticket`
|
||||
- `cargo fmt --check`
|
||||
- `git diff --check develop...HEAD`
|
||||
- `./tickets.sh doctor`
|
||||
- `cargo check --workspace --all-targets`
|
||||
- `nix build .#yoi --no-link`
|
||||
|
||||
All commands completed successfully.
|
||||
|
||||
## 7. Residual risk
|
||||
|
||||
The `thread.md` format still uses plain `---` event separators, so an event body containing a standalone `---` line remains ambiguous. This appears inherited from the current shell-compatible storage format rather than introduced by the new crate, and should be handled deliberately if future typed consumers require lossless arbitrary markdown event bodies.
|
||||
|
||||
|
||||
---
|
||||
|
||||
<!-- event: implementation_report author: hare at: 2026-06-05T04:44:08Z -->
|
||||
|
||||
## Implementation report
|
||||
|
||||
# Implementation report: ticket-local-files-backend
|
||||
|
||||
## Worktree / branch
|
||||
|
||||
- Worktree: `/home/hare/Projects/yoi/.worktree/ticket-local-files-backend`
|
||||
- Branch: `work/ticket-local-files-backend`
|
||||
|
||||
## Commit
|
||||
|
||||
- `740b017 feat: add local ticket backend`
|
||||
|
||||
## Summary
|
||||
|
||||
Added a new low-level `ticket` workspace crate that exposes a typed Ticket domain, `TicketBackend` trait, and `LocalTicketBackend` over the existing `work-items/` local markdown storage.
|
||||
|
||||
The implementation preserves the current local file layout and `tickets.sh` compatibility while making Ticket operations available as Rust API for later built-in tools, Intake workflow, and Orchestrator routing work.
|
||||
|
||||
## Public API / module summary
|
||||
|
||||
- `Ticket`, `TicketSummary`, `TicketMeta`, `TicketEvent`, `TicketReview`, `TicketArtifactRef`
|
||||
- `TicketStatus`, `TicketEventKind`, `TicketReviewStatus`, `TicketKind`, `TicketPriority`
|
||||
- `TicketIdOrSlug`, `TicketFilter`, `NewTicket`, `NewTicketEvent`
|
||||
- `TicketBackend` trait
|
||||
- `LocalTicketBackend`
|
||||
- `TicketDoctorReport` / `TicketDoctorDiagnostic`
|
||||
|
||||
Implemented backend operations:
|
||||
|
||||
- `list`
|
||||
- `show`
|
||||
- `create`
|
||||
- `add_event`
|
||||
- `review`
|
||||
- `set_status`
|
||||
- `close`
|
||||
- `doctor`
|
||||
|
||||
## Changed files
|
||||
|
||||
- `Cargo.lock`
|
||||
- `Cargo.toml`
|
||||
- `package.nix`
|
||||
- `crates/ticket/Cargo.toml`
|
||||
- `crates/ticket/src/lib.rs`
|
||||
|
||||
## Compatibility
|
||||
|
||||
- Keeps `work-items/{open,pending,closed}/<id>/item.md`, `thread.md`, `artifacts/`, and closed `resolution.md` layout.
|
||||
- Rust-created tickets pass `tickets.sh doctor` in tempdir tests.
|
||||
- `tickets.sh`-created tickets are readable by the Rust backend in tempdir tests.
|
||||
- `tickets.sh` can mutate Rust-created tickets in tempdir tests.
|
||||
- Real repository `./tickets.sh doctor` passed.
|
||||
|
||||
## Safety / scope
|
||||
|
||||
- New crate is lower-level and independent of `pod`, `tui`, Intake, Orchestrator routing, and scheduler code.
|
||||
- No Pod tools or UI were added.
|
||||
- No storage directory rename was introduced.
|
||||
- Writes are constrained to configured backend root paths.
|
||||
- Local backend uses a `.ticket-backend.lock` file for Rust backend caller coordination.
|
||||
- File rewrites use temp files in the destination directory followed by rename where practical.
|
||||
|
||||
## Validation
|
||||
|
||||
Coder-reported validation passed:
|
||||
|
||||
- `cargo test -p ticket`
|
||||
- `cargo check --workspace --all-targets`
|
||||
- `cargo fmt --check`
|
||||
- `git diff --check`
|
||||
- `git diff --cached --check`
|
||||
- `./tickets.sh doctor`
|
||||
- `nix build .#yoi`
|
||||
|
||||
Reviewer-rerun validation passed:
|
||||
|
||||
- `cargo test -p ticket --no-run`
|
||||
- `cargo test -p ticket`
|
||||
- `cargo fmt --check`
|
||||
- `git diff --check develop...HEAD`
|
||||
- `./tickets.sh doctor`
|
||||
- `cargo check --workspace --all-targets`
|
||||
- `nix build .#yoi --no-link`
|
||||
|
||||
## Review status
|
||||
|
||||
External sibling reviewer approved with no blockers.
|
||||
|
||||
Non-blocker follow-ups:
|
||||
|
||||
- Event references are modeled but not persisted/parsed in `thread.md` yet.
|
||||
- Extension enum variants should remain read-tolerant, while local write paths should avoid emitting values that `tickets.sh doctor` rejects unless the format is intentionally extended.
|
||||
- Backend locking coordinates Rust backend callers, not concurrent direct `tickets.sh` writes.
|
||||
- The inherited `thread.md` `---` separator remains ambiguous for event bodies containing standalone `---` lines.
|
||||
|
||||
## Ready for merge
|
||||
|
||||
Yes.
|
||||
|
||||
|
||||
---
|
||||
|
||||
<!-- event: close author: hare at: 2026-06-05T04:45:46Z status: closed -->
|
||||
|
||||
## Closed
|
||||
|
||||
Ticket local files backend is complete and merged.
|
||||
|
||||
Implementation:
|
||||
|
||||
- `740b017 feat: add local ticket backend`
|
||||
- merge commit: `1041cdb merge: add local ticket backend`
|
||||
|
||||
Summary:
|
||||
|
||||
- Added a new low-level `ticket` workspace crate.
|
||||
- Added typed Ticket domain types and `TicketBackend` trait.
|
||||
- Added `LocalTicketBackend` over the current `work-items/` storage.
|
||||
- Implemented list/show/create/add_event/review/set_status/close/doctor operations.
|
||||
- Preserved current local storage layout and `tickets.sh` compatibility.
|
||||
- Kept the implementation independent from `pod`, `tui`, Intake, Orchestrator routing, and scheduler code.
|
||||
- Did not rename `work-items/` or remove `tickets.sh`.
|
||||
|
||||
Review:
|
||||
|
||||
- External sibling reviewer approved with no blockers.
|
||||
- Non-blocker follow-ups recorded in the implementation report/review:
|
||||
- event references are modeled but not persisted/parsed in `thread.md` yet;
|
||||
- write paths should avoid emitting extension values that `tickets.sh doctor` rejects unless the format is intentionally extended;
|
||||
- backend lock coordinates Rust callers but not direct concurrent `tickets.sh` writes;
|
||||
- inherited `thread.md` `---` separator ambiguity remains.
|
||||
|
||||
Post-merge validation passed:
|
||||
|
||||
- `cargo test -p ticket`
|
||||
- `cargo fmt --check`
|
||||
- `git diff --check`
|
||||
- `./tickets.sh doctor`
|
||||
- `cargo check --workspace --all-targets`
|
||||
- `nix build .#yoi --no-link`
|
||||
|
||||
|
||||
---
|
||||
Reference in New Issue
Block a user