pub enum HistoryEventKind {
Show 32 variants
RelationshipAdded,
RelationshipRemoved,
RelationshipRetargeted,
BlockedMoveAcknowledged,
ParentSet,
ParentChanged,
ParentCleared,
TransitionAccepted,
TriageAccepted,
TriageDeclined,
TriageDuplicated,
TriageDeferred,
Archived,
Restored,
HealthUpdated,
HealthOverridden,
ProjectAssociated,
ProjectDissociated,
EpicReferenced,
EpicDereferenced,
CycleClosed,
CycleExtended,
CycleSkipped,
CyclePaused,
CycleResumed,
CycleAdjusted,
CycleReopened,
TimeEntryCreated,
TimeEntryUpdated,
TimeEntryDeleted,
EstimateChanged,
CycleMembershipChanged,
}Expand description
What kind of mutation a HistoryEvent records.
Closed set per data-model.md §8. blocked_move_acknowledged is defined
here so WP04 consumes it without editing this file.
Variants§
RelationshipAdded
A relationship was created.
RelationshipRemoved
A relationship was removed.
RelationshipRetargeted
A relationship was retargeted or re-kinded.
BlockedMoveAcknowledged
A move toward completion was confirmed while blockers were open.
ParentSet
An issue gained its first parent.
ParentChanged
An existing parent reference was repointed.
ParentCleared
A parent reference was removed.
TransitionAccepted
A status change was accepted by the transition service and applied.
WP03. The name says accepted because acceptance is the only outcome that
reaches the log: a rejected transition is completely inert and appends
nothing (contract §3.5), and a re-applied transition is idempotent and also
appends nothing. So the presence of this kind in a file is the record
that the change was accepted — a name like transition_attempted would
imply rejections are logged here too, and they are not.
TriageAccepted
A triage inbox issue was accepted into the normal workflow.
WP03 (mission triage-inbox-review-flow-01M3C600). Four triage kinds
rather than one triage_decided for the reason the parent kinds are
separate: the decision is the thing an audit reader is looking for, and
triage_decided — decline … makes them read the detail to learn which of
four mutually exclusive actions was taken. They extend the one #169 log
(research R5) — there is no second log and no triage-specific section.
Only applied decisions reach the log: a refusal appends nothing and a
repeated identical decision is a no-op (contract decision-history.md),
exactly as with HistoryEventKind::TransitionAccepted.
TriageDeclined
A triage inbox issue was declined: moved to the configured declined column, never deleted or archived (C-003).
TriageDuplicated
A triage inbox issue was marked a duplicate of another issue.
The event records the decision; the typed duplicates edge is the
HistoryEventKind::RelationshipAdded entry. One decision, two kinds
only because the relation already has its own kind and inventing a
second spelling for it would leave the graph and the log disagreeing.
TriageDeferred
A triage inbox issue was deferred: it stays in the inbox with a refreshed entry time (data-model §5).
Archived
The issue file was archived: renamed in place to a dot-prefixed name (issue #1492).
Restored
An archived issue was restored to its active name (issue #1492).
HealthUpdated
An issue’s health state was updated, with an actor, a timestamp and a
rationale (mission project-issue-health-status-01M3C8HX, WP02).
One kind for an update and one for an override rather than one
health_changed with a flag: the decision is what an audit reader looks
for, and “somebody changed the health” makes them read the detail to learn
whether it was a measurement or a person overruling one.
HealthOverridden
A manual health override was applied over a derived value (WP02).
ProjectAssociated
An issue gained a project association (mission
first-class-projects-01M3BYBW, WP03).
Two dedicated kinds rather than one generic projects_changed, matching
the three parent kinds and the four triage kinds: the direction of the
change is what an audit reader is looking for, and projects_changed — … would make them read the detail to learn whether an association was
added or removed. The service declares exactly these two as
crate::projects::ProjectEventKind, so the vocabulary is decided once
and mapped here by Self::from_project.
ProjectDissociated
An issue lost a project association (WP03).
EpicReferenced
An issue gained an epic reference (mission
epics-work-items-01M3BYW4, WP03).
Two dedicated kinds rather than one generic epics_changed, matching the
three parent kinds, the four triage kinds, and the two project kinds: the
direction of the change is what an audit reader is looking for, and
epics_changed — … would make them read the detail to learn whether a
reference was added or removed. The service declares exactly these two as
crate::epics::EpicEventKind, so the vocabulary is decided once and
mapped here by Self::from_epic.
EpicDereferenced
An issue lost an epic reference (WP03).
CycleClosed
A generated cycle was explicitly closed, capturing its snapshot.
WP05 of mission repeating-cycle-schedules-01M3C7W1. These six kinds carry
the same append-only grammar as every issue event, but they are written to a
generated cycle record’s own body (docs/cycles/<stem>.md), never to an
issue: a cycle is not an issue, and the mission’s evidence for one is its
record, its snapshot and the cursor. One kind per action rather than one
cycle_lifecycle with a flag, for the same reason the parent/triage/project
kinds are split: the decision is what an audit reader looks for, and a
generic kind would make them read the detail to learn which of five
mutually-exclusive actions was taken.
CycleExtended
A generated cycle’s due date was extended by one cadence period.
CycleSkipped
A generated cycle’s sequence was recorded as skipped.
CyclePaused
A schedule (and its affected instances) was paused.
CycleResumed
A schedule (and its affected instances) was resumed.
CycleAdjusted
A schedule’s future instances were re-derived from its definition.
CycleReopened
A closed cycle was explicitly reopened.
WP04 of mission cycle-capacity-planning-01M3C85C. A closed cycle’s capacity is
the immutable snapshot captured at close (C-008), so reopening it — the one way
its capacity may be configured again — is a capacity-affecting change and is
recorded rather than performed silently. It extends the same cycle family as
HistoryEventKind::CycleClosed and is written to the generated cycle
record’s own body, beside cycle_closed: a cycle’s evidence is its record, its
snapshot and the cursor, and there is no second log. One kind rather than a flag
on cycle_closed, for the reason the other cycle kinds are split — the decision
is what an audit reader looks for. An applied reopen appends exactly one entry;
the prior snapshot and every prior event are retained verbatim.
TimeEntryCreated
A time entry was created on an issue (mission
per-issue-time-tracking-01M3C9A4, WP01 T047).
Pre-declared here, like blocked_move_acknowledged above, so WP02’s mutation
service appends the event without editing this file. Three kinds rather than one
time_changed for the reason the parent, triage, project and epic families are
split: the decision is what an audit reader is looking for, and a generic kind
would make them read the detail to learn whether an entry was added, corrected or
removed. Only an applied mutation appends one (contracts/time-entry.md,
data-model §2): a refused write appends nothing, and the detail carries the
entry id and the created value so the entry is attributable after any later edit.
TimeEntryUpdated
A time entry’s duration, date, author or note was corrected (WP01 T047).
The detail carries the entry id and the before/after values, so the prior value
remains attributable after the correction (C-004). Pre-declared with its siblings
so WP02 never edits this file.
TimeEntryDeleted
A time entry was deleted from an issue’s current projection (WP01 T047).
The entry leaves the issue’s frontmatter and the event, with its prior value, stays in History — a deletion removes the current projection, never the evidence (C-004). Pre-declared with its siblings so WP02 never edits this file.
EstimateChanged
An issue’s estimate value changed (mission
burndown-scope-analytics-01M3C9J1, WP01 T046).
FR-002 distinguishes scope growth from completion, and an estimate change moves
the planned size of the work without changing how many issues are in scope —
so it is a kind of its own rather than a flag on a membership or a status event,
and the analytics classification folds it as estimate_change. This is the one
class the mission’s own table would otherwise never produce: no surface used to
append an event for an estimate edit at all, so the class would have stayed
permanently unknown before an explicit event kind was added for it.
Appended by tix edit --estimate at the seam --parent already appends to,
with the before/after values in detail (estimate: <before> -> <after>,
none for an absent or blank value). An unchanged value appends nothing,
and a refused edit appends nothing — the entry exists only for a change that
was applied.
CycleMembershipChanged
An issue gained or lost a cycle membership (WP01 T046).
One kind rather than two direction-split ones, and that is the documented
exception to the split-by-direction convention the parent/triage/project/epic
families follow: a single --cycles edit routinely adds one cycle and removes
another, so “which direction?” has no single answer to split on. The direction is
therefore in detail — cycles: <before> -> <after>, none for an empty list —
which is what makes the change readable without replaying state.
Appended by tix edit --cycles at the same seam, and only when the membership
actually changed: an unchanged list appends nothing.
Implementations§
Source§impl HistoryEventKind
impl HistoryEventKind
Sourcepub fn is_triage_decision(self) -> bool
pub fn is_triage_decision(self) -> bool
Whether this kind records a triage decision (WP03’s four).
The membership test the decision service’s idempotence check and
not_in_triage/already_decided split both ask, so “is this a triage
decision?” has one answer rather than a four-way matches! at every
call site — where a fifth kind would be forgotten first.
Source§impl HistoryEventKind
impl HistoryEventKind
Sourcepub fn from_parent(kind: ParentEventKind) -> Self
pub fn from_parent(kind: ParentEventKind) -> Self
The model kind for a hierarchy event.
Vocabulary translation, not a rule: the service decides which transition
happened, and this maps that decision onto the log’s spelling. It lives on
the type that owns the log rather than at each call site, because three
callers need it — the storage write path, the --parent edit flag, and MCP’s
update_issue in WP07 — and a mapping repeated three times is one that will
be completed three times and fixed once.
Sourcepub fn from_project(kind: ProjectEventKind) -> Self
pub fn from_project(kind: ProjectEventKind) -> Self
The model kind for a project association event (WP03).
The same vocabulary translation as Self::from_parent: the project
service decides which mutation happened by returning a
crate::projects::ProjectEventKind, and this maps that decision onto the
log’s spelling. It lives on the type that owns the log because more than one
caller needs it — the storage write path, and the CLI/TUI/MCP surfaces that
follow — and a mapping repeated per call site is one that will be completed
per call site and fixed once.
Sourcepub fn from_epic(kind: EpicEventKind) -> Self
pub fn from_epic(kind: EpicEventKind) -> Self
The model kind for an epic reference event (WP03).
The same vocabulary translation as Self::from_project: the epic service
decides which mutation happened by returning a
crate::epics::EpicEventKind, and this maps that decision onto the log’s
spelling. It lives on the type that owns the log because more than one caller
needs it — the storage write path, and the CLI/TUI/MCP surfaces that follow —
and a mapping repeated per call site is one that will be completed per call
site and fixed once.
Trait Implementations§
Source§impl Clone for HistoryEventKind
impl Clone for HistoryEventKind
impl Copy for HistoryEventKind
Source§impl Debug for HistoryEventKind
impl Debug for HistoryEventKind
Source§impl<'de> Deserialize<'de> for HistoryEventKind
impl<'de> Deserialize<'de> for HistoryEventKind
Source§fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where
__D: Deserializer<'de>,
fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where
__D: Deserializer<'de>,
Source§impl Display for HistoryEventKind
impl Display for HistoryEventKind
impl Eq for HistoryEventKind
Source§impl FromStr for HistoryEventKind
impl FromStr for HistoryEventKind
Source§impl Hash for HistoryEventKind
impl Hash for HistoryEventKind
Source§impl Ord for HistoryEventKind
impl Ord for HistoryEventKind
1.21.0 (const: unstable) · Source§fn max(self, other: Self) -> Selfwhere
Self: Sized,
fn max(self, other: Self) -> Selfwhere
Self: Sized,
1.21.0 (const: unstable) · Source§fn min(self, other: Self) -> Selfwhere
Self: Sized,
fn min(self, other: Self) -> Selfwhere
Self: Sized,
Source§impl PartialEq for HistoryEventKind
impl PartialEq for HistoryEventKind
Source§impl PartialOrd for HistoryEventKind
impl PartialOrd for HistoryEventKind
Source§impl Serialize for HistoryEventKind
impl Serialize for HistoryEventKind
impl StructuralPartialEq for HistoryEventKind
Auto Trait Implementations§
impl Freeze for HistoryEventKind
impl RefUnwindSafe for HistoryEventKind
impl Send for HistoryEventKind
impl Sync for HistoryEventKind
impl Unpin for HistoryEventKind
impl UnsafeUnpin for HistoryEventKind
impl UnwindSafe for HistoryEventKind
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<Q, K> Comparable<K> for Q
impl<Q, K> Comparable<K> for Q
impl<T> DeserializeOwned for Twhere
T: for<'de> Deserialize<'de>,
Source§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
Source§fn equivalent(&self, key: &K) -> bool
fn equivalent(&self, key: &K) -> bool
key and return true if they are equal.Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§impl<T> ToCompactString for Twhere
T: Display,
impl<T> ToCompactString for Twhere
T: Display,
Source§fn try_to_compact_string(&self) -> Result<CompactString, ToCompactStringError>
fn try_to_compact_string(&self) -> Result<CompactString, ToCompactStringError>
ToCompactString::to_compact_string() Read moreSource§fn to_compact_string(&self) -> CompactString
fn to_compact_string(&self) -> CompactString
CompactString. Read more