返回 DeepSeek-Reasonix
obligation.go
根目录 / internal / readcoord / obligation.go
1 package readcoord
2
3 import (
4 "time"
5
6 "reasonix/internal/tool"
7 )
8
9 // Scope identifies the file a read requirement targets.
10 type Scope struct {
11 WorkspaceID string
12 CanonicalPath string
13 }
14
15 // State is the lifecycle position of one read requirement.
16 type State uint8
17
18 const (
19 StateCreated State = iota
20 StateFetching
21 StateDelivered
22 StateSatisfied
23 StateNeedsMore
24 StateNeedsScope
25 StateStale
26 StateBlocked
27 StateCancelled
28 )
29
30 var stateNames = [...]string{
31 StateCreated: "created",
32 StateFetching: "fetching",
33 StateDelivered: "delivered",
34 StateSatisfied: "satisfied",
35 StateNeedsMore: "needs_more",
36 StateNeedsScope: "needs_scope",
37 StateStale: "stale",
38 StateBlocked: "blocked",
39 StateCancelled: "cancelled",
40 }
41
42 func (s State) String() string {
43 if int(s) < len(stateNames) {
44 return stateNames[s]
45 }
46 return "unknown"
47 }
48
49 // Terminal reports whether the obligation can no longer be moved by a delivery.
50 func (s State) Terminal() bool { return s == StateSatisfied || s == StateCancelled }
51
52 // Requirement is what a read must cover to be satisfied.
53 type Requirement struct {
54 Intent tool.ReadIntent
55 // Ranges is the explicit coverage a range requirement must reach.
56 Ranges []tool.ReadRange
57 // WholeFile means the requirement covers the file's entire content at the
58 // obligation's version: only a delivery that reached EOF satisfies it.
59 WholeFile bool
60 }
61
62 // Block explains why an obligation stopped and what would resume it.
63 type Block struct {
64 Code string
65 Detail string
66 Recovery string
67 }
68
69 // Obligation is one logical read requirement plus the coverage accumulated for
70 // it. Coverage is only ever accumulated within one content version.
71 type Obligation struct {
72 Key string
73 Scope Scope
74 Requirement Requirement
75 State State
76 // Version is the content version coverage belongs to. A delivery from a
77 // different version resets coverage instead of extending it.
78 Version string
79 Source tool.ReadResultSource
80 // Covered is the union of delivered ranges on Version, in normalized order.
81 Covered []tool.ReadRange
82 // SawEOF reports that some delivery on Version reached the file's end.
83 SawEOF bool
84 // SourceEnd is the source's zero-based end line index when a delivery
85 // established it. Without it, EOF alone proves nothing.
86 SourceEnd *int
87 Generation uint64
88 Sequence uint64
89 Pages int
90 // Stagnant counts consecutive deliveries that added no new coverage;
91 // Pivoted records that the one allowed strategy change already happened.
92 Stagnant int
93 Pivoted bool
94 // ActiveTime is the host-measured time spent producing this read's pages.
95 // Waiting for the model is not counted.
96 ActiveTime time.Duration
97 // Stop carries the reason for StateBlocked or StateNeedsScope.
98 Stop *Block
99 }
100
101 // clone returns a deep copy so callers can never mutate coordinator state.
102 func (o *Obligation) clone() Obligation {
103 out := *o
104 out.Requirement.Ranges = append([]tool.ReadRange(nil), o.Requirement.Ranges...)
105 out.Covered = append([]tool.ReadRange(nil), o.Covered...)
106 if o.SourceEnd != nil {
107 end := *o.SourceEnd
108 out.SourceEnd = &end
109 }
110 if o.Stop != nil {
111 stop := *o.Stop
112 out.Stop = &stop
113 }
114 return out
115 }
116
116 lines GO