Repository navigation
Expand file tree
/
Copy pathsubharness.go
More file actions
195 lines (177 loc) · 9.22 KB
/
Copy pathsubharness.go
File metadata and controls
195 lines (177 loc) · 9.22 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
package exec
import (
"strings"
"sync"
"time"
"github.com/Agent-Field/codeaf/internal/plan"
)
// A subharness is a named way of turning a Task into an Outcome. There is ONE
// worker, the generalist, and nothing chooses it because there is nothing to
// choose. What the rest of the system still needs from this file is the fact it
// has always needed before a leaf runs: how much room the leaf gets. The
// executor that does the work is registered separately, on a Registry, because
// a surface builds its worker with its own clients and workspaces while this
// description is a fact about the process.
//
// The manifest table below is the SAVED-PROGRAM contract:
// a bundle or a Go-native program registers its typed front door through
// [RegisterManifest]. A program is a named piece of work somebody saved, not a
// second worker, and nothing here puts a name in front of a model to pick.
// LinearSubharness is the worker. An empty name resolves to it, but the two are
// not the same fact: empty is a question nobody answered, and this name is the
// answer said out loud. GeneralistSubharness is the predicate that keeps them
// apart, and old graphs are full of both.
const LinearSubharness = plan.LinearSubharness
// SubharnessInfo is one registration: what it is for, and how much room its
// work is given.
//
// THE TAGS ARE THE ON-DISK SPELLING OF HALF A MANIFEST. [Manifest] embeds this
// struct and is the document a bundle's manifest.json actually is (PRD §6) — a
// file a person writes by hand, a model iterates on, and a pull request reviews.
// Untagged, this half of it would come out spelled in Go field names next to the
// tagged half's lowercase ones, and the format would be two conventions in one
// object. They are named the way the fields beside them are, and everything but
// the name is omitempty, so a manifest that says nothing about its budget shape
// carries nothing about it.
type SubharnessInfo struct {
Name string `json:"name"`
Purpose string `json:"purpose,omitempty"`
// PriorAnchors is the capacity ruler in the style of plan/size.go's three
// worked examples: comfortably atomic, borderline, oversized. A saved
// program that measures differently from the generalist says so here.
PriorAnchors string `json:"prior_anchors,omitempty"`
// DeadlineFloor and the scaling pair are the budget shape. A leaf's hang
// backstop is not a policy about patience, it is a claim about how long
// this kind of work legitimately takes. Zero values fall back to the
// generalist's shape, so a registration that says nothing about time is
// served rather than refused.
DeadlineFloor time.Duration `json:"deadline_floor,omitempty"`
DeadlineStep time.Duration `json:"deadline_step,omitempty"`
DeadlinePerTokens int `json:"deadline_per_tokens,omitempty"`
}
// linearInfo is the shape the whole system runs on: fifteen minutes floor, one
// minute per fifty thousand tokens above it. Every surface that grants a leaf
// its room reads it through [SubharnessFor]. Its Purpose and PriorAnchors are
// deliberately empty — the generalist is the baseline every node is already
// judged against, and there is nothing beside it to tell it apart from.
var linearInfo = SubharnessInfo{
Name: LinearSubharness,
DeadlineFloor: 15 * time.Minute,
DeadlineStep: time.Minute,
DeadlinePerTokens: 50_000,
}
// Deadline is the budget shape applied to one leaf's token grant.
//
// THIS IS THE ONLY PLACE IN THE PROCESS THAT DOES THIS ARITHMETIC, and that is
// the law rather than a tidiness. The same fifteen-minute floor and the same
// minute per fifty thousand tokens were written out longhand in four places —
// the chat surface, the headless runner, the linear loop's own fallback and the
// claim reaper's window — and the four then had to be kept in step by hand
// across a change none of them could see. The reaper's window is derived from
// this figure two additions along, so a floor that moved here and nowhere else
// put the backstop BELOW the deadline it is meant to sit above, which is not a
// backstop but the thing that fires first. `TestOnlyTheSubharnessTableSizesALeafsRoom`
// fails the build on a fifth copy.
func (s SubharnessInfo) Deadline(budgetTokens int) time.Duration {
floor, step, per := s.DeadlineFloor, s.DeadlineStep, s.DeadlinePerTokens
if floor <= 0 {
floor = linearInfo.DeadlineFloor
}
if step <= 0 || per <= 0 {
step, per = linearInfo.DeadlineStep, linearInfo.DeadlinePerTokens
}
if scaled := time.Duration(budgetTokens/per) * step; scaled > floor {
return scaled
}
return floor
}
// DeadlineWithin widens one leaf's token-sized room to use the wall it runs
// under, while leaving the watchdog's landing pad inside that wall.
//
// A forty-five-minute errand handed its only leaf the generalist's fifteen-
// minute floor, with no path by which the leaf could learn that another thirty
// minutes were going unused. THE WALL IS A CEILING AND THE TOKEN GRANT IS A
// FLOOR: this method only widens. A short wall never takes away room the token
// grant already bought, and no wall leaves the shape byte-for-byte unchanged.
func (s SubharnessInfo) DeadlineWithin(budgetTokens int, remaining time.Duration) time.Duration {
room := s.Deadline(budgetTokens)
if remaining <= 0 {
return room
}
usable := remaining - watchdogPad
if usable > room {
return usable
}
return room
}
// watchdogPad is how far above a leaf's own deadline the node watchdog sits.
//
// It is the room a leaf told to land needs to notice and finish: one more model
// call and one more transcript flush. Two minutes, unchanged from the figure
// every surface wrote out for itself, and it lives beside the deadline it is
// added to because the deadline landing reserve and this watchdog pad are one
// bound in two parts — the reserve is what the landing is granted, and the pad
// is where the watchdog sits so that landing fits underneath it. Neither half
// moves alone.
const watchdogPad = 2 * time.Minute
// WatchdogAbove is the node watchdog over a deadline that has already been
// decided — a retry running on the shape its first attempt was given.
//
// It is derived here rather than at each dispatch site for the reason stated on
// [SubharnessInfo.Deadline]: `deadline + 2*time.Minute`, written out by hand in
// seven places across three files, is a pad that disagrees with itself the first
// time one of them is edited.
func WatchdogAbove(deadline time.Duration) time.Duration {
return deadline + watchdogPad
}
// Watchdog is the node watchdog above one leaf's token grant: its own deadline
// plus the landing pad. The executor has a deadline of its own, so this only
// fires when a leaf is wedged past every limit it was given.
func (s SubharnessInfo) Watchdog(budgetTokens int) time.Duration {
return WatchdogAbove(s.Deadline(budgetTokens))
}
// linearManifest is the worker wearing the typed front door every saved program
// has.
//
// ITS PURPOSE STAYS EMPTY, which is the law two lines above linearInfo and not
// an omission here. The generalist is what you get when you pick nothing, not
// something you pick, so it is never listed anywhere.
// [Manifest.Validate] knows about this one exemption by name.
var linearManifest = LeafManifest(linearInfo)
var (
subharnessMutex sync.RWMutex
// subharnessBy is the process's one table of what a name means, and it
// holds MANIFESTS: the schemas, cues, whitelist and guards ride along in
// the same entry instead of in a second table that could disagree with this
// one about which programs exist.
subharnessBy = map[string]Manifest{LinearSubharness: linearManifest}
)
// SubharnessFor resolves a name to what will actually run it, which is the one
// worker. An unknown or empty name is it rather than an error — the same
// degradation Registry.For promises, said one layer up so a budget shape can be
// read before dispatch.
func SubharnessFor(string) SubharnessInfo { return linearInfo }
// KnownSubharness reports whether this build can run a name as written. There
// is one worker, so the answer is yes for the generalist — named, or left blank
// by a plan that never asked — and no for everything else.
//
// It has one reader left, and it is about old graphs: a node stored by a build
// that had a second worker still names it, and this is how a surface tells that
// the name it is holding is not a worker this build has. Such a node runs
// linear and says so once.
func KnownSubharness(name string) bool {
name = strings.TrimSpace(name)
return name == "" || strings.EqualFold(name, LinearSubharness)
}
// GeneralistSubharness reports whether a name is the generalist, named. It is
// deliberately not KnownSubharness: this one answers no to the empty string,
// which is the difference between "the worker, said out loud" and "nobody said
// anything" — two different things to every reader that would otherwise fill a
// blank in from somewhere else.
//
// It is the registry's answer rather than a comparison each surface spells for
// itself, which would be one rename away from being wrong.
func GeneralistSubharness(name string) bool { return plan.GeneralistSubharness(name) }
// SubharnessChosen reports whether a node's worker column was ever written at
// all. Only the empty string is nothing.
func SubharnessChosen(name string) bool { return plan.SubharnessChosen(name) }