@openrig/cli 0.5.3 → 0.5.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (194) hide show
  1. package/daemon/assets/plugins/openrig-core/.claude-plugin/plugin.json +1 -1
  2. package/daemon/assets/plugins/openrig-core/.codex-plugin/plugin.json +1 -1
  3. package/daemon/assets/plugins/openrig-core/README.md +1 -1
  4. package/daemon/assets/plugins/openrig-core/hooks/scripts/refocus.cjs +32 -12
  5. package/daemon/assets/plugins/openrig-core/skills/openrig-skills/SKILL.md +3 -0
  6. package/daemon/assets/plugins/openrig-core/skills/software-for-agents/SKILL.md +4 -9
  7. package/daemon/context-packs/skills/core/agent-starters/manifest.yaml +1 -1
  8. package/daemon/context-packs/skills/core/agent-startup-and-context-ingestion/manifest.yaml +1 -1
  9. package/daemon/context-packs/skills/core/attention-queue/manifest.yaml +1 -1
  10. package/daemon/context-packs/skills/core/cross-host-rig-commands/manifest.yaml +1 -1
  11. package/daemon/context-packs/skills/core/human-in-the-loop/manifest.yaml +1 -1
  12. package/daemon/context-packs/skills/core/openrig-architect/manifest.yaml +1 -1
  13. package/daemon/context-packs/skills/core/openrig-cmux/manifest.yaml +1 -1
  14. package/daemon/context-packs/skills/core/openrig-herdr/manifest.yaml +1 -1
  15. package/daemon/context-packs/skills/core/openrig-upgrade/manifest.yaml +1 -1
  16. package/daemon/context-packs/skills/core/rig-bundles-and-shareable-artifacts/manifest.yaml +1 -1
  17. package/daemon/context-packs/skills/core/rig-lifecycle/manifest.yaml +1 -1
  18. package/daemon/context-packs/skills/core/session-source-fork/manifest.yaml +1 -1
  19. package/daemon/context-packs/skills/core/specification-system/manifest.yaml +1 -1
  20. package/daemon/context-packs/skills/core/topology-mutation-and-seat-management/manifest.yaml +1 -1
  21. package/daemon/context-packs/skills/core/watchdog/manifest.yaml +1 -1
  22. package/daemon/context-packs/skills/pm/backlog-capture/manifest.yaml +1 -1
  23. package/daemon/context-packs/skills/pm/context-builder/manifest.yaml +1 -1
  24. package/daemon/context-packs/skills/pm/exec-summary/manifest.yaml +1 -1
  25. package/daemon/context-packs/skills/pm/office-hours/manifest.yaml +1 -1
  26. package/daemon/context-packs/skills/pm/plan-review/manifest.yaml +1 -1
  27. package/daemon/context-packs/skills/pm/requirements-writer/manifest.yaml +1 -1
  28. package/daemon/context-packs/skills/pm/ui-mockup/manifest.yaml +1 -1
  29. package/daemon/context-packs/skills/pods/development-team/manifest.yaml +1 -1
  30. package/daemon/context-packs/skills/pods/orchestration-team/manifest.yaml +1 -1
  31. package/daemon/context-packs/skills/pods/oversight-team/manifest.yaml +1 -1
  32. package/daemon/context-packs/skills/pods/review-team/manifest.yaml +1 -1
  33. package/daemon/context-packs/skills/process/agent-browser/manifest.yaml +1 -1
  34. package/daemon/context-packs/skills/process/brainstorming/manifest.yaml +1 -1
  35. package/daemon/context-packs/skills/process/context-engineering/manifest.yaml +1 -1
  36. package/daemon/context-packs/skills/process/dogfood/manifest.yaml +1 -1
  37. package/daemon/context-packs/skills/process/executing-plans/manifest.yaml +1 -1
  38. package/daemon/context-packs/skills/process/frontend-design/manifest.yaml +1 -1
  39. package/daemon/context-packs/skills/process/systematic-debugging/manifest.yaml +1 -1
  40. package/daemon/context-packs/skills/process/test-driven-development/manifest.yaml +1 -1
  41. package/daemon/context-packs/skills/process/using-superpowers/manifest.yaml +1 -1
  42. package/daemon/context-packs/skills/process/verification-before-completion/manifest.yaml +1 -1
  43. package/daemon/context-packs/skills/process/writing-plans/manifest.yaml +1 -1
  44. package/daemon/context-packs/world/install/manifest.yaml +1 -1
  45. package/daemon/dist/adapters/tmux.d.ts +31 -0
  46. package/daemon/dist/adapters/tmux.d.ts.map +1 -1
  47. package/daemon/dist/adapters/tmux.js +31 -11
  48. package/daemon/dist/adapters/tmux.js.map +1 -1
  49. package/daemon/dist/build-info.js +3 -3
  50. package/daemon/dist/daemon-db-path.d.ts.map +1 -1
  51. package/daemon/dist/daemon-db-path.js +50 -2
  52. package/daemon/dist/daemon-db-path.js.map +1 -1
  53. package/daemon/dist/domain/plugin-discovery-service.d.ts +16 -0
  54. package/daemon/dist/domain/plugin-discovery-service.d.ts.map +1 -1
  55. package/daemon/dist/domain/plugin-discovery-service.js +175 -1
  56. package/daemon/dist/domain/plugin-discovery-service.js.map +1 -1
  57. package/daemon/dist/domain/plugin-vendor-service.d.ts +9 -5
  58. package/daemon/dist/domain/plugin-vendor-service.d.ts.map +1 -1
  59. package/daemon/dist/domain/plugin-vendor-service.js +101 -12
  60. package/daemon/dist/domain/plugin-vendor-service.js.map +1 -1
  61. package/daemon/dist/domain/queue-repository.d.ts +3 -1
  62. package/daemon/dist/domain/queue-repository.d.ts.map +1 -1
  63. package/daemon/dist/domain/queue-repository.js +50 -2
  64. package/daemon/dist/domain/queue-repository.js.map +1 -1
  65. package/daemon/dist/domain/reconciler.d.ts.map +1 -1
  66. package/daemon/dist/domain/reconciler.js +6 -1
  67. package/daemon/dist/domain/reconciler.js.map +1 -1
  68. package/daemon/dist/domain/rig-repository.d.ts +4 -0
  69. package/daemon/dist/domain/rig-repository.d.ts.map +1 -1
  70. package/daemon/dist/domain/rig-repository.js +9 -0
  71. package/daemon/dist/domain/rig-repository.js.map +1 -1
  72. package/daemon/dist/domain/rigspec-instantiator.d.ts +9 -0
  73. package/daemon/dist/domain/rigspec-instantiator.d.ts.map +1 -1
  74. package/daemon/dist/domain/rigspec-instantiator.js +32 -0
  75. package/daemon/dist/domain/rigspec-instantiator.js.map +1 -1
  76. package/daemon/dist/domain/running-name-guard.d.ts +52 -0
  77. package/daemon/dist/domain/running-name-guard.d.ts.map +1 -0
  78. package/daemon/dist/domain/running-name-guard.js +34 -0
  79. package/daemon/dist/domain/running-name-guard.js.map +1 -0
  80. package/daemon/dist/domain/seat-lifecycle-service.d.ts +97 -0
  81. package/daemon/dist/domain/seat-lifecycle-service.d.ts.map +1 -0
  82. package/daemon/dist/domain/seat-lifecycle-service.js +312 -0
  83. package/daemon/dist/domain/seat-lifecycle-service.js.map +1 -0
  84. package/daemon/dist/domain/session-transport.d.ts +8 -5
  85. package/daemon/dist/domain/session-transport.d.ts.map +1 -1
  86. package/daemon/dist/domain/session-transport.js +39 -16
  87. package/daemon/dist/domain/session-transport.js.map +1 -1
  88. package/daemon/dist/domain/types.d.ts +36 -0
  89. package/daemon/dist/domain/types.d.ts.map +1 -1
  90. package/daemon/dist/domain/types.js.map +1 -1
  91. package/daemon/dist/routes/queue.d.ts.map +1 -1
  92. package/daemon/dist/routes/queue.js +29 -24
  93. package/daemon/dist/routes/queue.js.map +1 -1
  94. package/daemon/dist/routes/rigspec.js +20 -6
  95. package/daemon/dist/routes/rigspec.js.map +1 -1
  96. package/daemon/dist/routes/seat.d.ts.map +1 -1
  97. package/daemon/dist/routes/seat.js +58 -0
  98. package/daemon/dist/routes/seat.js.map +1 -1
  99. package/daemon/dist/routes/transport.d.ts.map +1 -1
  100. package/daemon/dist/routes/transport.js +40 -36
  101. package/daemon/dist/routes/transport.js.map +1 -1
  102. package/daemon/dist/routes/up.js +21 -2
  103. package/daemon/dist/routes/up.js.map +1 -1
  104. package/dist/build-info.js +3 -3
  105. package/dist/cli-error.js +1 -1
  106. package/dist/cli-error.js.map +1 -1
  107. package/dist/commands/broadcast.js +6 -0
  108. package/dist/commands/broadcast.js.map +1 -1
  109. package/dist/commands/context.d.ts.map +1 -1
  110. package/dist/commands/context.js +13 -3
  111. package/dist/commands/context.js.map +1 -1
  112. package/dist/commands/daemon.d.ts.map +1 -1
  113. package/dist/commands/daemon.js +23 -2
  114. package/dist/commands/daemon.js.map +1 -1
  115. package/dist/commands/import.d.ts.map +1 -1
  116. package/dist/commands/import.js +10 -0
  117. package/dist/commands/import.js.map +1 -1
  118. package/dist/commands/queue.d.ts.map +1 -1
  119. package/dist/commands/queue.js +36 -13
  120. package/dist/commands/queue.js.map +1 -1
  121. package/dist/commands/seat.d.ts.map +1 -1
  122. package/dist/commands/seat.js +88 -0
  123. package/dist/commands/seat.js.map +1 -1
  124. package/dist/commands/send.d.ts.map +1 -1
  125. package/dist/commands/send.js +224 -20
  126. package/dist/commands/send.js.map +1 -1
  127. package/dist/commands/up.d.ts.map +1 -1
  128. package/dist/commands/up.js +8 -0
  129. package/dist/commands/up.js.map +1 -1
  130. package/dist/commands/walk.d.ts +1 -1
  131. package/dist/commands/walk.d.ts.map +1 -1
  132. package/dist/commands/walk.js +20 -10
  133. package/dist/commands/walk.js.map +1 -1
  134. package/node_modules/@openrig/daemon/dist/adapters/tmux.d.ts +31 -0
  135. package/node_modules/@openrig/daemon/dist/adapters/tmux.d.ts.map +1 -1
  136. package/node_modules/@openrig/daemon/dist/adapters/tmux.js +31 -11
  137. package/node_modules/@openrig/daemon/dist/adapters/tmux.js.map +1 -1
  138. package/node_modules/@openrig/daemon/dist/build-info.js +3 -3
  139. package/node_modules/@openrig/daemon/dist/daemon-db-path.d.ts.map +1 -1
  140. package/node_modules/@openrig/daemon/dist/daemon-db-path.js +50 -2
  141. package/node_modules/@openrig/daemon/dist/daemon-db-path.js.map +1 -1
  142. package/node_modules/@openrig/daemon/dist/domain/plugin-discovery-service.d.ts +16 -0
  143. package/node_modules/@openrig/daemon/dist/domain/plugin-discovery-service.d.ts.map +1 -1
  144. package/node_modules/@openrig/daemon/dist/domain/plugin-discovery-service.js +175 -1
  145. package/node_modules/@openrig/daemon/dist/domain/plugin-discovery-service.js.map +1 -1
  146. package/node_modules/@openrig/daemon/dist/domain/plugin-vendor-service.d.ts +9 -5
  147. package/node_modules/@openrig/daemon/dist/domain/plugin-vendor-service.d.ts.map +1 -1
  148. package/node_modules/@openrig/daemon/dist/domain/plugin-vendor-service.js +101 -12
  149. package/node_modules/@openrig/daemon/dist/domain/plugin-vendor-service.js.map +1 -1
  150. package/node_modules/@openrig/daemon/dist/domain/queue-repository.d.ts +3 -1
  151. package/node_modules/@openrig/daemon/dist/domain/queue-repository.d.ts.map +1 -1
  152. package/node_modules/@openrig/daemon/dist/domain/queue-repository.js +50 -2
  153. package/node_modules/@openrig/daemon/dist/domain/queue-repository.js.map +1 -1
  154. package/node_modules/@openrig/daemon/dist/domain/reconciler.d.ts.map +1 -1
  155. package/node_modules/@openrig/daemon/dist/domain/reconciler.js +6 -1
  156. package/node_modules/@openrig/daemon/dist/domain/reconciler.js.map +1 -1
  157. package/node_modules/@openrig/daemon/dist/domain/rig-repository.d.ts +4 -0
  158. package/node_modules/@openrig/daemon/dist/domain/rig-repository.d.ts.map +1 -1
  159. package/node_modules/@openrig/daemon/dist/domain/rig-repository.js +9 -0
  160. package/node_modules/@openrig/daemon/dist/domain/rig-repository.js.map +1 -1
  161. package/node_modules/@openrig/daemon/dist/domain/rigspec-instantiator.d.ts +9 -0
  162. package/node_modules/@openrig/daemon/dist/domain/rigspec-instantiator.d.ts.map +1 -1
  163. package/node_modules/@openrig/daemon/dist/domain/rigspec-instantiator.js +32 -0
  164. package/node_modules/@openrig/daemon/dist/domain/rigspec-instantiator.js.map +1 -1
  165. package/node_modules/@openrig/daemon/dist/domain/running-name-guard.d.ts +52 -0
  166. package/node_modules/@openrig/daemon/dist/domain/running-name-guard.d.ts.map +1 -0
  167. package/node_modules/@openrig/daemon/dist/domain/running-name-guard.js +34 -0
  168. package/node_modules/@openrig/daemon/dist/domain/running-name-guard.js.map +1 -0
  169. package/node_modules/@openrig/daemon/dist/domain/seat-lifecycle-service.d.ts +97 -0
  170. package/node_modules/@openrig/daemon/dist/domain/seat-lifecycle-service.d.ts.map +1 -0
  171. package/node_modules/@openrig/daemon/dist/domain/seat-lifecycle-service.js +312 -0
  172. package/node_modules/@openrig/daemon/dist/domain/seat-lifecycle-service.js.map +1 -0
  173. package/node_modules/@openrig/daemon/dist/domain/session-transport.d.ts +8 -5
  174. package/node_modules/@openrig/daemon/dist/domain/session-transport.d.ts.map +1 -1
  175. package/node_modules/@openrig/daemon/dist/domain/session-transport.js +39 -16
  176. package/node_modules/@openrig/daemon/dist/domain/session-transport.js.map +1 -1
  177. package/node_modules/@openrig/daemon/dist/domain/types.d.ts +36 -0
  178. package/node_modules/@openrig/daemon/dist/domain/types.d.ts.map +1 -1
  179. package/node_modules/@openrig/daemon/dist/domain/types.js.map +1 -1
  180. package/node_modules/@openrig/daemon/dist/routes/queue.d.ts.map +1 -1
  181. package/node_modules/@openrig/daemon/dist/routes/queue.js +29 -24
  182. package/node_modules/@openrig/daemon/dist/routes/queue.js.map +1 -1
  183. package/node_modules/@openrig/daemon/dist/routes/rigspec.js +20 -6
  184. package/node_modules/@openrig/daemon/dist/routes/rigspec.js.map +1 -1
  185. package/node_modules/@openrig/daemon/dist/routes/seat.d.ts.map +1 -1
  186. package/node_modules/@openrig/daemon/dist/routes/seat.js +58 -0
  187. package/node_modules/@openrig/daemon/dist/routes/seat.js.map +1 -1
  188. package/node_modules/@openrig/daemon/dist/routes/transport.d.ts.map +1 -1
  189. package/node_modules/@openrig/daemon/dist/routes/transport.js +40 -36
  190. package/node_modules/@openrig/daemon/dist/routes/transport.js.map +1 -1
  191. package/node_modules/@openrig/daemon/dist/routes/up.js +21 -2
  192. package/node_modules/@openrig/daemon/dist/routes/up.js.map +1 -1
  193. package/node_modules/@openrig/daemon/package.json +1 -1
  194. package/package.json +1 -1
@@ -0,0 +1,312 @@
1
+ import { getNodeInventory } from "./node-inventory.js";
2
+ import { parseSessionName } from "./session-name.js";
3
+ /**
4
+ * S5 (OPR.0.5.4.7) — the seat-lifecycle verb surface: set-model, single-seat stop,
5
+ * dead-session clean. One coherent design (KI-5.3-9):
6
+ *
7
+ * - ONE seat-resolution path shared by all three verbs (the SeatStatusService
8
+ * findMatches semantics: parseSessionName greedy first-@ rig; canonical-name or
9
+ * logical-id match; ambiguity returns the match list) — never a per-verb resolver.
10
+ * - Every mutation is transactional and persists its audit event in the SAME
11
+ * transaction (node.model_changed / session.stopped / session.cleaned).
12
+ * - Every refusal names what was actually checked; an indeterminate tmux probe is
13
+ * a refusal, never a guess (the S1 error bar applied at birth).
14
+ */
15
+ const SEAT_LOOKUP_GUIDANCE = "List seats with: rig ps --nodes";
16
+ /** Terminal session statuses — rows the clean verb must NOT touch (they already
17
+ * record an ended tenancy; the vocabulary is shared with seat-handover-service
18
+ * and the watchdog's TERMINAL_SESSION_STATUSES). */
19
+ const TERMINAL_SESSION_STATUSES = new Set(["superseded", "detached", "exited"]);
20
+ export class SeatLifecycleService {
21
+ db;
22
+ rigRepo;
23
+ sessionRegistry;
24
+ eventBus;
25
+ tmuxAdapter;
26
+ constructor(deps) {
27
+ if (deps.db !== deps.rigRepo.db)
28
+ throw new Error("SeatLifecycleService: rigRepo must share the same db handle");
29
+ if (deps.db !== deps.sessionRegistry.db)
30
+ throw new Error("SeatLifecycleService: sessionRegistry must share the same db handle");
31
+ if (deps.db !== deps.eventBus.db)
32
+ throw new Error("SeatLifecycleService: eventBus must share the same db handle");
33
+ this.db = deps.db;
34
+ this.rigRepo = deps.rigRepo;
35
+ this.sessionRegistry = deps.sessionRegistry;
36
+ this.eventBus = deps.eventBus;
37
+ this.tmuxAdapter = deps.tmuxAdapter;
38
+ }
39
+ async setModel(input) {
40
+ const required = this.requireReason(input.reason);
41
+ if (required)
42
+ return required;
43
+ if (!input.model?.trim()) {
44
+ return { ok: false, code: "missing_model", message: "A target model id is required (--model)." };
45
+ }
46
+ const resolved = this.resolveSeat(input.seatRef);
47
+ if ("code" in resolved)
48
+ return resolved;
49
+ const model = input.model.trim();
50
+ const seat = this.describe(resolved);
51
+ const from = resolved.entry.model ?? null;
52
+ if (from === model) {
53
+ // Honest no-op: the persisted value already IS the target; no event is minted.
54
+ return { ok: true, seat, from, to: model, changed: false };
55
+ }
56
+ let persisted = null;
57
+ const tx = this.db.transaction(() => {
58
+ this.rigRepo.setNodeModel(resolved.nodeId, model);
59
+ persisted = this.eventBus.persistWithinTransaction({
60
+ type: "node.model_changed",
61
+ rigId: seat.rigId,
62
+ nodeId: seat.nodeId,
63
+ logicalId: seat.logicalId,
64
+ from,
65
+ to: model,
66
+ reason: input.reason.trim(),
67
+ operator: input.operator ?? null,
68
+ });
69
+ });
70
+ tx();
71
+ if (persisted)
72
+ this.eventBus.notifySubscribers(persisted);
73
+ return { ok: true, seat, from, to: model, changed: true };
74
+ }
75
+ async stopSeat(input) {
76
+ const required = this.requireReason(input.reason);
77
+ if (required)
78
+ return required;
79
+ const resolved = this.resolveSeat(input.seatRef);
80
+ if ("code" in resolved)
81
+ return resolved;
82
+ const seat = this.describe(resolved);
83
+ const session = this.latestSession(resolved.nodeId);
84
+ if (!session) {
85
+ return { ok: false, code: "no_session", message: `Seat "${input.seatRef}" has no session to stop (checked: latest sessions row for node ${seat.logicalId}).` };
86
+ }
87
+ if (session.origin === "claimed") {
88
+ return {
89
+ ok: false,
90
+ code: "claimed_session",
91
+ message: `Session "${session.session_name}" was adopted (origin=claimed), not launched by OpenRig — stop refuses to kill it.`,
92
+ guidance: "Release an adopted session with: rig unclaim",
93
+ };
94
+ }
95
+ // Wave-2 fix round 1 (r1 row 9baac99f): consume the CLASSIFIED probe, never the
96
+ // collapsed hasSession view — a transport blip is INDETERMINATE, not absence
97
+ // (KI-5.3-8 fabricated-absence class, destructive direction).
98
+ const probed = await this.probeLiveness(session.session_name, "stop refuses rather than kill blind");
99
+ if ("code" in probed)
100
+ return probed;
101
+ if (probed.state === "absent") {
102
+ return {
103
+ ok: false,
104
+ code: "session_not_live",
105
+ message: `Session "${session.session_name}" is absent in tmux (checked: tmux has-session, POSITIVE absence evidence) — there is nothing to stop.`,
106
+ guidance: "A dead seat with stale records is returned to launchable with: rig seat clean",
107
+ };
108
+ }
109
+ // Kill exactly this seat's own tmux session — structurally single-seat.
110
+ const kill = await this.tmuxAdapter.killSession(session.session_name);
111
+ if (kill && !kill.ok && kill.code !== "session_not_found") {
112
+ return {
113
+ ok: false,
114
+ code: "tmux_probe_failed",
115
+ message: `tmux kill-session for "${session.session_name}" failed: ${kill.message ?? kill.code}`,
116
+ };
117
+ }
118
+ let persisted = null;
119
+ const tx = this.db.transaction(() => {
120
+ this.sessionRegistry.updateStatus(session.id, "exited");
121
+ this.sessionRegistry.clearBinding(resolved.nodeId);
122
+ persisted = this.eventBus.persistWithinTransaction({
123
+ type: "session.stopped",
124
+ rigId: seat.rigId,
125
+ nodeId: seat.nodeId,
126
+ sessionName: session.session_name,
127
+ reason: input.reason.trim(),
128
+ operator: input.operator ?? null,
129
+ });
130
+ });
131
+ tx();
132
+ if (persisted)
133
+ this.eventBus.notifySubscribers(persisted);
134
+ return { ok: true, seat, sessionName: session.session_name, sessionId: session.id };
135
+ }
136
+ async cleanSeat(input) {
137
+ const required = this.requireReason(input.reason);
138
+ if (required)
139
+ return required;
140
+ const resolved = this.resolveSeat(input.seatRef);
141
+ if ("code" in resolved)
142
+ return resolved;
143
+ const seat = this.describe(resolved);
144
+ const binding = this.sessionRegistry.getBindingForNode(resolved.nodeId);
145
+ const nonTerminal = this.db.prepare("SELECT id, session_name, status, origin FROM sessions WHERE node_id = ? ORDER BY id").all(resolved.nodeId)
146
+ .filter((s) => !TERMINAL_SESSION_STATUSES.has(s.status));
147
+ // Fix r2-F3 (row 30045f39): clean MUTATES every non-terminal session row, so
148
+ // its safety checks must cover exactly that set — probing only the newest row
149
+ // fabricates safety for the others (older-live/newer-dead under canonical-name
150
+ // churn). Every row that would be touched is checked for adopted origin and
151
+ // probed for POSITIVE absence (r1 discipline); the binding's own tmux session
152
+ // is probed too when it names a session no row carries.
153
+ const mutationTargets = nonTerminal;
154
+ for (const row of mutationTargets) {
155
+ if (row.origin === "claimed") {
156
+ return {
157
+ ok: false,
158
+ code: "claimed_session",
159
+ message: `Session "${row.session_name}" was adopted (origin=claimed) — clean refuses to touch adopted state.`,
160
+ guidance: "Release an adopted session with: rig unclaim",
161
+ };
162
+ }
163
+ }
164
+ const probeNames = [...new Set([
165
+ ...mutationTargets.map((s) => s.session_name),
166
+ ...(binding?.tmuxSession ? [binding.tmuxSession] : []),
167
+ ])];
168
+ for (const name of probeNames) {
169
+ const probed = await this.probeLiveness(name, "clean refuses rather than clear state under a possibly-live seat");
170
+ if ("code" in probed)
171
+ return probed;
172
+ if (probed.state === "present") {
173
+ return {
174
+ ok: false,
175
+ code: "session_live",
176
+ message: `Session "${name}" is alive in tmux (checked: tmux has-session, against EVERY session row clean would mutate) — clean only operates on dead seats.`,
177
+ guidance: "Stop a live seat first with: rig seat stop",
178
+ };
179
+ }
180
+ }
181
+ const session = this.latestSession(resolved.nodeId);
182
+ if (!binding && nonTerminal.length === 0) {
183
+ return {
184
+ ok: false,
185
+ code: "nothing_to_clean",
186
+ message: `Seat "${input.seatRef}" is already clean (checked: no binding row for the node, and no session rows outside terminal statuses ${[...TERMINAL_SESSION_STATUSES].join("/")}).`,
187
+ };
188
+ }
189
+ const sessionsExited = [];
190
+ let persisted = null;
191
+ const tx = this.db.transaction(() => {
192
+ for (const row of nonTerminal) {
193
+ this.sessionRegistry.updateStatus(row.id, "exited");
194
+ sessionsExited.push(row.session_name);
195
+ }
196
+ this.sessionRegistry.clearBinding(resolved.nodeId);
197
+ persisted = this.eventBus.persistWithinTransaction({
198
+ type: "session.cleaned",
199
+ rigId: seat.rigId,
200
+ nodeId: seat.nodeId,
201
+ sessionName: session?.session_name ?? null,
202
+ reason: input.reason.trim(),
203
+ operator: input.operator ?? null,
204
+ actions: { sessionsExited, bindingCleared: binding !== null },
205
+ });
206
+ });
207
+ tx();
208
+ if (persisted)
209
+ this.eventBus.notifySubscribers(persisted);
210
+ return { ok: true, seat, actions: { sessionsExited, bindingCleared: binding !== null } };
211
+ }
212
+ // -- shared internals --
213
+ /**
214
+ * The ONE liveness read both mutating verbs share (fix r1, row 9baac99f):
215
+ * the CLASSIFIED probeSession, never the collapsed hasSession view.
216
+ * present / absent → returned for the verb to act on (absent is
217
+ * POSITIVE tmux evidence, per OPR.0.5.4.2).
218
+ * transport_unavailable → an INDETERMINATE refusal: session existence was
219
+ * NOT determined, so neither verb may act — and the
220
+ * refusal never routes the operator to a
221
+ * destructive verb.
222
+ * unexpected probe throw → the same indeterminate refusal (fail closed).
223
+ */
224
+ async probeLiveness(sessionName, refusalConsequence) {
225
+ let probe;
226
+ try {
227
+ probe = await this.tmuxAdapter.probeSession(sessionName);
228
+ }
229
+ catch (err) {
230
+ return {
231
+ ok: false,
232
+ code: "tmux_probe_failed",
233
+ message: `tmux liveness probe for "${sessionName}" failed (${err instanceof Error ? err.message : String(err)}) — liveness is INDETERMINATE, so ${refusalConsequence}.`,
234
+ };
235
+ }
236
+ if (probe.state === "transport_unavailable") {
237
+ return {
238
+ ok: false,
239
+ code: "tmux_probe_failed",
240
+ message: `tmux transport unavailable probing "${sessionName}" (${probe.cause}) — session existence was NOT determined (checked: classified tmux probe), so ${refusalConsequence}. Retry when the tmux transport is back.`,
241
+ };
242
+ }
243
+ return { state: probe.state };
244
+ }
245
+ requireReason(reason) {
246
+ if (!reason?.trim()) {
247
+ return { ok: false, code: "missing_reason", message: "An audit reason is required (--reason)." };
248
+ }
249
+ return null;
250
+ }
251
+ describe(resolved) {
252
+ return {
253
+ rigId: resolved.entry.rigId,
254
+ rigName: resolved.entry.rigName,
255
+ logicalId: resolved.entry.logicalId,
256
+ nodeId: resolved.nodeId,
257
+ };
258
+ }
259
+ latestSession(nodeId) {
260
+ const row = this.db.prepare("SELECT id, session_name, status, origin FROM sessions WHERE node_id = ? ORDER BY id DESC LIMIT 1").get(nodeId);
261
+ return row ?? null;
262
+ }
263
+ /** The ONE resolution path, mirroring SeatStatusService.findMatches semantics
264
+ * (seat-status-service.ts) so every seat verb resolves identically: a canonical
265
+ * `name@rig` ref scopes to that rig's inventory; a bare ref scans all rigs;
266
+ * matches are by canonicalSessionName or logicalId; >1 match is a listed
267
+ * ambiguity, never a pick. */
268
+ resolveSeat(seatRef) {
269
+ const ref = seatRef?.trim() ?? "";
270
+ if (!ref) {
271
+ return { ok: false, code: "seat_ref_required", message: "seat reference is required", guidance: SEAT_LOOKUP_GUIDANCE };
272
+ }
273
+ const matches = this.findMatches(ref);
274
+ if (matches.length === 0) {
275
+ return {
276
+ ok: false,
277
+ code: "seat_not_found",
278
+ message: `Seat "${ref}" not found (checked: canonical session names and logical ids across ${parseSessionName(ref).kind === "canonical" ? "the named rig" : "all rigs"}).`,
279
+ guidance: SEAT_LOOKUP_GUIDANCE,
280
+ };
281
+ }
282
+ if (matches.length > 1) {
283
+ return {
284
+ ok: false,
285
+ code: "seat_ambiguous",
286
+ message: `Seat "${ref}" matched multiple nodes`,
287
+ guidance: SEAT_LOOKUP_GUIDANCE,
288
+ matches: matches.map((entry) => ({
289
+ rig_name: entry.rigName,
290
+ logical_id: entry.logicalId,
291
+ current_occupant: entry.canonicalSessionName,
292
+ })),
293
+ };
294
+ }
295
+ const entry = matches[0];
296
+ const nodeRow = this.db.prepare("SELECT id FROM nodes WHERE rig_id = ? AND logical_id = ?").get(entry.rigId, entry.logicalId);
297
+ if (!nodeRow) {
298
+ return { ok: false, code: "seat_not_found", message: `Seat "${ref}" resolved to a node that no longer exists.`, guidance: SEAT_LOOKUP_GUIDANCE };
299
+ }
300
+ return { entry, nodeId: nodeRow.id };
301
+ }
302
+ findMatches(ref) {
303
+ const parsed = parseSessionName(ref);
304
+ if (parsed.kind === "canonical") {
305
+ const localRef = parsed.member;
306
+ const rigs = this.rigRepo.findRigsByName(parsed.rig);
307
+ return rigs.flatMap((rig) => getNodeInventory(this.db, rig.id).filter((entry) => entry.canonicalSessionName === ref || entry.logicalId === localRef));
308
+ }
309
+ return this.rigRepo.listRigs().flatMap((rig) => getNodeInventory(this.db, rig.id).filter((entry) => entry.canonicalSessionName === ref || entry.logicalId === ref));
310
+ }
311
+ }
312
+ //# sourceMappingURL=seat-lifecycle-service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"seat-lifecycle-service.js","sourceRoot":"","sources":["../../src/domain/seat-lifecycle-service.ts"],"names":[],"mappings":"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"}
@@ -138,11 +138,14 @@ export declare class SessionTransport {
138
138
  constructor(deps: SessionTransportDeps);
139
139
  /**
140
140
  * Slice-05 D5/D6 — when a live transport op (send/capture) observes that the
141
- * seat's tmux session is genuinely gone (`hasSession(sessionName) === false`),
142
- * durably record the SAME `session_missing` identity verdict the reconciler
143
- * would write, so `rig ps` stops reporting the dead seat as running WITHOUT
144
- * waiting for the next reconciler poll. This is the transport-side writer of
145
- * the shared verdict bridge; the reconciler is the poll-side writer.
141
+ * seat's tmux session is genuinely gone (a `probeSession` result of `absent`
142
+ * POSITIVE tmux evidence, never a transport failure; OPR.0.5.4.2 mini-req
143
+ * 5), durably record the SAME `session_missing` identity verdict the
144
+ * reconciler would write, so `rig ps` stops reporting the dead seat as
145
+ * running WITHOUT waiting for the next reconciler poll. This is the
146
+ * transport-side writer of the shared verdict bridge; the reconciler is the
147
+ * poll-side writer. Transport-absence must never reach this method: a blip
148
+ * against a live seat would otherwise fabricate a durable absence verdict.
146
149
  *
147
150
  * Only writes an APPLICABLE verdict: the join is narrowed to the node whose
148
151
  * LATEST running session_name equals the probed session (so
@@ -1 +1 @@
1
- {"version":3,"file":"session-transport.d.ts","sourceRoot":"","sources":["../../src/domain/session-transport.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"session-transport.d.ts","sourceRoot":"","sources":["../../src/domain/session-transport.ts"],"names":[],"mappings":"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"}
@@ -340,11 +340,14 @@ export class SessionTransport {
340
340
  }
341
341
  /**
342
342
  * Slice-05 D5/D6 — when a live transport op (send/capture) observes that the
343
- * seat's tmux session is genuinely gone (`hasSession(sessionName) === false`),
344
- * durably record the SAME `session_missing` identity verdict the reconciler
345
- * would write, so `rig ps` stops reporting the dead seat as running WITHOUT
346
- * waiting for the next reconciler poll. This is the transport-side writer of
347
- * the shared verdict bridge; the reconciler is the poll-side writer.
343
+ * seat's tmux session is genuinely gone (a `probeSession` result of `absent`
344
+ * POSITIVE tmux evidence, never a transport failure; OPR.0.5.4.2 mini-req
345
+ * 5), durably record the SAME `session_missing` identity verdict the
346
+ * reconciler would write, so `rig ps` stops reporting the dead seat as
347
+ * running WITHOUT waiting for the next reconciler poll. This is the
348
+ * transport-side writer of the shared verdict bridge; the reconciler is the
349
+ * poll-side writer. Transport-absence must never reach this method: a blip
350
+ * against a live seat would otherwise fabricate a durable absence verdict.
348
351
  *
349
352
  * Only writes an APPLICABLE verdict: the join is narrowed to the node whose
350
353
  * LATEST running session_name equals the probed session (so
@@ -625,25 +628,35 @@ export class SessionTransport {
625
628
  };
626
629
  }
627
630
  }
628
- // 1. Check session exists / tmux available
631
+ // 1. Resolve the session through the classified probe (OPR.0.5.4.2): a
632
+ // transport blip must never read as a dead seat, and absence is only ever
633
+ // asserted on positive tmux evidence.
629
634
  try {
630
- const exists = await this.tmuxAdapter.hasSession(sessionName);
631
- if (!exists) {
635
+ const probe = await this.tmuxAdapter.probeSession(sessionName);
636
+ if (probe.state === "absent") {
632
637
  this.recordSessionMissingVerdict(sessionName);
633
638
  return {
634
639
  ok: false,
635
640
  sessionName,
636
641
  reason: "session_missing",
637
- error: `Session '${sessionName}' not found. Check available sessions with: rig ps --nodes`,
642
+ error: `Session '${sessionName}' not found: tmux reports no session with this name. No text was sent. Check available sessions with: rig ps --nodes`,
643
+ };
644
+ }
645
+ if (probe.state === "transport_unavailable") {
646
+ return {
647
+ ok: false,
648
+ sessionName,
649
+ reason: "tmux_unavailable",
650
+ error: `The tmux server could not be reached (${probe.cause}). Whether session '${sessionName}' exists was not determined. No text was sent.`,
638
651
  };
639
652
  }
640
653
  }
641
- catch {
654
+ catch (err) {
642
655
  return {
643
656
  ok: false,
644
657
  sessionName,
645
658
  reason: "tmux_unavailable",
646
- error: "tmux is not available. Ensure tmux is installed and a server is running.",
659
+ error: `The tmux session probe failed unexpectedly (${err instanceof Error ? err.message : String(err)}). Whether session '${sessionName}' exists was not determined. No text was sent.`,
647
660
  };
648
661
  }
649
662
  // SUBMIT-ONLY (mechanics-gate fix, desk ruling d9b3989a): the single Enter retry for staged
@@ -1132,24 +1145,34 @@ export class SessionTransport {
1132
1145
  error: `Session '${sessionName}' is attached as an external CLI node. Inbound tmux capture is unavailable for this target.`,
1133
1146
  };
1134
1147
  }
1148
+ // Classified probe (OPR.0.5.4.2) — same discipline as the send gate: a
1149
+ // transport blip is a transport answer, never a dead-seat answer.
1135
1150
  try {
1136
- const exists = await this.tmuxAdapter.hasSession(sessionName);
1137
- if (!exists) {
1151
+ const probe = await this.tmuxAdapter.probeSession(sessionName);
1152
+ if (probe.state === "absent") {
1138
1153
  this.recordSessionMissingVerdict(sessionName);
1139
1154
  return {
1140
1155
  ok: false,
1141
1156
  sessionName,
1142
1157
  reason: "session_missing",
1143
- error: `Session '${sessionName}' not found. Check available sessions with: rig ps --nodes`,
1158
+ error: `Session '${sessionName}' not found: tmux reports no session with this name. Nothing was captured. Check available sessions with: rig ps --nodes`,
1159
+ };
1160
+ }
1161
+ if (probe.state === "transport_unavailable") {
1162
+ return {
1163
+ ok: false,
1164
+ sessionName,
1165
+ reason: "tmux_unavailable",
1166
+ error: `The tmux server could not be reached (${probe.cause}). Whether session '${sessionName}' exists was not determined. Nothing was captured.`,
1144
1167
  };
1145
1168
  }
1146
1169
  }
1147
- catch {
1170
+ catch (err) {
1148
1171
  return {
1149
1172
  ok: false,
1150
1173
  sessionName,
1151
1174
  reason: "tmux_unavailable",
1152
- error: "tmux is not available. Ensure tmux is installed and a server is running.",
1175
+ error: `The tmux session probe failed unexpectedly (${err instanceof Error ? err.message : String(err)}). Whether session '${sessionName}' exists was not determined. Nothing was captured.`,
1153
1176
  };
1154
1177
  }
1155
1178
  const lines = opts?.lines ?? 20;