Skip to main content

agentic_time/
inventions.rs

1//! The 16 Temporal Inventions — advanced temporal reasoning capabilities.
2//!
3//! Organized into five categories:
4//!
5//! - **Exploration** (1-3): Temporal Replay, Temporal Cloning, Temporal Echoes
6//! - **Prediction** (4-6): Deadline Prophecy, Causal Archaeology, Future Memory
7//! - **Management** (7-9): Temporal Debt, Chrono-Gravity, Temporal Entanglement
8//! - **Protection** (10-12): Temporal Immune System, Decay Reversal, Time Dilation Awareness
9//! - **Time Travel** (13-16): Temporal Jump, Temporal Anchors, Time Loops, Temporal Wormholes
10
11use chrono::{DateTime, Utc};
12use serde::{Deserialize, Serialize};
13
14use crate::TemporalId;
15
16// ─── EXPLORATION (1-3) ─────────────────────────────────────────────────────────
17
18// ─── 1. Temporal Replay ────────────────────────────────────────────────────────
19
20/// A decision point that could have gone differently.
21#[derive(Debug, Clone, Serialize, Deserialize)]
22pub struct BranchPoint {
23    /// Unique identifier.
24    pub id: TemporalId,
25    /// When the decision was made.
26    pub decided_at: DateTime<Utc>,
27    /// What was decided.
28    pub decision: String,
29    /// All alternatives that were considered.
30    pub alternatives: Vec<Alternative>,
31    /// Snapshot of the context at decision time.
32    pub context_snapshot: serde_json::Value,
33    /// What actually happened after this decision.
34    pub actual_outcome: Option<String>,
35}
36
37/// One possible alternative at a branch point.
38#[derive(Debug, Clone, Serialize, Deserialize)]
39pub struct Alternative {
40    /// Short label for this alternative.
41    pub label: String,
42    /// Detailed description.
43    pub description: String,
44    /// Whether this was the alternative that was actually chosen.
45    pub was_chosen: bool,
46}
47
48/// A forked timeline exploring a different choice.
49#[derive(Debug, Clone, Serialize, Deserialize)]
50pub struct TimelineFork {
51    /// Unique identifier.
52    pub id: TemporalId,
53    /// The branch point this fork diverges from.
54    pub branch_point: TemporalId,
55    /// Index into the branch point's alternatives vec.
56    pub alternative_index: usize,
57    /// Simulated events that would have occurred.
58    pub simulated_events: Vec<SimulatedEvent>,
59    /// Projected outcome of this timeline.
60    pub projected_outcome: String,
61    /// Confidence in this projection (0.0-1.0).
62    pub confidence: f64,
63}
64
65/// A simulated event in a forked timeline.
66#[derive(Debug, Clone, Serialize, Deserialize)]
67pub struct SimulatedEvent {
68    /// When this event would have occurred.
69    pub timestamp: DateTime<Utc>,
70    /// What would have happened.
71    pub description: String,
72    /// Impact magnitude (-1.0 to 1.0, negative = bad).
73    pub impact: f64,
74}
75
76// ─── 2. Temporal Cloning ───────────────────────────────────────────────────────
77
78/// A parallel exploration clone testing a hypothesis.
79#[derive(Debug, Clone, Serialize, Deserialize)]
80pub struct TemporalClone {
81    /// Unique identifier.
82    pub id: TemporalId,
83    /// Parent entity this clone was spawned from.
84    pub parent: TemporalId,
85    /// What this clone is testing.
86    pub hypothesis: String,
87    /// Current status.
88    pub status: CloneStatus,
89    /// Findings discovered during exploration.
90    pub findings: Vec<Finding>,
91    /// How long this clone has been exploring (seconds).
92    pub exploration_time_secs: i64,
93    /// When the clone was created.
94    pub created_at: DateTime<Utc>,
95    /// When the clone finished (if it has).
96    pub completed_at: Option<DateTime<Utc>>,
97}
98
99/// Status of a temporal clone.
100#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
101pub enum CloneStatus {
102    /// Still actively exploring.
103    Exploring,
104    /// Found a viable solution.
105    FoundSolution,
106    /// Ruled out the hypothesis.
107    RuledOut,
108    /// Merged back into the parent.
109    Merged,
110    /// Abandoned without conclusion.
111    Abandoned,
112}
113
114/// A finding from a temporal clone's exploration.
115#[derive(Debug, Clone, Serialize, Deserialize)]
116pub struct Finding {
117    /// What was discovered.
118    pub description: String,
119    /// Confidence in this finding (0.0-1.0).
120    pub confidence: f64,
121    /// Evidence supporting this finding.
122    pub evidence: String,
123}
124
125/// A race between multiple clones to find the best approach.
126#[derive(Debug, Clone, Serialize, Deserialize)]
127pub struct CloneRace {
128    /// Unique identifier.
129    pub id: TemporalId,
130    /// Clones participating in this race.
131    pub clones: Vec<TemporalId>,
132    /// The winning clone (if decided).
133    pub winner: Option<TemporalId>,
134    /// When the race began.
135    pub started_at: DateTime<Utc>,
136}
137
138// ─── 3. Temporal Echoes ────────────────────────────────────────────────────────
139
140/// Ripple effects from a change propagating through time.
141#[derive(Debug, Clone, Serialize, Deserialize)]
142pub struct TemporalEcho {
143    /// Unique identifier.
144    pub id: TemporalId,
145    /// The change that triggered the ripples.
146    pub source_change: String,
147    /// Ripples across different time horizons.
148    pub ripples: Vec<Ripple>,
149    /// Overall impact summary.
150    pub impact_summary: String,
151}
152
153/// A single ripple at a particular time horizon.
154#[derive(Debug, Clone, Serialize, Deserialize)]
155pub struct Ripple {
156    /// When this ripple manifests.
157    pub time_horizon: TimeHorizon,
158    /// Items affected by this ripple.
159    pub affected_items: Vec<AffectedItem>,
160    /// Severity (0.0-1.0).
161    pub severity: f64,
162    /// Whether the ripple's effects can be undone.
163    pub reversible: bool,
164}
165
166/// How far into the future a ripple reaches.
167#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
168pub enum TimeHorizon {
169    /// Minutes to hours.
170    Immediate,
171    /// Hours to days.
172    ShortTerm,
173    /// Days to weeks.
174    MediumTerm,
175    /// Weeks to months.
176    LongTerm,
177    /// Months to years.
178    Extended,
179}
180
181/// An item affected by a temporal ripple.
182#[derive(Debug, Clone, Serialize, Deserialize)]
183pub struct AffectedItem {
184    /// ID of the affected entity.
185    pub entity_id: TemporalId,
186    /// Description of how it is affected.
187    pub description: String,
188    /// Impact magnitude (0.0-1.0).
189    pub impact: f64,
190}
191
192// ─── PREDICTION (4-6) ──────────────────────────────────────────────────────────
193
194// ─── 4. Deadline Prophecy ──────────────────────────────────────────────────────
195
196/// A prediction about whether a deadline will be met.
197#[derive(Debug, Clone, Serialize, Deserialize)]
198pub struct DeadlineProphecy {
199    /// Unique identifier.
200    pub id: TemporalId,
201    /// The deadline being prophesied about.
202    pub deadline_id: TemporalId,
203    /// Probability of meeting the deadline (0.0-1.0).
204    pub success_probability: f64,
205    /// Factors influencing the prophecy.
206    pub factors: Vec<ProphecyFactor>,
207    /// Possible interventions to improve odds.
208    pub interventions: Vec<Intervention>,
209    /// When this prophecy was made.
210    pub prophesied_at: DateTime<Utc>,
211    /// How accurate past prophecies have been (0.0-1.0).
212    pub historical_accuracy: f64,
213}
214
215/// A factor influencing a deadline prophecy.
216#[derive(Debug, Clone, Serialize, Deserialize)]
217pub struct ProphecyFactor {
218    /// Name of the factor.
219    pub name: String,
220    /// How much this factor impacts the prophecy (-1.0 to 1.0).
221    pub impact: f64,
222    /// Confidence in this factor's assessment (0.0-1.0).
223    pub confidence: f64,
224    /// Evidence for this factor.
225    pub evidence: String,
226}
227
228/// A possible intervention to improve deadline success.
229#[derive(Debug, Clone, Serialize, Deserialize)]
230pub struct Intervention {
231    /// What action to take.
232    pub action: String,
233    /// Success probability after this intervention (0.0-1.0).
234    pub success_probability_after: f64,
235    /// Cost description.
236    pub cost: String,
237    /// Whether this intervention is recommended.
238    pub recommended: bool,
239}
240
241// ─── 5. Causal Archaeology ─────────────────────────────────────────────────────
242
243/// An excavation into the root cause of a problem.
244#[derive(Debug, Clone, Serialize, Deserialize)]
245pub struct CausalExcavation {
246    /// Unique identifier.
247    pub id: TemporalId,
248    /// The problem being investigated.
249    pub problem: String,
250    /// The identified root cause.
251    pub root_cause: CausalEvent,
252    /// The chain of events from root cause to problem.
253    pub causal_chain: Vec<CausalEvent>,
254    /// Points where the chain could have been broken.
255    pub inflection_points: Vec<InflectionPoint>,
256    /// Recurring patterns found during excavation.
257    pub patterns: Vec<CausalPattern>,
258}
259
260/// An event in a causal chain.
261#[derive(Debug, Clone, Serialize, Deserialize)]
262pub struct CausalEvent {
263    /// When the event occurred.
264    pub timestamp: DateTime<Utc>,
265    /// What happened.
266    pub description: String,
267    /// Type of causal event.
268    pub event_type: CausalEventType,
269    /// What this event led to.
270    pub led_to: Vec<String>,
271}
272
273/// Classification of a causal event.
274#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
275pub enum CausalEventType {
276    /// A deliberate choice.
277    Decision,
278    /// Something from outside the system.
279    ExternalEvent,
280    /// Failure to act.
281    Inaction,
282    /// Communication breakdown.
283    Miscommunication,
284    /// Something broke.
285    TechnicalFailure,
286}
287
288/// A point where a different action could have changed the outcome.
289#[derive(Debug, Clone, Serialize, Deserialize)]
290pub struct InflectionPoint {
291    /// The event at this inflection point.
292    pub event: CausalEvent,
293    /// What could have been done differently.
294    pub alternative_action: String,
295    /// Estimated impact of the alternative.
296    pub estimated_impact: String,
297}
298
299/// A recurring causal pattern.
300#[derive(Debug, Clone, Serialize, Deserialize)]
301pub struct CausalPattern {
302    /// Description of the pattern.
303    pub description: String,
304    /// How many times this pattern has occurred.
305    pub occurrences: u32,
306    /// Severity of this pattern (0.0-1.0).
307    pub severity: f64,
308}
309
310// ─── 6. Future Memory ──────────────────────────────────────────────────────────
311
312/// Pre-loaded context for an upcoming event.
313#[derive(Debug, Clone, Serialize, Deserialize)]
314pub struct FutureMemory {
315    /// Unique identifier.
316    pub id: TemporalId,
317    /// The event this memory is for.
318    pub event_id: TemporalId,
319    /// When the event occurs.
320    pub event_time: DateTime<Utc>,
321    /// Relevant context items.
322    pub context_items: Vec<ContextItem>,
323    /// Data precomputed for quick access.
324    pub precomputed: Vec<PrecomputedData>,
325    /// Suggested areas of focus.
326    pub suggested_focus: Vec<String>,
327    /// When this future memory was created.
328    pub created_at: DateTime<Utc>,
329}
330
331/// A piece of context relevant to a future event.
332#[derive(Debug, Clone, Serialize, Deserialize)]
333pub struct ContextItem {
334    /// Short label.
335    pub label: String,
336    /// Type of content.
337    pub content_type: ContextType,
338    /// The actual content.
339    pub content: String,
340    /// How relevant this is (0.0-1.0).
341    pub relevance: f64,
342}
343
344/// Classification of context content.
345#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
346pub enum ContextType {
347    /// A document.
348    Document,
349    /// Notes from a previous meeting.
350    PreviousMeeting,
351    /// A related task.
352    RelatedTask,
353    /// Information about a person.
354    PersonInfo,
355    /// A metric or data point.
356    Metric,
357}
358
359/// Data precomputed for a future event.
360#[derive(Debug, Clone, Serialize, Deserialize)]
361pub struct PrecomputedData {
362    /// Label for this data.
363    pub label: String,
364    /// The precomputed data.
365    pub data: serde_json::Value,
366}
367
368// ─── MANAGEMENT (7-9) ──────────────────────────────────────────────────────────
369
370// ─── 7. Temporal Debt ──────────────────────────────────────────────────────────
371
372/// A unit of temporal debt — postponed work that compounds over time.
373#[derive(Debug, Clone, Serialize, Deserialize)]
374pub struct TemporalDebt {
375    /// Unique identifier.
376    pub id: TemporalId,
377    /// What was deferred.
378    pub description: String,
379    /// Original time cost in minutes.
380    pub principal_minutes: u32,
381    /// Interest rate (fraction per compound period).
382    pub interest_rate: f64,
383    /// How often interest compounds (seconds).
384    pub compound_period_secs: i64,
385    /// When the debt was incurred.
386    pub incurred_at: DateTime<Utc>,
387    /// Current total including interest (minutes).
388    pub current_total_minutes: u32,
389    /// What this debt is blocking.
390    pub blocking: Vec<String>,
391    /// Category of debt.
392    pub category: DebtCategory,
393    /// When the debt was paid off (if it has been).
394    pub paid_at: Option<DateTime<Utc>>,
395}
396
397/// Category of temporal debt.
398#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
399pub enum DebtCategory {
400    /// Deferred tests.
401    Testing,
402    /// Missing or outdated documentation.
403    Documentation,
404    /// Code that needs restructuring.
405    Refactoring,
406    /// Security improvements deferred.
407    Security,
408    /// Performance optimizations deferred.
409    Performance,
410}
411
412/// A report summarizing all temporal debt.
413#[derive(Debug, Clone, Serialize, Deserialize)]
414pub struct DebtReport {
415    /// Total debt across all items (minutes).
416    pub total_debt_minutes: u32,
417    /// Individual debt items.
418    pub items: Vec<TemporalDebt>,
419    /// Interest accruing per week (minutes).
420    pub interest_per_week_minutes: u32,
421    /// Recommended payoff order.
422    pub recommendations: Vec<PayoffRecommendation>,
423}
424
425/// A recommendation for paying off a specific debt.
426#[derive(Debug, Clone, Serialize, Deserialize)]
427pub struct PayoffRecommendation {
428    /// Which debt to pay off.
429    pub debt_id: TemporalId,
430    /// Current cost to pay it off (minutes).
431    pub current_cost_minutes: u32,
432    /// What it will cost if left unpaid (minutes).
433    pub future_cost_if_unpaid: u32,
434    /// Return on investment of paying now vs. later.
435    pub roi_percentage: f64,
436}
437
438impl TemporalDebt {
439    /// Create a new temporal debt with default 10% interest rate and 7-day compound period.
440    pub fn new(description: &str, principal_minutes: u32, category: DebtCategory) -> Self {
441        let now = Utc::now();
442        Self {
443            id: TemporalId::new(),
444            description: description.to_string(),
445            principal_minutes,
446            interest_rate: 0.1,
447            compound_period_secs: 7 * 24 * 3600, // 7 days
448            incurred_at: now,
449            current_total_minutes: principal_minutes,
450            blocking: Vec::new(),
451            category,
452            paid_at: None,
453        }
454    }
455
456    /// Calculate the current total debt including compound interest.
457    ///
458    /// Uses the formula: P * (1 + r)^n where:
459    /// - P = principal_minutes
460    /// - r = interest_rate per compound period
461    /// - n = number of compound periods elapsed
462    pub fn calculate_current_total(&self) -> u32 {
463        if self.paid_at.is_some() {
464            return self.current_total_minutes;
465        }
466
467        let elapsed_secs = (Utc::now() - self.incurred_at).num_seconds();
468        if elapsed_secs <= 0 || self.compound_period_secs <= 0 {
469            return self.principal_minutes;
470        }
471
472        let periods = elapsed_secs as f64 / self.compound_period_secs as f64;
473        let total = self.principal_minutes as f64 * (1.0 + self.interest_rate).powf(periods);
474        total.round() as u32
475    }
476
477    /// Mark this debt as paid at the current timestamp.
478    pub fn pay(&mut self) {
479        self.current_total_minutes = self.calculate_current_total();
480        self.paid_at = Some(Utc::now());
481    }
482}
483
484// ─── 8. Chrono-Gravity ─────────────────────────────────────────────────────────
485
486/// A high-mass temporal event that pulls other items toward it.
487#[derive(Debug, Clone, Serialize, Deserialize)]
488pub struct ChronoGravity {
489    /// Unique identifier.
490    pub id: TemporalId,
491    /// The event exerting gravitational pull.
492    pub event_id: TemporalId,
493    /// Gravitational mass (importance/urgency).
494    pub mass: f64,
495    /// Radius of influence in days.
496    pub radius_days: u32,
497    /// Point of no return — after this, everything gets pulled in.
498    pub event_horizon: Option<DateTime<Utc>>,
499    /// Items being attracted.
500    pub attracted_items: Vec<AttractedItem>,
501    /// Time dilation factor near this event.
502    pub time_dilation_factor: f64,
503}
504
505/// An item being pulled by chrono-gravity.
506#[derive(Debug, Clone, Serialize, Deserialize)]
507pub struct AttractedItem {
508    /// The item being attracted.
509    pub item_id: TemporalId,
510    /// Type of the item.
511    pub item_type: String,
512    /// How strongly it is being pulled (0.0-1.0).
513    pub pull_strength: f64,
514    /// Whether this item will reach the event in time.
515    pub will_reach_event: bool,
516}
517
518/// A conflict when two gravity wells pull the same item.
519#[derive(Debug, Clone, Serialize, Deserialize)]
520pub struct GravityConflict {
521    /// The item being pulled in two directions.
522    pub item_id: TemporalId,
523    /// Gravity wells pulling this item.
524    pub pulled_by: Vec<TemporalId>,
525    /// Whether this conflict needs resolution.
526    pub resolution_needed: bool,
527    /// Suggested resolution.
528    pub suggested_resolution: String,
529}
530
531// ─── 9. Temporal Entanglement ──────────────────────────────────────────────────
532
533/// A quantum-like link between temporal entities that must move together.
534#[derive(Debug, Clone, Serialize, Deserialize)]
535pub struct TemporalEntanglement {
536    /// Unique identifier.
537    pub id: TemporalId,
538    /// Entangled entities.
539    pub entities: Vec<TemporalId>,
540    /// How they are entangled.
541    pub entanglement_type: EntanglementType,
542    /// Whether this entanglement is still active.
543    pub active: bool,
544    /// When this entanglement was created.
545    pub created_at: DateTime<Utc>,
546    /// Notification channels for entanglement violations.
547    pub notify: Vec<String>,
548}
549
550/// How two entities are temporally entangled.
551#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
552pub enum EntanglementType {
553    /// Move together — if one shifts, the other shifts identically.
554    Sync,
555    /// Must happen in sequence with a fixed gap.
556    Sequence {
557        /// Gap between events in seconds.
558        gap_secs: i64,
559    },
560    /// Mirror — if one moves forward, the other moves backward.
561    Mirror,
562    /// Inverse — if one succeeds, the other fails.
563    Inverse,
564    /// If one fails, the failure propagates.
565    FailurePropagation,
566}
567
568// ─── PROTECTION (10-12) ────────────────────────────────────────────────────────
569
570// ─── 10. Temporal Immune System ────────────────────────────────────────────────
571
572/// An anomaly detected in the temporal graph.
573#[derive(Debug, Clone, Serialize, Deserialize)]
574pub struct TemporalAnomaly {
575    /// Unique identifier.
576    pub id: TemporalId,
577    /// Type of anomaly.
578    pub anomaly_type: AnomalyType,
579    /// Severity (0.0-1.0).
580    pub severity: f64,
581    /// Entities involved in this anomaly.
582    pub involved_entities: Vec<TemporalId>,
583    /// Human-readable description.
584    pub description: String,
585    /// Possible resolutions.
586    pub resolutions: Vec<Resolution>,
587    /// When the anomaly was detected.
588    pub detected_at: DateTime<Utc>,
589}
590
591/// Classification of temporal anomalies.
592#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
593pub enum AnomalyType {
594    /// A circular dependency in the temporal graph.
595    DependencyCycle,
596    /// Too many items scheduled in the same period.
597    CapacityOverflow,
598    /// An effect precedes its cause.
599    CausalityViolation,
600    /// Conflicting entanglements.
601    EntanglementConflict,
602    /// Two gravity wells fighting over the same item.
603    GravityConflict,
604    /// A deadline that cannot possibly be met.
605    ImpossibleDeadline,
606}
607
608/// A possible resolution for an anomaly.
609#[derive(Debug, Clone, Serialize, Deserialize)]
610pub struct Resolution {
611    /// What action to take.
612    pub action: String,
613    /// Whether this action fully removes the anomaly.
614    pub removes_anomaly: bool,
615    /// Side effects of this resolution.
616    pub side_effects: Vec<String>,
617}
618
619/// Overall immune system health status.
620#[derive(Debug, Clone, Serialize, Deserialize)]
621pub struct ImmuneStatus {
622    /// Number of active anomalies.
623    pub anomaly_count: u32,
624    /// All detected anomalies.
625    pub anomalies: Vec<TemporalAnomaly>,
626    /// When the last scan was performed.
627    pub last_scan: DateTime<Utc>,
628    /// Overall health score (0.0-1.0, higher is healthier).
629    pub health_score: f64,
630}
631
632// ─── 11. Decay Reversal ────────────────────────────────────────────────────────
633
634/// Options for reversing temporal decay.
635#[derive(Debug, Clone, Serialize, Deserialize)]
636pub struct DecayReversal {
637    /// Unique identifier.
638    pub id: TemporalId,
639    /// The decay model to reverse.
640    pub decay_id: TemporalId,
641    /// Current decayed value.
642    pub current_value: f64,
643    /// Target value to restore to.
644    pub target_value: f64,
645    /// Available reversal options.
646    pub options: Vec<ReversalOption>,
647    /// Index of the recommended option (if any).
648    pub recommended: Option<usize>,
649}
650
651/// A specific option for reversing decay.
652#[derive(Debug, Clone, Serialize, Deserialize)]
653pub struct ReversalOption {
654    /// Name of this reversal strategy.
655    pub name: String,
656    /// Time required to complete the reversal (seconds).
657    pub time_required_secs: i64,
658    /// Value after reversal is applied.
659    pub restored_value: f64,
660    /// Steps to complete this reversal.
661    pub steps: Vec<String>,
662    /// How long the reversal will last before decay resumes (seconds).
663    pub durability_secs: i64,
664}
665
666// ─── 12. Time Dilation Awareness ───────────────────────────────────────────────
667
668/// A model of how time perception varies by activity and energy.
669#[derive(Debug, Clone, Serialize, Deserialize)]
670pub struct TimeDilationModel {
671    /// Unique identifier.
672    pub id: TemporalId,
673    /// How different activities dilate time.
674    pub activity_factors: Vec<ActivityDilation>,
675    /// Energy level curve over the day: (hour, energy_level).
676    pub energy_curve: Vec<(u32, f64)>,
677    /// Weekly productivity pattern: (day_name, productivity_factor).
678    pub weekly_pattern: Vec<(String, f64)>,
679}
680
681/// How a specific activity dilates perceived time.
682#[derive(Debug, Clone, Serialize, Deserialize)]
683pub struct ActivityDilation {
684    /// Name of the activity.
685    pub activity: String,
686    /// Dilation factor (>1.0 = time flies, <1.0 = time drags).
687    pub dilation_factor: f64,
688    /// Energy cost (0.0-1.0).
689    pub energy_cost: f64,
690    /// Best hours of the day for this activity (0-23).
691    pub optimal_hours: Vec<u32>,
692}
693
694/// A report on subjective time for a period.
695#[derive(Debug, Clone, Serialize, Deserialize)]
696pub struct SubjectiveTimeReport {
697    /// Start of the period.
698    pub period_start: DateTime<Utc>,
699    /// End of the period.
700    pub period_end: DateTime<Utc>,
701    /// Actual wall-clock hours.
702    pub clock_hours: f64,
703    /// Perceived productive hours.
704    pub perceived_productive_hours: f64,
705    /// Perceived wasted hours.
706    pub perceived_wasted_hours: f64,
707    /// Total perceived hours (productive + wasted, may differ from clock).
708    pub total_perceived_hours: f64,
709    /// Recommendations for improving time perception.
710    pub recommendations: Vec<String>,
711}
712
713// ─── EntityType extensions needed ──────────────────────────────────────────────
714//
715// The following new EntityType variants will be needed in `file_format::EntityType`
716// to store these inventions in `.atime` files:
717//
718//   BranchPoint      = 10,
719//   TimelineFork     = 11,
720//   TemporalClone    = 12,
721//   CloneRace        = 13,
722//   TemporalEcho     = 14,
723//   DeadlineProphecy = 15,
724//   CausalExcavation = 16,
725//   FutureMemory     = 17,
726//   TemporalDebt     = 18,
727//   ChronoGravity    = 19,
728//   TemporalEntanglement = 20,
729//   TemporalAnomaly  = 21,
730//   ImmuneStatus     = 22,
731//   DecayReversal    = 23,
732//   TimeDilationModel = 24,
733//   SubjectiveTimeReport = 25,
734//
735//   TIME TRAVEL INVENTIONS (26-35):
736//   TemporalJump     = 26,
737//   JumpPoint        = 27,
738//   TemporalAnchor   = 28,
739//   StateSnapshot    = 29,
740//   TimeLoop         = 30,
741//   LoopPattern      = 31,
742//   LoopBreaker      = 32,
743//   TemporalWormhole = 33,
744//   WormholeEndpoint = 34,
745//   WormholeInsight  = 35,
746
747// ─── TIME TRAVEL INVENTIONS (13-16) ─────────────────────────────────────────────
748
749// ─── 13. Temporal Jump ──────────────────────────────────────────────────────────
750
751/// A cognitive teleportation to any point in a project's timeline.
752#[derive(Debug, Clone, Serialize, Deserialize)]
753pub struct TemporalJump {
754    /// Jump identifier.
755    pub id: TemporalId,
756    /// Current temporal position.
757    pub current_position: DateTime<Utc>,
758    /// Origin (where we jumped from).
759    pub origin: DateTime<Utc>,
760    /// What was known at this time.
761    pub known_facts: Vec<KnownFact>,
762    /// What was unknown (hindsight from future).
763    pub unknown_facts: Vec<UnknownFact>,
764    /// Breadcrumb trail (for returning).
765    pub jump_history: Vec<JumpPoint>,
766    /// Is this an active jump?
767    pub active: bool,
768    /// Created at.
769    pub created_at: DateTime<Utc>,
770}
771
772/// A fact that was known at a given point in time.
773#[derive(Debug, Clone, Serialize, Deserialize)]
774pub struct KnownFact {
775    /// The fact.
776    pub fact: String,
777    /// Source of the fact.
778    pub source: String,
779    /// Confidence at the time.
780    pub confidence_at_time: f64,
781}
782
783/// A fact that was NOT known at a given point (discovered later).
784#[derive(Debug, Clone, Serialize, Deserialize)]
785pub struct UnknownFact {
786    /// What wasn't known.
787    pub fact: String,
788    /// When it became known.
789    pub discovered_at: DateTime<Utc>,
790    /// Impact of not knowing.
791    pub impact: String,
792    /// Signals that could have revealed it.
793    pub missed_signals: Vec<String>,
794}
795
796/// A point in the jump history breadcrumb trail.
797#[derive(Debug, Clone, Serialize, Deserialize)]
798pub struct JumpPoint {
799    /// The timestamp jumped to.
800    pub timestamp: DateTime<Utc>,
801    /// When the jump was made.
802    pub jumped_at: DateTime<Utc>,
803    /// Why the jump was made.
804    pub reason: String,
805}
806
807impl TemporalJump {
808    /// Create a new temporal jump to a destination time.
809    pub fn new(destination: DateTime<Utc>) -> Self {
810        let now = Utc::now();
811        Self {
812            id: TemporalId::new(),
813            current_position: destination,
814            origin: now,
815            known_facts: Vec::new(),
816            unknown_facts: Vec::new(),
817            jump_history: vec![JumpPoint {
818                timestamp: destination,
819                jumped_at: now,
820                reason: "Initial jump".to_string(),
821            }],
822            active: true,
823            created_at: now,
824        }
825    }
826
827    /// Return to origin time.
828    pub fn return_to_origin(&mut self) {
829        self.active = false;
830        self.jump_history.push(JumpPoint {
831            timestamp: self.origin,
832            jumped_at: Utc::now(),
833            reason: "Return to origin".to_string(),
834        });
835        self.current_position = self.origin;
836    }
837}
838
839// ─── 14. Temporal Anchors ───────────────────────────────────────────────────────
840
841/// A save point in time that captures full cognitive context.
842#[derive(Debug, Clone, Serialize, Deserialize)]
843pub struct TemporalAnchor {
844    /// Anchor identifier.
845    pub id: TemporalId,
846    /// Human-readable name.
847    pub name: String,
848    /// When anchor was created.
849    pub anchored_at: DateTime<Utc>,
850    /// Full state snapshot.
851    pub state_snapshot: StateSnapshot,
852    /// Why this anchor was created.
853    pub reason: String,
854    /// Tags for organization.
855    pub tags: Vec<String>,
856    /// Expiration (optional).
857    pub expires_at: Option<DateTime<Utc>>,
858    /// Times this anchor has been jumped to.
859    pub jump_count: u32,
860    /// Last jumped to.
861    pub last_jumped_at: Option<DateTime<Utc>>,
862}
863
864/// A captured state snapshot at an anchor point.
865#[derive(Debug, Clone, Serialize, Deserialize)]
866pub struct StateSnapshot {
867    /// Codebase understanding at this point.
868    pub codebase_state: Option<String>,
869    /// Memory/decisions at this point.
870    pub memory_state: Option<String>,
871    /// Active temporal entity IDs.
872    pub active_deadlines: Vec<TemporalId>,
873    /// Active schedule IDs.
874    pub active_schedules: Vec<TemporalId>,
875    /// Active sequence IDs.
876    pub active_sequences: Vec<TemporalId>,
877    /// Decay model values at snapshot time.
878    pub decay_values: Vec<(TemporalId, f64)>,
879    /// User's mental model description.
880    pub mental_model: Option<String>,
881    /// Integrity checksum.
882    pub checksum: String,
883}
884
885/// Result of jumping to an anchor.
886#[derive(Debug, Clone, Serialize, Deserialize)]
887pub struct AnchorJumpResult {
888    /// The anchor we jumped to.
889    pub anchor_id: TemporalId,
890    /// Anchor name.
891    pub anchor_name: String,
892    /// When anchor was created.
893    pub anchored_at: DateTime<Utc>,
894    /// Knowledge preserved from the future (what we learned since anchor).
895    pub future_knowledge: Vec<String>,
896    /// What's different between anchor and now.
897    pub divergence_summary: String,
898}
899
900impl TemporalAnchor {
901    /// Create a new temporal anchor.
902    pub fn new(name: impl Into<String>, reason: impl Into<String>) -> Self {
903        Self {
904            id: TemporalId::new(),
905            name: name.into(),
906            anchored_at: Utc::now(),
907            state_snapshot: StateSnapshot {
908                codebase_state: None,
909                memory_state: None,
910                active_deadlines: Vec::new(),
911                active_schedules: Vec::new(),
912                active_sequences: Vec::new(),
913                decay_values: Vec::new(),
914                mental_model: None,
915                checksum: String::new(),
916            },
917            reason: reason.into(),
918            tags: Vec::new(),
919            expires_at: None,
920            jump_count: 0,
921            last_jumped_at: None,
922        }
923    }
924
925    /// Check if anchor has expired.
926    pub fn is_expired(&self) -> bool {
927        self.expires_at.map(|exp| Utc::now() > exp).unwrap_or(false)
928    }
929
930    /// Record a jump to this anchor.
931    pub fn record_jump(&mut self) {
932        self.jump_count += 1;
933        self.last_jumped_at = Some(Utc::now());
934    }
935}
936
937// ─── 15. Time Loops ─────────────────────────────────────────────────────────────
938
939/// A detected repetitive pattern that wastes time.
940#[derive(Debug, Clone, Serialize, Deserialize)]
941pub struct TimeLoop {
942    /// Loop identifier.
943    pub id: TemporalId,
944    /// Pattern signature.
945    pub pattern: LoopPattern,
946    /// Detected iterations.
947    pub iterations: Vec<LoopIteration>,
948    /// Total time spent in this loop (seconds).
949    pub total_time_spent_secs: i64,
950    /// Is the loop currently active?
951    pub active: bool,
952    /// Root cause analysis.
953    pub root_cause: Option<RootCauseAnalysis>,
954    /// Suggested loop breaker.
955    pub breaker: Option<LoopBreaker>,
956    /// When this loop was first detected.
957    pub detected_at: DateTime<Utc>,
958}
959
960/// The repeating pattern within a time loop.
961#[derive(Debug, Clone, Serialize, Deserialize)]
962pub struct LoopPattern {
963    /// Actions that repeat.
964    pub repeating_actions: Vec<String>,
965    /// What triggers each iteration.
966    pub trigger: String,
967    /// Expected outcome (never achieved).
968    pub expected_outcome: String,
969    /// Actual outcome (repeated).
970    pub actual_outcome: String,
971    /// Similarity score for detection (0.0-1.0).
972    pub similarity_score: f64,
973}
974
975/// A single iteration within a time loop.
976#[derive(Debug, Clone, Serialize, Deserialize)]
977pub struct LoopIteration {
978    /// Iteration number.
979    pub number: u32,
980    /// When this iteration started.
981    pub started_at: DateTime<Utc>,
982    /// When this iteration ended.
983    pub ended_at: Option<DateTime<Utc>>,
984    /// What was tried.
985    pub action_taken: String,
986    /// What happened.
987    pub result: String,
988    /// Duration in seconds.
989    pub duration_secs: i64,
990}
991
992/// Root cause analysis for why a loop persists.
993#[derive(Debug, Clone, Serialize, Deserialize)]
994pub struct RootCauseAnalysis {
995    /// The actual root cause.
996    pub root_cause: String,
997    /// Why the repeated fix doesn't work.
998    pub why_fix_fails: String,
999    /// Evidence for this analysis.
1000    pub evidence: Vec<String>,
1001    /// Confidence in analysis (0.0-1.0).
1002    pub confidence: f64,
1003}
1004
1005/// A recommendation for breaking a time loop.
1006#[derive(Debug, Clone, Serialize, Deserialize)]
1007pub struct LoopBreaker {
1008    /// Recommended action to break the loop.
1009    pub action: String,
1010    /// Why this will break the loop.
1011    pub rationale: String,
1012    /// Estimated time to implement (seconds).
1013    pub estimated_time_secs: i64,
1014    /// Expected outcome after breaking.
1015    pub expected_outcome: String,
1016    /// Confidence this will work (0.0-1.0).
1017    pub confidence: f64,
1018}
1019
1020impl TimeLoop {
1021    /// Create a new time loop detection.
1022    pub fn new(pattern: LoopPattern) -> Self {
1023        Self {
1024            id: TemporalId::new(),
1025            pattern,
1026            iterations: Vec::new(),
1027            total_time_spent_secs: 0,
1028            active: true,
1029            root_cause: None,
1030            breaker: None,
1031            detected_at: Utc::now(),
1032        }
1033    }
1034
1035    /// Add an iteration to this loop.
1036    pub fn add_iteration(&mut self, iteration: LoopIteration) {
1037        self.total_time_spent_secs += iteration.duration_secs;
1038        self.iterations.push(iteration);
1039    }
1040
1041    /// Get the number of iterations.
1042    pub fn iteration_count(&self) -> u32 {
1043        self.iterations.len() as u32
1044    }
1045
1046    /// Mark loop as broken.
1047    pub fn mark_broken(&mut self) {
1048        self.active = false;
1049    }
1050}
1051
1052// ─── 16. Temporal Wormholes ─────────────────────────────────────────────────────
1053
1054/// A bidirectional connection between two distant points in time.
1055#[derive(Debug, Clone, Serialize, Deserialize)]
1056pub struct TemporalWormhole {
1057    /// Wormhole identifier.
1058    pub id: TemporalId,
1059    /// First endpoint (usually earlier).
1060    pub endpoint_a: WormholeEndpoint,
1061    /// Second endpoint (usually later).
1062    pub endpoint_b: WormholeEndpoint,
1063    /// Causal relationship description.
1064    pub relationship: String,
1065    /// Insights transmitted through wormhole.
1066    pub transmitted_insights: Vec<WormholeInsight>,
1067    /// Is wormhole active?
1068    pub active: bool,
1069    /// Created at.
1070    pub created_at: DateTime<Utc>,
1071    /// Times queried.
1072    pub query_count: u32,
1073}
1074
1075/// One end of a temporal wormhole.
1076#[derive(Debug, Clone, Serialize, Deserialize)]
1077pub struct WormholeEndpoint {
1078    /// Point in time.
1079    pub timestamp: DateTime<Utc>,
1080    /// Label for this endpoint.
1081    pub label: String,
1082    /// What happened here.
1083    pub event_description: String,
1084    /// Related temporal entities.
1085    pub related_entities: Vec<TemporalId>,
1086    /// Context at this point.
1087    pub context_summary: String,
1088}
1089
1090/// An insight transmitted through a wormhole.
1091#[derive(Debug, Clone, Serialize, Deserialize)]
1092pub struct WormholeInsight {
1093    /// Direction of insight.
1094    pub direction: InsightDirection,
1095    /// The insight content.
1096    pub insight: String,
1097    /// When this insight was transmitted.
1098    pub transmitted_at: DateTime<Utc>,
1099    /// Impact of this insight.
1100    pub impact: String,
1101}
1102
1103/// Direction of information flow through a wormhole.
1104#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
1105pub enum InsightDirection {
1106    /// Past informing future (understanding why).
1107    PastToFuture,
1108    /// Future informing past (hindsight annotation).
1109    FutureToPast,
1110    /// Bidirectional.
1111    Bidirectional,
1112}
1113
1114impl TemporalWormhole {
1115    /// Create a new temporal wormhole connecting two time points.
1116    pub fn new(
1117        endpoint_a: WormholeEndpoint,
1118        endpoint_b: WormholeEndpoint,
1119        relationship: impl Into<String>,
1120    ) -> Self {
1121        Self {
1122            id: TemporalId::new(),
1123            endpoint_a,
1124            endpoint_b,
1125            relationship: relationship.into(),
1126            transmitted_insights: Vec::new(),
1127            active: true,
1128            created_at: Utc::now(),
1129            query_count: 0,
1130        }
1131    }
1132
1133    /// Add an insight to the wormhole.
1134    pub fn transmit_insight(
1135        &mut self,
1136        direction: InsightDirection,
1137        insight: String,
1138        impact: String,
1139    ) {
1140        self.transmitted_insights.push(WormholeInsight {
1141            direction,
1142            insight,
1143            transmitted_at: Utc::now(),
1144            impact,
1145        });
1146    }
1147
1148    /// Record a query through this wormhole.
1149    pub fn record_query(&mut self) {
1150        self.query_count += 1;
1151    }
1152
1153    /// Close the wormhole.
1154    pub fn close(&mut self) {
1155        self.active = false;
1156    }
1157}
1158
1159#[cfg(test)]
1160mod tests {
1161    use super::*;
1162    use chrono::Duration as ChronoDuration;
1163
1164    #[test]
1165    fn test_temporal_debt_new_defaults() {
1166        let debt = TemporalDebt::new("Write unit tests", 60, DebtCategory::Testing);
1167        assert_eq!(debt.principal_minutes, 60);
1168        assert_eq!(debt.current_total_minutes, 60);
1169        assert!((debt.interest_rate - 0.1).abs() < f64::EPSILON);
1170        assert_eq!(debt.compound_period_secs, 7 * 24 * 3600);
1171        assert!(debt.paid_at.is_none());
1172        assert!(debt.blocking.is_empty());
1173        assert_eq!(debt.category, DebtCategory::Testing);
1174    }
1175
1176    #[test]
1177    fn test_temporal_debt_no_interest_before_first_period() {
1178        let debt = TemporalDebt::new("Fresh debt", 100, DebtCategory::Documentation);
1179        // Just created, so elapsed time is ~0 — should return principal.
1180        let total = debt.calculate_current_total();
1181        assert_eq!(total, 100);
1182    }
1183
1184    #[test]
1185    fn test_temporal_debt_compound_interest_one_period() {
1186        let mut debt = TemporalDebt::new("Old debt", 100, DebtCategory::Refactoring);
1187        // Backdate by exactly one compound period (7 days).
1188        debt.incurred_at = Utc::now() - ChronoDuration::seconds(debt.compound_period_secs);
1189
1190        let total = debt.calculate_current_total();
1191        // After 1 period at 10%: 100 * 1.1^1 = 110
1192        assert_eq!(total, 110);
1193    }
1194
1195    #[test]
1196    fn test_temporal_debt_compound_interest_two_periods() {
1197        let mut debt = TemporalDebt::new("Older debt", 100, DebtCategory::Security);
1198        // Backdate by exactly two compound periods (14 days).
1199        debt.incurred_at = Utc::now() - ChronoDuration::seconds(2 * debt.compound_period_secs);
1200
1201        let total = debt.calculate_current_total();
1202        // After 2 periods at 10%: 100 * 1.1^2 = 121
1203        assert_eq!(total, 121);
1204    }
1205
1206    #[test]
1207    fn test_temporal_debt_pay_freezes_total() {
1208        let mut debt = TemporalDebt::new("Pay me", 100, DebtCategory::Performance);
1209        // Backdate by one period.
1210        debt.incurred_at = Utc::now() - ChronoDuration::seconds(debt.compound_period_secs);
1211
1212        debt.pay();
1213        assert!(debt.paid_at.is_some());
1214        assert_eq!(debt.current_total_minutes, 110);
1215
1216        // After paying, calculate_current_total should return the frozen value.
1217        let total = debt.calculate_current_total();
1218        assert_eq!(total, 110);
1219    }
1220
1221    #[test]
1222    fn test_temporal_debt_custom_rate() {
1223        let mut debt = TemporalDebt::new("Custom rate", 200, DebtCategory::Testing);
1224        debt.interest_rate = 0.2;
1225        debt.incurred_at = Utc::now() - ChronoDuration::seconds(debt.compound_period_secs);
1226
1227        let total = debt.calculate_current_total();
1228        // 200 * 1.2^1 = 240
1229        assert_eq!(total, 240);
1230    }
1231
1232    #[test]
1233    fn test_clone_status_derives() {
1234        let s1 = CloneStatus::Exploring;
1235        let s2 = CloneStatus::Exploring;
1236        assert_eq!(s1, s2);
1237
1238        // Copy
1239        let s3 = s1;
1240        assert_eq!(s3, CloneStatus::Exploring);
1241    }
1242
1243    #[test]
1244    fn test_entanglement_type_partial_eq() {
1245        let t1 = EntanglementType::Sequence { gap_secs: 3600 };
1246        let t2 = EntanglementType::Sequence { gap_secs: 3600 };
1247        let t3 = EntanglementType::Sync;
1248        assert_eq!(t1, t2);
1249        assert_ne!(t1, t3);
1250    }
1251
1252    #[test]
1253    fn test_anomaly_type_copy() {
1254        let a = AnomalyType::CausalityViolation;
1255        let b = a; // Copy
1256        assert_eq!(a, b);
1257    }
1258
1259    #[test]
1260    fn test_debt_category_copy() {
1261        let c = DebtCategory::Security;
1262        let d = c; // Copy
1263        assert_eq!(c, d);
1264    }
1265
1266    // ── Time Travel Inventions (13-16) ────────────────────────────────────────
1267
1268    #[test]
1269    fn test_temporal_jump_create_and_return() {
1270        let destination = Utc::now() - ChronoDuration::hours(24);
1271        let mut jump = TemporalJump::new(destination);
1272        assert!(jump.active);
1273        assert_eq!(jump.jump_history.len(), 1);
1274
1275        jump.return_to_origin();
1276        assert!(!jump.active);
1277        assert_eq!(jump.jump_history.len(), 2);
1278        assert_eq!(jump.current_position, jump.origin);
1279    }
1280
1281    #[test]
1282    fn test_temporal_anchor_create_and_expire() {
1283        let anchor = TemporalAnchor::new("pre-refactor", "Safety save before risky change");
1284        assert_eq!(anchor.name, "pre-refactor");
1285        assert_eq!(anchor.jump_count, 0);
1286        assert!(!anchor.is_expired());
1287    }
1288
1289    #[test]
1290    fn test_temporal_anchor_record_jump() {
1291        let mut anchor = TemporalAnchor::new("checkpoint", "test");
1292        anchor.record_jump();
1293        anchor.record_jump();
1294        assert_eq!(anchor.jump_count, 2);
1295        assert!(anchor.last_jumped_at.is_some());
1296    }
1297
1298    #[test]
1299    fn test_time_loop_add_iterations() {
1300        let pattern = LoopPattern {
1301            repeating_actions: vec!["fix null check".to_string()],
1302            trigger: "null pointer exception".to_string(),
1303            expected_outcome: "bug fixed".to_string(),
1304            actual_outcome: "bug returns".to_string(),
1305            similarity_score: 0.95,
1306        };
1307        let mut loop_det = TimeLoop::new(pattern);
1308        assert_eq!(loop_det.iteration_count(), 0);
1309
1310        loop_det.add_iteration(LoopIteration {
1311            number: 1,
1312            started_at: Utc::now(),
1313            ended_at: Some(Utc::now()),
1314            action_taken: "Added null check".to_string(),
1315            result: "Bug returned after 2 hours".to_string(),
1316            duration_secs: 7200,
1317        });
1318
1319        assert_eq!(loop_det.iteration_count(), 1);
1320        assert_eq!(loop_det.total_time_spent_secs, 7200);
1321
1322        loop_det.mark_broken();
1323        assert!(!loop_det.active);
1324    }
1325
1326    #[test]
1327    fn test_temporal_wormhole_create_and_transmit() {
1328        let ep_a = WormholeEndpoint {
1329            timestamp: Utc::now() - ChronoDuration::days(30),
1330            label: "Architecture decision".to_string(),
1331            event_description: "Chose sync calls".to_string(),
1332            related_entities: vec![],
1333            context_summary: "Early design phase".to_string(),
1334        };
1335        let ep_b = WormholeEndpoint {
1336            timestamp: Utc::now(),
1337            label: "Scaling problems".to_string(),
1338            event_description: "3x cost increase".to_string(),
1339            related_entities: vec![],
1340            context_summary: "Production scaling issues".to_string(),
1341        };
1342        let mut wormhole = TemporalWormhole::new(ep_a, ep_b, "Sync calls causing scale issues");
1343        assert!(wormhole.active);
1344        assert_eq!(wormhole.transmitted_insights.len(), 0);
1345
1346        wormhole.transmit_insight(
1347            InsightDirection::FutureToPast,
1348            "This sync design causes 3x scaling cost".to_string(),
1349            "Would have saved $50k".to_string(),
1350        );
1351        assert_eq!(wormhole.transmitted_insights.len(), 1);
1352
1353        wormhole.record_query();
1354        assert_eq!(wormhole.query_count, 1);
1355
1356        wormhole.close();
1357        assert!(!wormhole.active);
1358    }
1359
1360    #[test]
1361    fn test_insight_direction_copy() {
1362        let d = InsightDirection::PastToFuture;
1363        let e = d; // Copy
1364        assert_eq!(d, e);
1365    }
1366}