@@ -55,6 +55,12 @@ public struct LoopNode: Identifiable, Codable, Equatable, Sendable {
5555 /// full unbounded series lives in the node's memory log; this is the cache the canvas
5656 /// and the plateau rule read.
5757 public var metricHistory : [ MetricSample ]
58+ /// The loop that asked for this one, when a running session created it through the
59+ /// CLI (`NodeDraft.createdBy`). Recorded on the node, not just as the already-fired
60+ /// edge `linkToCreator` draws — a fired edge is indistinguishable from any drawn
61+ /// handoff, and custody has to be: stopping or deleting a parent takes its spawned
62+ /// descendants with it, while a drawn edge to a peer must never be caught in that.
63+ public let createdBy : UUID ?
5864 public var state : LoopState
5965 public var createdAt : Date
6066
@@ -72,6 +78,7 @@ public struct LoopNode: Identifiable, Codable, Equatable, Sendable {
7278 pilotState: PilotState = . notPiloted,
7379 usage: UsageSample ? = nil ,
7480 metricHistory: [ MetricSample ] = [ ] ,
81+ createdBy: UUID ? = nil ,
7582 state: LoopState = . idle,
7683 createdAt: Date = Date ( )
7784 ) {
@@ -88,6 +95,7 @@ public struct LoopNode: Identifiable, Codable, Equatable, Sendable {
8895 self . pilotState = pilotState
8996 self . usage = usage
9097 self . metricHistory = metricHistory
98+ self . createdBy = createdBy
9199 self . state = state
92100 self . createdAt = createdAt
93101 }
@@ -164,7 +172,8 @@ public struct LoopNode: Identifiable, Codable, Equatable, Sendable {
164172
165173 private enum CodingKeys : String , CodingKey {
166174 case id, title, loopType, checkDescription, triggerPrompt, goal, backend, modelTier
167- case worktreeBinding, subGraph, pilotState, usage, metricHistory, state, createdAt
175+ case worktreeBinding, subGraph, pilotState, usage, metricHistory, createdBy
176+ case state, createdAt
168177 }
169178
170179 /// Hand-written for the same reason `LoopEdge`'s is: `ProjectPersistence.loadGraph`
@@ -187,6 +196,7 @@ public struct LoopNode: Identifiable, Codable, Equatable, Sendable {
187196 usage = try container. decodeIfPresent ( UsageSample . self, forKey: . usage)
188197 metricHistory =
189198 try container. decodeIfPresent ( [ MetricSample ] . self, forKey: . metricHistory) ?? [ ]
199+ createdBy = try container. decodeIfPresent ( UUID . self, forKey: . createdBy)
190200 state = try container. decodeIfPresent ( LoopState . self, forKey: . state) ?? . idle
191201 createdAt = try container. decodeIfPresent ( Date . self, forKey: . createdAt) ?? Date ( )
192202 }
0 commit comments