Expand description
Local issue tracking system — GitHub-style issues stored as markdown files.
Issues live in .oxi/issues/ at the project root (discovered by walking
up from the current directory until .oxi/ is found, mirroring
Settings::find_project_settings). Each issue is a single markdown file
with a YAML frontmatter block holding structured metadata, followed by a
free-form markdown body:
---
id: 12
title: "Fix login bug"
status: open
priority: high
labels: [bug, auth]
assignee: null
created_at: 2026-06-17T10:30:00Z
updated_at: 2026-06-17T14:20:00Z
closed_at: null
sessions: [abc123, def456]
assigned_to: null
github: null
---
Free-form markdown body...§Design decisions
- Why not a
StateStoreport? Issues are documents that humans open in$EDITOR, commit to git, and diff.StateStoreis an opaque KV/append blob. Different workload, different storage shape. This mirrors howstore/session.rsandstore/settings.rscoexist with the SDK ports. - Optimistic concurrency (content-hash CAS). Mutations take an optional
content_hashcaptured at the last read. The write is rejected if the on-disk content has changed since. This is the exact pattern used by theedittool (oxi-agent/src/tools/edit.rs), so external edits (e.g. someone editing the file in vim) are detected without any locking. - Atomic writes via temp+rename (same pattern as
store/session.rs). - Assignment is process-liveness based, not time based. An assigned
issue records the owning session id. Whether that session is still alive
is determined by an OS-held advisory lock on
.oxi/issues/.alive/<session_id>(seeliveness). When the owning process exits — includingkill -9, crash, or terminal close — the OS releases the lock and the assignment becomes stale and reclaimable. No wall-clock expiry, no heartbeats, no zombie assignments. - Per-file write serialization uses the agent’s
file_mutation_queuefor in-process concurrency. Cross-process races are bounded by the content-hash CAS: the loser gets a “retry” response, the same semantics as theedittool.
Modules§
- liveness
- Process-liveness tracking via OS advisory locks.
Structs§
- Assignment
- Who currently owns the work on an issue.
- File
Issue Store - File-backed issue store.
- Github
Ref - A reference to a synced GitHub issue. Populated only after Phase 6 sync.
- Issue
- An in-memory issue: metadata + markdown body + the file path it came from.
- Issue
Filter - Filter for
list. All fields optional (None = no constraint). - Issue
Meta - YAML frontmatter for an issue.
- Issue
Patch - A precise update payload for
FileIssueStore::apply_patch. - Issue
Summary - Summary view exposed for UI consumers (footer indicator, panel header). Cheap to construct — values come straight from the in-memory cache.
Enums§
- Issue
Error - Errors returned by issue operations.
- Priority
- Issue priority. Ordered low → critical for sorting.
- Status
- Issue status.
Functions§
- content_
hash - Compute a content hash used for optimistic concurrency (same idea as the
edittool’sexpected_hash). Uses the std default hasher for zero deps. - issue_
filename - Filename for an issue: zero-padded 4-digit id + slugified title.
- issues_
dir - Walk up from
startlooking for a.oxi/directory. Returns the path to<root>/.oxi/issues. If no.oxi/exists, returns<start>/.oxi/issues(lazily created on first write). - parse_
issue - Parse a markdown-with-frontmatter file into an
Issue. - serialize_
issue - Serialize an issue back to the markdown-with-frontmatter form.