@openrig/cli 0.3.4 → 0.4.1

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 (300) hide show
  1. package/daemon/assets/plugins/openrig-core/hooks/claude.json +11 -0
  2. package/daemon/assets/plugins/openrig-core/hooks/codex.json +14 -3
  3. package/daemon/assets/plugins/openrig-core/hooks/scripts/activity-relay.cjs +34 -0
  4. package/daemon/assets/plugins/openrig-core/hooks/scripts/compaction-restore-bridge.cjs +28 -24
  5. package/daemon/assets/plugins/openrig-core/skills/claude-compaction-restore/scripts/precompact-hook.mjs +72 -11
  6. package/daemon/assets/plugins/openrig-core/skills/queue-handoff/SKILL.md +62 -29
  7. package/daemon/dist/adapters/codex-resume.d.ts +2 -1
  8. package/daemon/dist/adapters/codex-resume.d.ts.map +1 -1
  9. package/daemon/dist/adapters/codex-resume.js +18 -6
  10. package/daemon/dist/adapters/codex-resume.js.map +1 -1
  11. package/daemon/dist/adapters/codex-runtime-adapter.d.ts +37 -1
  12. package/daemon/dist/adapters/codex-runtime-adapter.d.ts.map +1 -1
  13. package/daemon/dist/adapters/codex-runtime-adapter.js +212 -6
  14. package/daemon/dist/adapters/codex-runtime-adapter.js.map +1 -1
  15. package/daemon/dist/adapters/tmux.d.ts +28 -14
  16. package/daemon/dist/adapters/tmux.d.ts.map +1 -1
  17. package/daemon/dist/adapters/tmux.js +65 -30
  18. package/daemon/dist/adapters/tmux.js.map +1 -1
  19. package/daemon/dist/db/migrations/043_resume_provenance.d.ts +3 -0
  20. package/daemon/dist/db/migrations/043_resume_provenance.d.ts.map +1 -0
  21. package/daemon/dist/db/migrations/043_resume_provenance.js +5 -0
  22. package/daemon/dist/db/migrations/043_resume_provenance.js.map +1 -0
  23. package/daemon/dist/db/migrations/044_queue_item_summary.d.ts +21 -0
  24. package/daemon/dist/db/migrations/044_queue_item_summary.d.ts.map +1 -0
  25. package/daemon/dist/db/migrations/044_queue_item_summary.js +25 -0
  26. package/daemon/dist/db/migrations/044_queue_item_summary.js.map +1 -0
  27. package/daemon/dist/domain/agent-activity-store.d.ts +11 -1
  28. package/daemon/dist/domain/agent-activity-store.d.ts.map +1 -1
  29. package/daemon/dist/domain/agent-activity-store.js +22 -2
  30. package/daemon/dist/domain/agent-activity-store.js.map +1 -1
  31. package/daemon/dist/domain/claude-compaction-enforcer.d.ts.map +1 -1
  32. package/daemon/dist/domain/claude-compaction-enforcer.js +69 -1
  33. package/daemon/dist/domain/claude-compaction-enforcer.js.map +1 -1
  34. package/daemon/dist/domain/daemon-version.d.ts +15 -0
  35. package/daemon/dist/domain/daemon-version.d.ts.map +1 -0
  36. package/daemon/dist/domain/daemon-version.js +28 -0
  37. package/daemon/dist/domain/daemon-version.js.map +1 -0
  38. package/daemon/dist/domain/native-resume-probe.d.ts +2 -1
  39. package/daemon/dist/domain/native-resume-probe.d.ts.map +1 -1
  40. package/daemon/dist/domain/native-resume-probe.js +21 -2
  41. package/daemon/dist/domain/native-resume-probe.js.map +1 -1
  42. package/daemon/dist/domain/node-cmux-service.d.ts +1 -0
  43. package/daemon/dist/domain/node-cmux-service.d.ts.map +1 -1
  44. package/daemon/dist/domain/node-cmux-service.js +29 -2
  45. package/daemon/dist/domain/node-cmux-service.js.map +1 -1
  46. package/daemon/dist/domain/node-inventory.d.ts.map +1 -1
  47. package/daemon/dist/domain/node-inventory.js +70 -46
  48. package/daemon/dist/domain/node-inventory.js.map +1 -1
  49. package/daemon/dist/domain/node-launcher.d.ts +7 -7
  50. package/daemon/dist/domain/node-launcher.d.ts.map +1 -1
  51. package/daemon/dist/domain/node-launcher.js +0 -22
  52. package/daemon/dist/domain/node-launcher.js.map +1 -1
  53. package/daemon/dist/domain/profile-resolver.d.ts +4 -5
  54. package/daemon/dist/domain/profile-resolver.d.ts.map +1 -1
  55. package/daemon/dist/domain/profile-resolver.js.map +1 -1
  56. package/daemon/dist/domain/queue-repository.d.ts +22 -0
  57. package/daemon/dist/domain/queue-repository.d.ts.map +1 -1
  58. package/daemon/dist/domain/queue-repository.js +39 -2
  59. package/daemon/dist/domain/queue-repository.js.map +1 -1
  60. package/daemon/dist/domain/restore-check-service.d.ts +14 -0
  61. package/daemon/dist/domain/restore-check-service.d.ts.map +1 -1
  62. package/daemon/dist/domain/restore-check-service.js +78 -8
  63. package/daemon/dist/domain/restore-check-service.js.map +1 -1
  64. package/daemon/dist/domain/restore-orchestrator.d.ts.map +1 -1
  65. package/daemon/dist/domain/restore-orchestrator.js +3 -3
  66. package/daemon/dist/domain/restore-orchestrator.js.map +1 -1
  67. package/daemon/dist/domain/resume-metadata-refresher.js +1 -1
  68. package/daemon/dist/domain/resume-metadata-refresher.js.map +1 -1
  69. package/daemon/dist/domain/resume-token-validation.d.ts +17 -0
  70. package/daemon/dist/domain/resume-token-validation.d.ts.map +1 -0
  71. package/daemon/dist/domain/resume-token-validation.js +46 -0
  72. package/daemon/dist/domain/resume-token-validation.js.map +1 -0
  73. package/daemon/dist/domain/rigspec-instantiator.d.ts.map +1 -1
  74. package/daemon/dist/domain/rigspec-instantiator.js +3 -6
  75. package/daemon/dist/domain/rigspec-instantiator.js.map +1 -1
  76. package/daemon/dist/domain/runtime-adapter.d.ts.map +1 -1
  77. package/daemon/dist/domain/runtime-adapter.js +1 -0
  78. package/daemon/dist/domain/runtime-adapter.js.map +1 -1
  79. package/daemon/dist/domain/scope/dot-id.d.ts +43 -0
  80. package/daemon/dist/domain/scope/dot-id.d.ts.map +1 -0
  81. package/daemon/dist/domain/scope/dot-id.js +165 -0
  82. package/daemon/dist/domain/scope/dot-id.js.map +1 -0
  83. package/daemon/dist/domain/scope/scope-audit.d.ts +38 -0
  84. package/daemon/dist/domain/scope/scope-audit.d.ts.map +1 -0
  85. package/daemon/dist/domain/scope/scope-audit.js +191 -0
  86. package/daemon/dist/domain/scope/scope-audit.js.map +1 -0
  87. package/daemon/dist/domain/scope/types.d.ts +67 -0
  88. package/daemon/dist/domain/scope/types.d.ts.map +1 -0
  89. package/daemon/dist/domain/scope/types.js +46 -0
  90. package/daemon/dist/domain/scope/types.js.map +1 -0
  91. package/daemon/dist/domain/seat-attention-reconciler.d.ts +12 -0
  92. package/daemon/dist/domain/seat-attention-reconciler.d.ts.map +1 -1
  93. package/daemon/dist/domain/seat-attention-reconciler.js +116 -88
  94. package/daemon/dist/domain/seat-attention-reconciler.js.map +1 -1
  95. package/daemon/dist/domain/session-registry.d.ts +15 -1
  96. package/daemon/dist/domain/session-registry.d.ts.map +1 -1
  97. package/daemon/dist/domain/session-registry.js +46 -4
  98. package/daemon/dist/domain/session-registry.js.map +1 -1
  99. package/daemon/dist/domain/session-transport.d.ts +10 -0
  100. package/daemon/dist/domain/session-transport.d.ts.map +1 -1
  101. package/daemon/dist/domain/session-transport.js +153 -19
  102. package/daemon/dist/domain/session-transport.js.map +1 -1
  103. package/daemon/dist/domain/skill-audit.d.ts +47 -0
  104. package/daemon/dist/domain/skill-audit.d.ts.map +1 -0
  105. package/daemon/dist/domain/skill-audit.js +218 -0
  106. package/daemon/dist/domain/skill-audit.js.map +1 -0
  107. package/daemon/dist/domain/skill-discovery.d.ts +15 -0
  108. package/daemon/dist/domain/skill-discovery.d.ts.map +1 -1
  109. package/daemon/dist/domain/skill-discovery.js +70 -0
  110. package/daemon/dist/domain/skill-discovery.js.map +1 -1
  111. package/daemon/dist/domain/skill-mirror-drift.d.ts +10 -0
  112. package/daemon/dist/domain/skill-mirror-drift.d.ts.map +1 -0
  113. package/daemon/dist/domain/skill-mirror-drift.js +24 -0
  114. package/daemon/dist/domain/skill-mirror-drift.js.map +1 -0
  115. package/daemon/dist/domain/slices/slice-detail-projector.d.ts.map +1 -1
  116. package/daemon/dist/domain/slices/slice-detail-projector.js +10 -3
  117. package/daemon/dist/domain/slices/slice-detail-projector.js.map +1 -1
  118. package/daemon/dist/domain/startup-orchestrator.js +1 -1
  119. package/daemon/dist/domain/startup-orchestrator.js.map +1 -1
  120. package/daemon/dist/domain/types.d.ts +48 -14
  121. package/daemon/dist/domain/types.d.ts.map +1 -1
  122. package/daemon/dist/domain/types.js.map +1 -1
  123. package/daemon/dist/domain/user-settings/settings-store.d.ts +1 -1
  124. package/daemon/dist/domain/user-settings/settings-store.d.ts.map +1 -1
  125. package/daemon/dist/domain/user-settings/settings-store.js +4 -0
  126. package/daemon/dist/domain/user-settings/settings-store.js.map +1 -1
  127. package/daemon/dist/domain/whoami-service.d.ts +1 -0
  128. package/daemon/dist/domain/whoami-service.d.ts.map +1 -1
  129. package/daemon/dist/domain/whoami-service.js +8 -4
  130. package/daemon/dist/domain/whoami-service.js.map +1 -1
  131. package/daemon/dist/domain/workspace/default-workspace-scaffold.d.ts +1 -0
  132. package/daemon/dist/domain/workspace/default-workspace-scaffold.d.ts.map +1 -1
  133. package/daemon/dist/domain/workspace/default-workspace-scaffold.js +25 -1
  134. package/daemon/dist/domain/workspace/default-workspace-scaffold.js.map +1 -1
  135. package/daemon/dist/index.d.ts.map +1 -1
  136. package/daemon/dist/index.js +25 -3
  137. package/daemon/dist/index.js.map +1 -1
  138. package/daemon/dist/routes/activity.d.ts.map +1 -1
  139. package/daemon/dist/routes/activity.js +29 -0
  140. package/daemon/dist/routes/activity.js.map +1 -1
  141. package/daemon/dist/routes/bundles.d.ts.map +1 -1
  142. package/daemon/dist/routes/bundles.js +1 -18
  143. package/daemon/dist/routes/bundles.js.map +1 -1
  144. package/daemon/dist/routes/health-summary.d.ts.map +1 -1
  145. package/daemon/dist/routes/health-summary.js +13 -2
  146. package/daemon/dist/routes/health-summary.js.map +1 -1
  147. package/daemon/dist/routes/queue.d.ts.map +1 -1
  148. package/daemon/dist/routes/queue.js +11 -0
  149. package/daemon/dist/routes/queue.js.map +1 -1
  150. package/daemon/dist/routes/restore-check.js +33 -2
  151. package/daemon/dist/routes/restore-check.js.map +1 -1
  152. package/daemon/dist/routes/scope-audit.d.ts +3 -0
  153. package/daemon/dist/routes/scope-audit.d.ts.map +1 -0
  154. package/daemon/dist/routes/scope-audit.js +175 -0
  155. package/daemon/dist/routes/scope-audit.js.map +1 -0
  156. package/daemon/dist/routes/sessions.d.ts.map +1 -1
  157. package/daemon/dist/routes/sessions.js +67 -3
  158. package/daemon/dist/routes/sessions.js.map +1 -1
  159. package/daemon/dist/routes/skills.d.ts.map +1 -1
  160. package/daemon/dist/routes/skills.js +43 -0
  161. package/daemon/dist/routes/skills.js.map +1 -1
  162. package/daemon/dist/routes/terminal-ws.d.ts +7 -0
  163. package/daemon/dist/routes/terminal-ws.d.ts.map +1 -0
  164. package/daemon/dist/routes/terminal-ws.js +132 -0
  165. package/daemon/dist/routes/terminal-ws.js.map +1 -0
  166. package/daemon/dist/routes/transport.d.ts +3 -1
  167. package/daemon/dist/routes/transport.d.ts.map +1 -1
  168. package/daemon/dist/routes/transport.js +26 -1
  169. package/daemon/dist/routes/transport.js.map +1 -1
  170. package/daemon/dist/routes/whoami.d.ts.map +1 -1
  171. package/daemon/dist/routes/whoami.js +5 -0
  172. package/daemon/dist/routes/whoami.js.map +1 -1
  173. package/daemon/dist/server.d.ts +6 -0
  174. package/daemon/dist/server.d.ts.map +1 -1
  175. package/daemon/dist/server.js +29 -2
  176. package/daemon/dist/server.js.map +1 -1
  177. package/daemon/dist/startup.d.ts +8 -0
  178. package/daemon/dist/startup.d.ts.map +1 -1
  179. package/daemon/dist/startup.js +41 -10
  180. package/daemon/dist/startup.js.map +1 -1
  181. package/daemon/dist/terminal/TerminalSessionBroker.d.ts +173 -0
  182. package/daemon/dist/terminal/TerminalSessionBroker.d.ts.map +1 -0
  183. package/daemon/dist/terminal/TerminalSessionBroker.js +570 -0
  184. package/daemon/dist/terminal/TerminalSessionBroker.js.map +1 -0
  185. package/daemon/specs/agents/shared/skills/core/openrig-user/SKILL.md +131 -2
  186. package/daemon/specs/agents/shared/skills/pods/orchestration-team/SKILL.md +29 -0
  187. package/dist/client.d.ts +1 -0
  188. package/dist/client.d.ts.map +1 -1
  189. package/dist/client.js +23 -0
  190. package/dist/client.js.map +1 -1
  191. package/dist/commands/auth.d.ts +11 -0
  192. package/dist/commands/auth.d.ts.map +1 -0
  193. package/dist/commands/auth.js +145 -0
  194. package/dist/commands/auth.js.map +1 -0
  195. package/dist/commands/capture.d.ts.map +1 -1
  196. package/dist/commands/capture.js +6 -6
  197. package/dist/commands/capture.js.map +1 -1
  198. package/dist/commands/config-init-workspace.d.ts.map +1 -1
  199. package/dist/commands/config-init-workspace.js +7 -4
  200. package/dist/commands/config-init-workspace.js.map +1 -1
  201. package/dist/commands/context.d.ts.map +1 -1
  202. package/dist/commands/context.js +41 -5
  203. package/dist/commands/context.js.map +1 -1
  204. package/dist/commands/down.d.ts.map +1 -1
  205. package/dist/commands/down.js +27 -0
  206. package/dist/commands/down.js.map +1 -1
  207. package/dist/commands/launch.d.ts.map +1 -1
  208. package/dist/commands/launch.js +34 -0
  209. package/dist/commands/launch.js.map +1 -1
  210. package/dist/commands/ps.d.ts.map +1 -1
  211. package/dist/commands/ps.js +361 -53
  212. package/dist/commands/ps.js.map +1 -1
  213. package/dist/commands/queue.d.ts.map +1 -1
  214. package/dist/commands/queue.js +83 -3
  215. package/dist/commands/queue.js.map +1 -1
  216. package/dist/commands/restore-check.d.ts.map +1 -1
  217. package/dist/commands/restore-check.js +80 -2
  218. package/dist/commands/restore-check.js.map +1 -1
  219. package/dist/commands/scope.d.ts.map +1 -1
  220. package/dist/commands/scope.js +747 -5
  221. package/dist/commands/scope.js.map +1 -1
  222. package/dist/commands/seat.d.ts +3 -1
  223. package/dist/commands/seat.d.ts.map +1 -1
  224. package/dist/commands/seat.js +61 -1
  225. package/dist/commands/seat.js.map +1 -1
  226. package/dist/commands/send.d.ts.map +1 -1
  227. package/dist/commands/send.js +46 -13
  228. package/dist/commands/send.js.map +1 -1
  229. package/dist/commands/skill.d.ts +4 -0
  230. package/dist/commands/skill.d.ts.map +1 -0
  231. package/dist/commands/skill.js +77 -0
  232. package/dist/commands/skill.js.map +1 -0
  233. package/dist/commands/up.d.ts.map +1 -1
  234. package/dist/commands/up.js +27 -0
  235. package/dist/commands/up.js.map +1 -1
  236. package/dist/commands/whoami.d.ts.map +1 -1
  237. package/dist/commands/whoami.js +208 -20
  238. package/dist/commands/whoami.js.map +1 -1
  239. package/dist/cross-host-executor.d.ts +1 -1
  240. package/dist/cross-host-executor.d.ts.map +1 -1
  241. package/dist/cross-host-executor.js +3 -2
  242. package/dist/cross-host-executor.js.map +1 -1
  243. package/dist/cross-host-types.d.ts +2 -0
  244. package/dist/cross-host-types.d.ts.map +1 -0
  245. package/dist/cross-host-types.js +2 -0
  246. package/dist/cross-host-types.js.map +1 -0
  247. package/dist/host-registry.d.ts +27 -5
  248. package/dist/host-registry.d.ts.map +1 -1
  249. package/dist/host-registry.js +86 -19
  250. package/dist/host-registry.js.map +1 -1
  251. package/dist/index.d.ts +1 -0
  252. package/dist/index.d.ts.map +1 -1
  253. package/dist/index.js +4 -0
  254. package/dist/index.js.map +1 -1
  255. package/dist/lib/codex-auth.d.ts +124 -0
  256. package/dist/lib/codex-auth.d.ts.map +1 -0
  257. package/dist/lib/codex-auth.js +418 -0
  258. package/dist/lib/codex-auth.js.map +1 -0
  259. package/dist/lib/scope/progress-edit.d.ts +42 -0
  260. package/dist/lib/scope/progress-edit.d.ts.map +1 -0
  261. package/dist/lib/scope/progress-edit.js +171 -0
  262. package/dist/lib/scope/progress-edit.js.map +1 -0
  263. package/dist/lib/scope/scope-audit.d.ts +38 -0
  264. package/dist/lib/scope/scope-audit.d.ts.map +1 -0
  265. package/dist/lib/scope/scope-audit.js +191 -0
  266. package/dist/lib/scope/scope-audit.js.map +1 -0
  267. package/dist/lib/scope/templates.d.ts +11 -0
  268. package/dist/lib/scope/templates.d.ts.map +1 -1
  269. package/dist/lib/scope/templates.js +22 -1
  270. package/dist/lib/scope/templates.js.map +1 -1
  271. package/dist/lib/scope/trust.d.ts +30 -0
  272. package/dist/lib/scope/trust.d.ts.map +1 -0
  273. package/dist/lib/scope/trust.js +80 -0
  274. package/dist/lib/scope/trust.js.map +1 -0
  275. package/dist/lib/scope/types.d.ts +6 -0
  276. package/dist/lib/scope/types.d.ts.map +1 -1
  277. package/dist/lib/scope/types.js +8 -0
  278. package/dist/lib/scope/types.js.map +1 -1
  279. package/dist/lib/scope-templates/backlog-deprecation.md +1 -0
  280. package/dist/lib/scope-templates/backlog-tech-debt.md +1 -0
  281. package/dist/lib/scope-templates/bug-fix.md +1 -0
  282. package/dist/lib/scope-templates/mission-brief.md +20 -0
  283. package/dist/lib/scope-templates/mission-placeholder.md +1 -0
  284. package/dist/lib/scope-templates/mission-progress.md +12 -0
  285. package/dist/lib/scope-templates/mission-release.md +1 -0
  286. package/dist/lib/scope-templates/placeholder.md +9 -0
  287. package/dist/lib/scope-templates/proof.md +17 -0
  288. package/dist/lib/scope-templates/release-feature.md +1 -0
  289. package/dist/lib/scope-templates/research.md +1 -0
  290. package/dist/lib/scope-templates/slice-progress.md +11 -0
  291. package/dist/remote-host-ops.d.ts +24 -0
  292. package/dist/remote-host-ops.d.ts.map +1 -0
  293. package/dist/remote-host-ops.js +53 -0
  294. package/dist/remote-host-ops.js.map +1 -0
  295. package/package.json +2 -1
  296. package/ui/dist/assets/index-CnqRX7A3.css +32 -0
  297. package/ui/dist/assets/index-CtL9jXFt.js +582 -0
  298. package/ui/dist/index.html +2 -2
  299. package/ui/dist/assets/index-C_Q5FczU.css +0 -1
  300. package/ui/dist/assets/index-De6vv0yO.js +0 -552
@@ -0,0 +1,191 @@
1
+ import * as YAML from "yaml";
2
+ import { isMissionDotId, isSliceDotId } from "./dot-id.js";
3
+ const MISSION_BRIEF_HEADERS = ["What & why", "Building", "Progress", "Proven", "Needs you", "Pointers"];
4
+ function childPath(parent, child) {
5
+ return parent.endsWith("/") ? `${parent}${child}` : `${parent}/${child}`;
6
+ }
7
+ function missionBriefFix() {
8
+ return "Create/populate MISSION_BRIEF.md using the slice-16 schema: # <Mission name> — Brief, then ## What & why, ## Building, ## Progress, ## Proven, ## Needs you, ## Pointers.";
9
+ }
10
+ function missionBriefConforms(content) {
11
+ const lines = content.split(/\r?\n/);
12
+ const title = lines.find((line) => /^#\s+/.test(line) && !/^##\s+/.test(line))?.trim() ?? "";
13
+ if (!/^#\s+.+\s+—\s+Brief\s*$/.test(title))
14
+ return false;
15
+ const h2s = lines
16
+ .map((line) => /^##\s+(.+?)\s*$/.exec(line)?.[1]?.trim() ?? null)
17
+ .filter((header) => header !== null);
18
+ if (h2s.length < MISSION_BRIEF_HEADERS.length)
19
+ return false;
20
+ return MISSION_BRIEF_HEADERS.every((header, idx) => h2s[idx] === header);
21
+ }
22
+ function parseStatusFromFrontmatter(raw) {
23
+ if (raw === null)
24
+ return null;
25
+ try {
26
+ const parsed = YAML.parse(raw);
27
+ if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
28
+ const status = parsed.status;
29
+ return typeof status === "string" ? status : null;
30
+ }
31
+ }
32
+ catch {
33
+ return null;
34
+ }
35
+ return null;
36
+ }
37
+ function statusRequiresProof(status) {
38
+ if (!status)
39
+ return false;
40
+ const normalized = status.toLowerCase().trim();
41
+ return normalized.includes("done")
42
+ || normalized.includes("ship")
43
+ || normalized.includes("close")
44
+ || normalized.includes("proven")
45
+ || normalized.includes("promoted");
46
+ }
47
+ export function classifyScopeItem(input) {
48
+ const findings = [];
49
+ let frontmatterError = null;
50
+ let railStatus;
51
+ // Rail status
52
+ if (input.readmeOnlyMarker) {
53
+ railStatus = "readme-only";
54
+ }
55
+ else if (input.progressFileExists) {
56
+ railStatus = "present";
57
+ }
58
+ else {
59
+ railStatus = "missing";
60
+ findings.push({
61
+ kind: "missing_progress",
62
+ severity: input.isActiveRelease ? "high" : "low",
63
+ path: input.path,
64
+ message: `${input.level} has no PROGRESS.md and no readme-only marker`,
65
+ remediation: `Run: rig scope ${input.level} create (scaffolds PROGRESS.md) or add progress_rail: readme-only to README frontmatter`,
66
+ });
67
+ }
68
+ // Frontmatter classification (strict parse, NOT parseYamlSafely)
69
+ if (input.readmeFrontmatterRaw === null) {
70
+ findings.push({
71
+ kind: "missing_id",
72
+ severity: input.isActiveRelease ? "high" : "low",
73
+ path: input.path,
74
+ message: `README has no frontmatter (no id can be extracted)`,
75
+ remediation: "Add YAML frontmatter with an id: field to the README",
76
+ });
77
+ }
78
+ else {
79
+ let parsed = null;
80
+ let parseError = null;
81
+ try {
82
+ parsed = YAML.parse(input.readmeFrontmatterRaw);
83
+ }
84
+ catch (err) {
85
+ parseError = err instanceof Error ? err.message : String(err);
86
+ }
87
+ const hasIdLine = /^id\s*:/m.test(input.readmeFrontmatterRaw);
88
+ if (parseError) {
89
+ frontmatterError = parseError;
90
+ railStatus = "malformed";
91
+ if (hasIdLine) {
92
+ findings.push({
93
+ kind: "registration_ghost",
94
+ severity: input.isActiveRelease ? "high" : "low",
95
+ path: input.path,
96
+ message: `README has an id: line but frontmatter fails to parse (registration ghost): ${parseError}`,
97
+ remediation: "Fix the YAML frontmatter syntax error so the id can be read",
98
+ });
99
+ }
100
+ else {
101
+ findings.push({
102
+ kind: "registration_ghost",
103
+ severity: input.isActiveRelease ? "high" : "low",
104
+ path: input.path,
105
+ message: `README frontmatter fails to parse: ${parseError}`,
106
+ remediation: "Fix the YAML frontmatter syntax error",
107
+ });
108
+ }
109
+ }
110
+ else {
111
+ const fm = parsed && typeof parsed === "object" && !Array.isArray(parsed)
112
+ ? parsed
113
+ : {};
114
+ const id = typeof fm.id === "string" ? fm.id : null;
115
+ if (!id) {
116
+ findings.push({
117
+ kind: "missing_id",
118
+ severity: input.isActiveRelease ? "high" : "low",
119
+ path: input.path,
120
+ message: `README frontmatter has no id field`,
121
+ remediation: "Add an id: field to the README frontmatter matching the scope dot-ID convention",
122
+ });
123
+ }
124
+ else {
125
+ const validator = input.level === "mission" ? isMissionDotId : isSliceDotId;
126
+ if (!validator(id)) {
127
+ findings.push({
128
+ kind: "id_convention_violation",
129
+ severity: input.isActiveRelease ? "high" : "info",
130
+ path: input.path,
131
+ message: `id "${id}" does not match the ${input.level} dot-ID convention`,
132
+ remediation: `Use a valid ${input.level} dot-ID format`,
133
+ });
134
+ }
135
+ }
136
+ }
137
+ }
138
+ if (input.level === "mission") {
139
+ const briefPath = input.missionBriefPath ?? childPath(input.path, "MISSION_BRIEF.md");
140
+ if (input.missionBriefExists === false) {
141
+ findings.push({
142
+ kind: "missing_mission_brief",
143
+ severity: "medium",
144
+ path: briefPath,
145
+ message: "Mission has no root MISSION_BRIEF.md, so the Steering tab human-facing brief degrades.",
146
+ remediation: missionBriefFix(),
147
+ });
148
+ }
149
+ else if (input.missionBriefExists === true
150
+ && typeof input.missionBriefContent === "string"
151
+ && !missionBriefConforms(input.missionBriefContent)) {
152
+ findings.push({
153
+ kind: "malformed_mission_brief",
154
+ severity: "medium",
155
+ path: briefPath,
156
+ message: "MISSION_BRIEF.md does not match the canonical MISSION_BRIEF.md section order.",
157
+ remediation: missionBriefFix(),
158
+ });
159
+ }
160
+ if (input.missionNotesExists === false) {
161
+ const notesPath = input.missionNotesPath ?? childPath(input.path, "MISSION_NOTES.md");
162
+ findings.push({
163
+ kind: "missing_mission_notes",
164
+ severity: "low",
165
+ path: notesPath,
166
+ message: "Mission has no MISSION_NOTES.md continuity file.",
167
+ remediation: "Add MISSION_NOTES.md at the mission root and populate it per the mission-notes convention.",
168
+ });
169
+ }
170
+ }
171
+ if (input.level === "slice") {
172
+ const status = input.sliceStatus ?? parseStatusFromFrontmatter(input.readmeFrontmatterRaw);
173
+ const hasProofPacket = input.hasProofPacket === true;
174
+ const hasRootProof = input.proofFileExists === true
175
+ && input.proofDirExists === true
176
+ && input.proofDirHasEntries === true;
177
+ const isProven = statusRequiresProof(status) || hasProofPacket;
178
+ if (isProven && !hasRootProof) {
179
+ const proofPath = input.proofFilePath ?? childPath(input.path, "PROOF.md");
180
+ findings.push({
181
+ kind: "missing_proof",
182
+ severity: "medium",
183
+ path: proofPath,
184
+ message: "Slice is done/proven but does not have complete root PROOF.md plus populated proof/ artifacts.",
185
+ remediation: "Add PROOF.md at the slice root and put verification artifacts under proof/ per the slice-closeout SOP.",
186
+ });
187
+ }
188
+ }
189
+ return { railStatus, findings, frontmatterError };
190
+ }
191
+ //# sourceMappingURL=scope-audit.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scope-audit.js","sourceRoot":"","sources":["../../../src/domain/scope/scope-audit.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,67 @@
1
+ /** Scope tiers. v0 ships `mission` + `slice`; `project` and `sub-slice`
2
+ * exist in the grammar but have no CLI verbs yet. */
3
+ export type ScopeTier = "project" | "mission" | "slice" | "sub-slice";
4
+ /** Stable reference ID parts. `OPR.0.3.2.12` → project="OPR",
5
+ * version="0.3.2", n=12. Escape-band non-release missions look like
6
+ * `OPR.99.0.1` → version="99.0.1", n=undefined. */
7
+ export interface DotId {
8
+ project: string;
9
+ version: string;
10
+ n?: number;
11
+ m?: number;
12
+ }
13
+ export interface MissionInfo {
14
+ /** Mission folder name (e.g., "release-0.3.2", "backlog"). */
15
+ name: string;
16
+ /** Absolute path to the mission folder. */
17
+ absPath: string;
18
+ /** Path to the mission's README.md, if present. */
19
+ readmePath: string | null;
20
+ /** Parsed frontmatter from the README. */
21
+ frontmatter: Record<string, unknown>;
22
+ /** Minted dot-ID for this mission (read from frontmatter if present,
23
+ * otherwise inferred from the folder name pattern). */
24
+ id: string | null;
25
+ activeSliceCount: number;
26
+ closedSliceCount: number;
27
+ }
28
+ export interface SliceInfo {
29
+ name: string;
30
+ absPath: string;
31
+ readmePath: string | null;
32
+ frontmatter: Record<string, unknown>;
33
+ /** "NN-slug" → NN. */
34
+ nn: number | null;
35
+ /** "NN-slug" → slug. */
36
+ slug: string | null;
37
+ missionName: string;
38
+ /** Minted dot-ID, parent.NN form. */
39
+ id: string | null;
40
+ /** Frontmatter `status` field, lowercased. */
41
+ status: string | null;
42
+ }
43
+ /** 3-part error shape per `building-agent-software` skill §3.6. */
44
+ export declare class ScopeCliError extends Error {
45
+ readonly fact: string;
46
+ readonly consequence: string;
47
+ readonly action: string;
48
+ constructor(opts: {
49
+ fact: string;
50
+ consequence: string;
51
+ action: string;
52
+ });
53
+ }
54
+ export type SliceState = "active" | "closed" | "shipped" | "all";
55
+ export type SliceTemplateKind = "placeholder" | "bug-fix" | "backlog-deprecation" | "backlog-tech-debt" | "release-feature" | "research";
56
+ export declare const SLICE_TEMPLATE_KINDS: ReadonlyArray<SliceTemplateKind>;
57
+ export type MissionTemplateKind = "placeholder" | "release";
58
+ export declare const MISSION_TEMPLATE_KINDS: ReadonlyArray<MissionTemplateKind>;
59
+ export type CloseReason = "wontfix" | "deferred" | "superseded" | "stale";
60
+ export declare const CLOSE_REASONS: ReadonlyArray<CloseReason>;
61
+ /** OPR.0.4.1.6 — the scope-and-versioning §2 epistemic-maturity `stage` enum
62
+ * (4 rungs + 2 exits). The ONLY valid stage values; invented values
63
+ * (shape/shaped/draft) are rejected. `superseded` must name its successor;
64
+ * `retired` means do-not-use. */
65
+ export type Stage = "wip" | "provisional" | "established" | "canonical" | "superseded" | "retired";
66
+ export declare const STAGE_VALUES: ReadonlyArray<Stage>;
67
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/domain/scope/types.ts"],"names":[],"mappings":"AAOA;sDACsD;AACtD,MAAM,MAAM,SAAS,GAAG,SAAS,GAAG,SAAS,GAAG,OAAO,GAAG,WAAW,CAAC;AAEtE;;oDAEoD;AACpD,MAAM,WAAW,KAAK;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,CAAC,CAAC,EAAE,MAAM,CAAC;IACX,CAAC,CAAC,EAAE,MAAM,CAAC;CACZ;AAED,MAAM,WAAW,WAAW;IAC1B,8DAA8D;IAC9D,IAAI,EAAE,MAAM,CAAC;IACb,2CAA2C;IAC3C,OAAO,EAAE,MAAM,CAAC;IAChB,mDAAmD;IACnD,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,0CAA0C;IAC1C,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACrC;4DACwD;IACxD,EAAE,EAAE,MAAM,GAAG,IAAI,CAAC;IAClB,gBAAgB,EAAE,MAAM,CAAC;IACzB,gBAAgB,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACrC,sBAAsB;IACtB,EAAE,EAAE,MAAM,GAAG,IAAI,CAAC;IAClB,wBAAwB;IACxB,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,qCAAqC;IACrC,EAAE,EAAE,MAAM,GAAG,IAAI,CAAC;IAClB,8CAA8C;IAC9C,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;CACvB;AAED,mEAAmE;AACnE,qBAAa,aAAc,SAAQ,KAAK;IACtC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;gBACZ,IAAI,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE;CAOxE;AAED,MAAM,MAAM,UAAU,GAAG,QAAQ,GAAG,QAAQ,GAAG,SAAS,GAAG,KAAK,CAAC;AACjE,MAAM,MAAM,iBAAiB,GACzB,aAAa,GACb,SAAS,GACT,qBAAqB,GACrB,mBAAmB,GACnB,iBAAiB,GACjB,UAAU,CAAC;AACf,eAAO,MAAM,oBAAoB,EAAE,aAAa,CAAC,iBAAiB,CAOjE,CAAC;AAEF,MAAM,MAAM,mBAAmB,GAAG,aAAa,GAAG,SAAS,CAAC;AAC5D,eAAO,MAAM,sBAAsB,EAAE,aAAa,CAAC,mBAAmB,CAGrE,CAAC;AAEF,MAAM,MAAM,WAAW,GAAG,SAAS,GAAG,UAAU,GAAG,YAAY,GAAG,OAAO,CAAC;AAC1E,eAAO,MAAM,aAAa,EAAE,aAAa,CAAC,WAAW,CAKpD,CAAC;AAEF;;;kCAGkC;AAClC,MAAM,MAAM,KAAK,GACb,KAAK,GACL,aAAa,GACb,aAAa,GACb,WAAW,GACX,YAAY,GACZ,SAAS,CAAC;AACd,eAAO,MAAM,YAAY,EAAE,aAAa,CAAC,KAAK,CAO7C,CAAC"}
@@ -0,0 +1,46 @@
1
+ // release-0.3.2 slice 12 — scope CLI primitive types.
2
+ //
3
+ // Aligned with the substrate convention at
4
+ // `openrig-work/conventions/scope-and-versioning/README.md` (stage:
5
+ // provisional, authored 2026-05-15). The CLI mints stable dot-IDs
6
+ // into created mission/slice frontmatter per §1 of that convention.
7
+ /** 3-part error shape per `building-agent-software` skill §3.6. */
8
+ export class ScopeCliError extends Error {
9
+ fact;
10
+ consequence;
11
+ action;
12
+ constructor(opts) {
13
+ super(`${opts.fact}\n${opts.consequence}\n${opts.action}`);
14
+ this.name = "ScopeCliError";
15
+ this.fact = opts.fact;
16
+ this.consequence = opts.consequence;
17
+ this.action = opts.action;
18
+ }
19
+ }
20
+ export const SLICE_TEMPLATE_KINDS = [
21
+ "placeholder",
22
+ "bug-fix",
23
+ "backlog-deprecation",
24
+ "backlog-tech-debt",
25
+ "release-feature",
26
+ "research",
27
+ ];
28
+ export const MISSION_TEMPLATE_KINDS = [
29
+ "placeholder",
30
+ "release",
31
+ ];
32
+ export const CLOSE_REASONS = [
33
+ "wontfix",
34
+ "deferred",
35
+ "superseded",
36
+ "stale",
37
+ ];
38
+ export const STAGE_VALUES = [
39
+ "wip",
40
+ "provisional",
41
+ "established",
42
+ "canonical",
43
+ "superseded",
44
+ "retired",
45
+ ];
46
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/domain/scope/types.ts"],"names":[],"mappings":"AAAA,sDAAsD;AACtD,EAAE;AACF,2CAA2C;AAC3C,oEAAoE;AACpE,kEAAkE;AAClE,oEAAoE;AAgDpE,mEAAmE;AACnE,MAAM,OAAO,aAAc,SAAQ,KAAK;IAC7B,IAAI,CAAS;IACb,WAAW,CAAS;IACpB,MAAM,CAAS;IACxB,YAAY,IAA2D;QACrE,KAAK,CAAC,GAAG,IAAI,CAAC,IAAI,KAAK,IAAI,CAAC,WAAW,KAAK,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC;QAC3D,IAAI,CAAC,IAAI,GAAG,eAAe,CAAC;QAC5B,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC;QACtB,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC,WAAW,CAAC;QACpC,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC;IAC5B,CAAC;CACF;AAUD,MAAM,CAAC,MAAM,oBAAoB,GAAqC;IACpE,aAAa;IACb,SAAS;IACT,qBAAqB;IACrB,mBAAmB;IACnB,iBAAiB;IACjB,UAAU;CACX,CAAC;AAGF,MAAM,CAAC,MAAM,sBAAsB,GAAuC;IACxE,aAAa;IACb,SAAS;CACV,CAAC;AAGF,MAAM,CAAC,MAAM,aAAa,GAA+B;IACvD,SAAS;IACT,UAAU;IACV,YAAY;IACZ,OAAO;CACR,CAAC;AAaF,MAAM,CAAC,MAAM,YAAY,GAAyB;IAChD,KAAK;IACL,aAAa;IACb,aAAa;IACb,WAAW;IACX,YAAY;IACZ,SAAS;CACV,CAAC"}
@@ -1,3 +1,4 @@
1
+ import type Database from "better-sqlite3";
1
2
  import type { SessionRegistry } from "./session-registry.js";
2
3
  import type { EventBus } from "./event-bus.js";
3
4
  import type { AgentActivityStore } from "./agent-activity-store.js";
@@ -15,6 +16,14 @@ export interface ClearAttentionResult {
15
16
  reason?: string;
16
17
  detail?: string;
17
18
  previousError?: string | null;
19
+ clearedClasses?: ("startup_status" | "restore_outcome")[];
20
+ derivedEvidence?: {
21
+ source: string;
22
+ kind?: string;
23
+ state?: string;
24
+ reason?: string;
25
+ runtimeCwdVerified: boolean;
26
+ };
18
27
  }
19
28
  export interface SendVerifyFn {
20
29
  (sessionName: string, text: string, opts?: {
@@ -41,6 +50,7 @@ interface ClearAttentionDeps {
41
50
  agentActivityStore: AgentActivityStore;
42
51
  sendVerify?: SendVerifyFn;
43
52
  capture?: CaptureFn;
53
+ db?: Database.Database;
44
54
  }
45
55
  export declare class SeatAttentionReconciler {
46
56
  private deps;
@@ -48,7 +58,9 @@ export declare class SeatAttentionReconciler {
48
58
  clearAttention(sessionName: string, opts?: {
49
59
  reason?: string;
50
60
  }): Promise<ClearAttentionResult>;
61
+ private performEvidenceClear;
51
62
  private findLatestSessionByName;
63
+ private getDerivedAttentionOutcome;
52
64
  }
53
65
  export {};
54
66
  //# sourceMappingURL=seat-attention-reconciler.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"seat-attention-reconciler.d.ts","sourceRoot":"","sources":["../../src/domain/seat-attention-reconciler.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAC7D,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAC/C,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAGpE,MAAM,WAAW,oBAAoB;IACnC,EAAE,EAAE,OAAO,CAAC;IACZ,IAAI,CAAC,EAAE,kBAAkB,GAAG,6BAA6B,GAAG,SAAS,CAAC;IACtE,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,SAAS,CAAC,EAAE,UAAU,GAAG,sBAAsB,CAAC;IAChD,QAAQ,CAAC,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAC7D,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC/B;AAED,MAAM,WAAW,YAAY;IAC3B,CAAC,WAAW,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE;QAAE,MAAM,CAAC,EAAE,OAAO,CAAA;KAAE,GAAG,OAAO,CAAC;QAAE,EAAE,EAAE,OAAO,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,OAAO,CAAA;KAAE,CAAC,CAAC;CAClI;AAED,MAAM,WAAW,SAAS;IACxB,CAAC,WAAW,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC;QAAE,EAAE,EAAE,OAAO,CAAC;QAAC,WAAW,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CACnI;AAED,UAAU,kBAAkB;IAC1B,eAAe,EAAE,eAAe,CAAC;IACjC,QAAQ,EAAE,QAAQ,CAAC;IACnB,kBAAkB,EAAE,kBAAkB,CAAC;IACvC,UAAU,CAAC,EAAE,YAAY,CAAC;IAC1B,OAAO,CAAC,EAAE,SAAS,CAAC;CACrB;AAID,qBAAa,uBAAuB;IAClC,OAAO,CAAC,IAAI,CAAqB;gBAErB,IAAI,EAAE,kBAAkB;IAI9B,cAAc,CAClB,WAAW,EAAE,MAAM,EACnB,IAAI,CAAC,EAAE;QAAE,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE,GACzB,OAAO,CAAC,oBAAoB,CAAC;IAmJhC,OAAO,CAAC,uBAAuB;CA0ChC"}
1
+ {"version":3,"file":"seat-attention-reconciler.d.ts","sourceRoot":"","sources":["../../src/domain/seat-attention-reconciler.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,QAAQ,MAAM,gBAAgB,CAAC;AAC3C,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAC7D,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAC/C,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAGpE,MAAM,WAAW,oBAAoB;IACnC,EAAE,EAAE,OAAO,CAAC;IACZ,IAAI,CAAC,EAAE,kBAAkB,GAAG,6BAA6B,GAAG,SAAS,CAAC;IACtE,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,SAAS,CAAC,EAAE,UAAU,GAAG,sBAAsB,CAAC;IAChD,QAAQ,CAAC,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAC7D,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,cAAc,CAAC,EAAE,CAAC,gBAAgB,GAAG,iBAAiB,CAAC,EAAE,CAAC;IAC1D,eAAe,CAAC,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,kBAAkB,EAAE,OAAO,CAAA;KAAE,CAAC;CACnH;AAED,MAAM,WAAW,YAAY;IAC3B,CAAC,WAAW,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE;QAAE,MAAM,CAAC,EAAE,OAAO,CAAA;KAAE,GAAG,OAAO,CAAC;QAAE,EAAE,EAAE,OAAO,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,OAAO,CAAA;KAAE,CAAC,CAAC;CAClI;AAED,MAAM,WAAW,SAAS;IACxB,CAAC,WAAW,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC;QAAE,EAAE,EAAE,OAAO,CAAC;QAAC,WAAW,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CACnI;AAED,UAAU,kBAAkB;IAC1B,eAAe,EAAE,eAAe,CAAC;IACjC,QAAQ,EAAE,QAAQ,CAAC;IACnB,kBAAkB,EAAE,kBAAkB,CAAC;IACvC,UAAU,CAAC,EAAE,YAAY,CAAC;IAC1B,OAAO,CAAC,EAAE,SAAS,CAAC;IACpB,EAAE,CAAC,EAAE,QAAQ,CAAC,QAAQ,CAAC;CACxB;AAID,qBAAa,uBAAuB;IAClC,OAAO,CAAC,IAAI,CAAqB;gBAErB,IAAI,EAAE,kBAAkB;IAI9B,cAAc,CAClB,WAAW,EAAE,MAAM,EACnB,IAAI,CAAC,EAAE;QAAE,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE,GACzB,OAAO,CAAC,oBAAoB,CAAC;IAuGhC,OAAO,CAAC,oBAAoB;IAqD5B,OAAO,CAAC,uBAAuB;IA8C/B,OAAO,CAAC,0BAA0B;CA0BnC"}
@@ -13,24 +13,42 @@ export class SeatAttentionReconciler {
13
13
  if (!session) {
14
14
  return { ok: false, code: "not_in_attention", detail: `Session '${sessionName}' not found` };
15
15
  }
16
- if (session.startupStatus !== "attention_required" && session.startupStatus !== "failed") {
17
- return { ok: false, code: "not_in_attention", detail: `Session startup_status is '${session.startupStatus}', not attention_required/failed` };
16
+ const startupClassActive = session.startupStatus === "attention_required" || session.startupStatus === "failed";
17
+ const derivedOutcome = this.getDerivedAttentionOutcome(session);
18
+ if (!startupClassActive && !!!derivedOutcome) {
19
+ return { ok: false, code: "not_in_attention", detail: `Session startup_status is '${session.startupStatus}' and restoreOutcome is not attention/failed — not in attention` };
18
20
  }
19
21
  const previousError = session.latestError ?? null;
20
22
  // Operator attestation override (--reason).
21
23
  if (opts?.reason) {
22
- sessionRegistry.updateStartupStatus(session.id, "ready", new Date().toISOString());
23
- eventBus.emit({
24
- type: "seat.attention_cleared",
25
- rigId: session.rigId,
26
- nodeId: session.nodeId,
27
- sessionName,
28
- from: session.startupStatus,
29
- to: "ready",
30
- clearedBy: "operator_attestation",
31
- reason: opts.reason,
32
- previousError,
33
- });
24
+ const clearedClasses = [];
25
+ if (startupClassActive) {
26
+ sessionRegistry.updateStartupStatus(session.id, "ready", new Date().toISOString());
27
+ eventBus.emit({
28
+ type: "seat.attention_cleared",
29
+ rigId: session.rigId,
30
+ nodeId: session.nodeId,
31
+ sessionName,
32
+ from: session.startupStatus,
33
+ to: "ready",
34
+ clearedBy: "operator_attestation",
35
+ reason: opts.reason,
36
+ previousError,
37
+ });
38
+ clearedClasses.push("startup_status");
39
+ }
40
+ if (derivedOutcome) {
41
+ eventBus.emit({
42
+ type: "restore.outcome_reconciled",
43
+ rigId: session.rigId,
44
+ nodeId: session.nodeId,
45
+ attemptId: 0,
46
+ from: derivedOutcome,
47
+ to: "operator_recovered",
48
+ evidence: { source: "operator_attestation", reason: opts.reason, runtimeCwdVerified: false },
49
+ });
50
+ clearedClasses.push("restore_outcome");
51
+ }
34
52
  return {
35
53
  ok: true,
36
54
  code: "cleared",
@@ -39,6 +57,8 @@ export class SeatAttentionReconciler {
39
57
  clearedBy: "operator_attestation",
40
58
  reason: opts.reason,
41
59
  previousError,
60
+ clearedClasses,
61
+ derivedEvidence: derivedOutcome ? { source: "operator_attestation", reason: opts.reason, runtimeCwdVerified: false } : undefined,
42
62
  };
43
63
  }
44
64
  // Evidence-gated clear.
@@ -47,27 +67,8 @@ export class SeatAttentionReconciler {
47
67
  sessionName,
48
68
  });
49
69
  if (activity && activity.stale !== true && POSITIVE_STATES.has(activity.state)) {
50
- sessionRegistry.updateStartupStatus(session.id, "ready", new Date().toISOString());
51
- eventBus.emit({
52
- type: "seat.attention_cleared",
53
- rigId: session.rigId,
54
- nodeId: session.nodeId,
55
- sessionName,
56
- from: session.startupStatus,
57
- to: "ready",
58
- clearedBy: "evidence",
59
- evidence: { kind: "fresh_activity", state: activity.state, reason: activity.reason },
60
- previousError,
61
- });
62
- return {
63
- ok: true,
64
- code: "cleared",
65
- from: session.startupStatus,
66
- to: "ready",
67
- clearedBy: "evidence",
68
- evidence: { kind: "fresh_activity", state: activity.state, reason: activity.reason },
69
- previousError,
70
- };
70
+ const evidence = { kind: "fresh_activity", state: activity.state, reason: activity.reason };
71
+ return this.performEvidenceClear(session, sessionName, startupClassActive, derivedOutcome, evidence, previousError);
71
72
  }
72
73
  // Second evidence path: active send-verify round-trip.
73
74
  if (this.deps.sendVerify) {
@@ -75,67 +76,21 @@ export class SeatAttentionReconciler {
75
76
  const probeText = `# OpenRig attention-clear liveness probe ${Date.now()}`;
76
77
  const sendResult = await this.deps.sendVerify(sessionName, probeText, { verify: true });
77
78
  if (sendResult.ok && (sendResult.outcome === "delivered" || sendResult.verified === true)) {
78
- sessionRegistry.updateStartupStatus(session.id, "ready", new Date().toISOString());
79
- eventBus.emit({
80
- type: "seat.attention_cleared",
81
- rigId: session.rigId,
82
- nodeId: session.nodeId,
83
- sessionName,
84
- from: session.startupStatus,
85
- to: "ready",
86
- clearedBy: "evidence",
87
- evidence: { kind: "send_verify_roundtrip", state: sendResult.outcome ?? "delivered" },
88
- previousError,
89
- });
90
- return {
91
- ok: true,
92
- code: "cleared",
93
- from: session.startupStatus,
94
- to: "ready",
95
- clearedBy: "evidence",
96
- evidence: { kind: "send_verify_roundtrip", state: sendResult.outcome ?? "delivered" },
97
- previousError,
98
- };
79
+ const evidence = { kind: "send_verify_roundtrip", state: sendResult.outcome ?? "delivered" };
80
+ return this.performEvidenceClear(session, sessionName, startupClassActive, derivedOutcome, evidence, previousError);
99
81
  }
100
- // rendered-unconfirmed: text landed but verify raced a TUI redraw.
101
- // Attempt capture-confirmation if capture dep is available.
102
82
  if (sendResult.ok && sendResult.outcome === "rendered-unconfirmed" && this.deps.capture) {
103
83
  try {
104
84
  const captureResult = await this.deps.capture(sessionName, { lines: 50 });
105
85
  if (captureResult.ok && captureResult.content && captureResult.content.includes(probeText)) {
106
- sessionRegistry.updateStartupStatus(session.id, "ready", new Date().toISOString());
107
- eventBus.emit({
108
- type: "seat.attention_cleared",
109
- rigId: session.rigId,
110
- nodeId: session.nodeId,
111
- sessionName,
112
- from: session.startupStatus,
113
- to: "ready",
114
- clearedBy: "evidence",
115
- evidence: { kind: "send_verify_capture_confirmed", state: "rendered-unconfirmed" },
116
- previousError,
117
- });
118
- return {
119
- ok: true,
120
- code: "cleared",
121
- from: session.startupStatus,
122
- to: "ready",
123
- clearedBy: "evidence",
124
- evidence: { kind: "send_verify_capture_confirmed", state: "rendered-unconfirmed" },
125
- previousError,
126
- };
86
+ const evidence = { kind: "send_verify_capture_confirmed", state: "rendered-unconfirmed" };
87
+ return this.performEvidenceClear(session, sessionName, startupClassActive, derivedOutcome, evidence, previousError);
127
88
  }
128
89
  }
129
- catch {
130
- // Capture failed — transport error. Do not clear on capture failure.
131
- }
90
+ catch { /* Capture failed */ }
132
91
  }
133
- // No capture dep, or capture didn't confirm: could-not-confirm, NOT dead.
134
- // failed: transport did not land. Neither clears.
135
- }
136
- catch {
137
- // Send failed — transport error. Do not clear.
138
92
  }
93
+ catch { /* Send failed */ }
139
94
  }
140
95
  return {
141
96
  ok: false,
@@ -145,8 +100,50 @@ export class SeatAttentionReconciler {
145
100
  : "No recent agent activity found; send-verify also not confirmed",
146
101
  };
147
102
  }
103
+ performEvidenceClear(session, sessionName, startupClassActive, derivedOutcome, evidence, previousError) {
104
+ const { sessionRegistry, eventBus } = this.deps;
105
+ const clearedClasses = [];
106
+ if (startupClassActive) {
107
+ sessionRegistry.updateStartupStatus(session.id, "ready", new Date().toISOString());
108
+ eventBus.emit({
109
+ type: "seat.attention_cleared",
110
+ rigId: session.rigId,
111
+ nodeId: session.nodeId,
112
+ sessionName,
113
+ from: session.startupStatus,
114
+ to: "ready",
115
+ clearedBy: "evidence",
116
+ evidence,
117
+ previousError,
118
+ });
119
+ clearedClasses.push("startup_status");
120
+ }
121
+ if (derivedOutcome) {
122
+ eventBus.emit({
123
+ type: "restore.outcome_reconciled",
124
+ rigId: session.rigId,
125
+ nodeId: session.nodeId,
126
+ attemptId: 0,
127
+ from: derivedOutcome,
128
+ to: "operator_recovered",
129
+ evidence: { source: "clear_attention_evidence", kind: evidence.kind, state: evidence.state, runtimeCwdVerified: false },
130
+ });
131
+ clearedClasses.push("restore_outcome");
132
+ }
133
+ return {
134
+ ok: true,
135
+ code: "cleared",
136
+ from: session.startupStatus,
137
+ to: "ready",
138
+ clearedBy: "evidence",
139
+ evidence,
140
+ previousError,
141
+ clearedClasses,
142
+ derivedEvidence: derivedOutcome ? { source: "clear_attention_evidence", kind: evidence.kind, state: evidence.state, runtimeCwdVerified: false } : undefined,
143
+ };
144
+ }
148
145
  findLatestSessionByName(sessionName) {
149
- const row = this.deps.sessionRegistry.db.prepare(`SELECT s.id, s.node_id, n.rig_id, s.startup_status,
146
+ const row = this.deps.sessionRegistry.db.prepare(`SELECT s.id, s.node_id, n.rig_id, s.startup_status, s.status,
150
147
  (SELECT e.payload FROM events e WHERE e.node_id = s.node_id AND e.type IN ('node.startup_attention_required','node.startup_failed') ORDER BY e.seq DESC LIMIT 1) as latest_error_payload
151
148
  FROM sessions s
152
149
  JOIN nodes n ON n.id = s.node_id
@@ -169,8 +166,39 @@ export class SeatAttentionReconciler {
169
166
  nodeId: row.node_id,
170
167
  rigId: row.rig_id,
171
168
  startupStatus: row.startup_status ?? "pending",
169
+ sessionStatus: row.status ?? "unknown",
172
170
  latestError,
173
171
  };
174
172
  }
173
+ getDerivedAttentionOutcome(session) {
174
+ if (!this.deps.db)
175
+ return null;
176
+ const rows = this.deps.db.prepare("SELECT type, payload FROM events WHERE rig_id = ? AND type IN ('restore.completed', 'restore.subset_completed', 'restore.outcome_reconciled') ORDER BY seq DESC").all(session.rigId);
177
+ for (const row of rows) {
178
+ try {
179
+ if (row.type === "restore.outcome_reconciled") {
180
+ const ev = JSON.parse(row.payload);
181
+ if (ev.nodeId !== session.nodeId)
182
+ continue;
183
+ return ev.to === "operator_recovered" ? null : "attention_required";
184
+ }
185
+ const ev = JSON.parse(row.payload);
186
+ const n = ev.result.nodes.find((nd) => nd.nodeId === session.nodeId);
187
+ if (!n)
188
+ continue;
189
+ // Mirror deriveNodeLifecycleState: attention_required regardless of
190
+ // sessionStatus; failed only when sessionStatus=running.
191
+ if (n.status === "attention_required")
192
+ return "attention_required";
193
+ if (n.status === "failed" && session.sessionStatus === "running")
194
+ return "failed";
195
+ return null;
196
+ }
197
+ catch {
198
+ continue;
199
+ }
200
+ }
201
+ return null;
202
+ }
175
203
  }
176
204
  //# sourceMappingURL=seat-attention-reconciler.js.map