@h-rig/contracts 0.0.6-alpha.176 → 0.0.6-alpha.178

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 (67) hide show
  1. package/dist/index.cjs +132 -63
  2. package/dist/index.mjs +132 -63
  3. package/dist/src/blocker-classifier.d.ts +21 -0
  4. package/dist/src/blocker-classifier.js +13 -0
  5. package/dist/src/cockpit.d.ts +30 -0
  6. package/dist/src/config.d.ts +7 -5
  7. package/dist/src/config.js +3 -1
  8. package/dist/src/control-plane-types.d.ts +2 -2
  9. package/dist/src/github.d.ts +10 -0
  10. package/dist/src/guard.d.ts +7 -0
  11. package/dist/src/guard.js +10 -1
  12. package/dist/src/harness-profile-state.d.ts +10 -0
  13. package/dist/src/harness-profile-state.js +13 -0
  14. package/dist/src/index.d.ts +14 -0
  15. package/dist/src/index.js +132 -63
  16. package/dist/src/layout.d.ts +0 -5
  17. package/dist/src/layout.js +1 -3
  18. package/dist/src/lifecycle-capabilities.d.ts +40 -2
  19. package/dist/src/lifecycle-capabilities.js +12 -0
  20. package/dist/src/managed-repos.d.ts +103 -3
  21. package/dist/src/managed-repos.js +4 -0
  22. package/dist/src/model.d.ts +11 -75
  23. package/dist/src/model.js +3 -58
  24. package/dist/src/placement.d.ts +47 -0
  25. package/dist/src/placement.js +13 -0
  26. package/dist/src/product-entrypoint.d.ts +22 -0
  27. package/dist/src/product-entrypoint.js +13 -0
  28. package/dist/src/provider.d.ts +14 -14
  29. package/dist/src/provider.js +12 -11
  30. package/dist/src/remote-control.d.ts +93 -0
  31. package/dist/src/remote-control.js +26 -0
  32. package/dist/src/run-control.d.ts +164 -0
  33. package/dist/src/run-control.js +13 -0
  34. package/dist/src/run-discovery.d.ts +5 -1
  35. package/dist/src/run-queue.d.ts +36 -0
  36. package/dist/src/run-queue.js +13 -0
  37. package/dist/src/run-read-model.d.ts +33 -88
  38. package/dist/src/run-session-journal.d.ts +86 -1
  39. package/dist/src/run-session-journal.js +9 -0
  40. package/dist/src/runtime-secrets.d.ts +10 -0
  41. package/dist/src/runtime-secrets.js +13 -0
  42. package/dist/src/session-hook-materializer.d.ts +41 -0
  43. package/dist/src/session-hook-materializer.js +13 -0
  44. package/dist/src/setup.d.ts +67 -1
  45. package/dist/src/supervisor-journal.d.ts +9 -9
  46. package/dist/src/supervisor-journal.js +2 -0
  47. package/dist/src/supervisor-loop.d.ts +40 -0
  48. package/dist/src/supervisor-loop.js +13 -0
  49. package/dist/src/task-artifacts.d.ts +20 -0
  50. package/dist/src/task-config.d.ts +22 -0
  51. package/dist/src/task-config.js +1 -0
  52. package/dist/src/task-data.d.ts +6 -8
  53. package/dist/src/task-source.d.ts +58 -27
  54. package/dist/src/task-source.js +9 -1
  55. package/dist/src/task-state-paths.d.ts +14 -0
  56. package/dist/src/task-state-paths.js +13 -0
  57. package/dist/src/task-state-store.d.ts +21 -1
  58. package/dist/src/task-state-store.js +4 -0
  59. package/dist/src/task-tracker-state.d.ts +5 -10
  60. package/dist/src/toolchain-sources.d.ts +1 -1
  61. package/dist/src/transport-config.d.ts +161 -0
  62. package/dist/src/transport-config.js +15 -0
  63. package/dist/src/workflow-journal.d.ts +33 -0
  64. package/dist/src/workflow-journal.js +9 -0
  65. package/dist/src/workspace-service.d.ts +16 -0
  66. package/dist/src/workspace-service.js +13 -0
  67. package/package.json +5 -1
@@ -0,0 +1,93 @@
1
+ import type { CapabilityId } from "./capability-id";
2
+ export type RemoteControlEnv = Readonly<Record<string, string | undefined>>;
3
+ export type RemoteControlJsonRecord = Record<string, unknown>;
4
+ export type RemoteControlMessage = {
5
+ readonly type: string;
6
+ readonly id?: string;
7
+ readonly timestamp?: string;
8
+ } & RemoteControlJsonRecord;
9
+ export type RemoteControlEndpointSelection = {
10
+ readonly projectRoot: string;
11
+ readonly host?: string | undefined;
12
+ readonly port?: string | undefined;
13
+ readonly token?: string | undefined;
14
+ readonly remoteAlias?: string | undefined;
15
+ readonly env?: RemoteControlEnv | undefined;
16
+ };
17
+ export type RemoteControlRemote = {
18
+ readonly source: "flags" | "alias" | "env";
19
+ readonly alias?: string | undefined;
20
+ readonly host: string;
21
+ readonly port: number;
22
+ };
23
+ export type RemoteControlEndpoint = RemoteControlRemote & {
24
+ readonly token: string;
25
+ };
26
+ export type RemoteControlEvent = {
27
+ readonly receivedAt: string;
28
+ readonly message: RemoteControlMessage;
29
+ };
30
+ export type RemoteControlWatchEvent = RemoteControlEvent & {
31
+ readonly summary: string;
32
+ };
33
+ export type RemoteControlOperationResult = {
34
+ readonly remote: RemoteControlRemote;
35
+ readonly response: RemoteControlMessage;
36
+ };
37
+ export type RemoteControlEndpointTestResult = RemoteControlOperationResult & {
38
+ readonly latencyMs: number;
39
+ };
40
+ export type RemoteControlWatchOptions = RemoteControlEndpointSelection & {
41
+ readonly eventType?: string | undefined;
42
+ readonly seconds?: number | undefined;
43
+ readonly maxCaptured?: number | undefined;
44
+ readonly shouldStop?: (() => boolean) | undefined;
45
+ readonly onEvent?: ((event: RemoteControlWatchEvent) => void) | undefined;
46
+ };
47
+ export type RemoteControlWatchResult = {
48
+ readonly remote: RemoteControlRemote;
49
+ readonly received: number;
50
+ readonly dropped: number;
51
+ readonly captured: readonly RemoteControlMessage[];
52
+ readonly event: string | null;
53
+ readonly seconds: number | null;
54
+ };
55
+ export type RemoteControlStartOrchestrationOptions = {
56
+ readonly maxWorkers?: number | undefined;
57
+ readonly maxIterations?: number | undefined;
58
+ readonly directMerge?: boolean | undefined;
59
+ };
60
+ export interface RemoteControlClient {
61
+ readonly remote: RemoteControlRemote;
62
+ readonly ping: () => Promise<RemoteControlMessage>;
63
+ readonly getState: () => Promise<RemoteControlMessage>;
64
+ readonly getTasks: () => Promise<RemoteControlMessage>;
65
+ readonly pause: () => Promise<RemoteControlMessage>;
66
+ readonly resume: () => Promise<RemoteControlMessage>;
67
+ readonly stop: () => Promise<RemoteControlMessage>;
68
+ readonly continueExecution: () => Promise<RemoteControlMessage>;
69
+ readonly refreshTasks: () => Promise<RemoteControlMessage>;
70
+ readonly addIterations: (count: number) => Promise<RemoteControlMessage>;
71
+ readonly removeIterations: (count: number) => Promise<RemoteControlMessage>;
72
+ readonly getPromptPreview: (taskId: string) => Promise<RemoteControlMessage>;
73
+ readonly getIterationOutput: (taskId: string) => Promise<RemoteControlMessage>;
74
+ readonly startOrchestration: (options: RemoteControlStartOrchestrationOptions) => Promise<RemoteControlMessage>;
75
+ readonly pauseOrchestration: (orchestrationId: string) => Promise<RemoteControlMessage>;
76
+ readonly resumeOrchestration: (orchestrationId: string) => Promise<RemoteControlMessage>;
77
+ readonly stopOrchestration: (orchestrationId: string) => Promise<RemoteControlMessage>;
78
+ readonly getOrchestrationState: (orchestrationId: string) => Promise<RemoteControlMessage>;
79
+ }
80
+ export interface RemoteControlService {
81
+ readonly resolveEndpoint: (input: RemoteControlEndpointSelection) => RemoteControlRemote;
82
+ readonly withClient: <T>(input: RemoteControlEndpointSelection, runner: (client: RemoteControlClient) => Promise<T>) => Promise<T>;
83
+ readonly testEndpoint: (input: RemoteControlEndpointSelection) => Promise<RemoteControlEndpointTestResult>;
84
+ readonly watch: (input: RemoteControlWatchOptions) => Promise<RemoteControlWatchResult>;
85
+ }
86
+ export declare class RemoteControlError extends Error {
87
+ readonly code: string;
88
+ readonly exitCode: number;
89
+ readonly details: RemoteControlJsonRecord | undefined;
90
+ constructor(code: string, message: string, exitCode?: number, details?: RemoteControlJsonRecord);
91
+ }
92
+ export declare const REMOTE_CONTROL_CAPABILITY_ID = "rig.remote.control";
93
+ export declare const REMOTE_CONTROL: CapabilityId<RemoteControlService>;
@@ -0,0 +1,26 @@
1
+ // @bun
2
+ // packages/contracts/src/capability-id.ts
3
+ function makeCapabilityId(id) {
4
+ return id;
5
+ }
6
+
7
+ // packages/contracts/src/remote-control.ts
8
+ class RemoteControlError extends Error {
9
+ code;
10
+ exitCode;
11
+ details;
12
+ constructor(code, message, exitCode = 1, details) {
13
+ super(message);
14
+ this.name = "RemoteControlError";
15
+ this.code = code;
16
+ this.exitCode = exitCode;
17
+ this.details = details;
18
+ }
19
+ }
20
+ var REMOTE_CONTROL_CAPABILITY_ID = "rig.remote.control";
21
+ var REMOTE_CONTROL = makeCapabilityId(REMOTE_CONTROL_CAPABILITY_ID);
22
+ export {
23
+ RemoteControlError,
24
+ REMOTE_CONTROL_CAPABILITY_ID,
25
+ REMOTE_CONTROL
26
+ };
@@ -0,0 +1,164 @@
1
+ /**
2
+ * run-control.ts - typed run control capability vocabulary.
3
+ *
4
+ * RUN_READ_MODEL is projection-oriented. Operators that plan launches, deliver
5
+ * control frames, resolve inbox requests, compute resume actions, or remove
6
+ * registry entries use this control seam instead of mutating through read-model
7
+ * consumers.
8
+ */
9
+ import type { CapabilityId } from "./capability-id";
10
+ import type { RunDiscoveryFilter } from "./run-discovery";
11
+ import type { RunRecord } from "./run-record";
12
+ import type { RunInboxResolutionInit } from "./run-session-journal";
13
+ export type RunControl = {
14
+ readonly kind: "steer";
15
+ readonly message: string;
16
+ } | {
17
+ readonly kind: "stop";
18
+ readonly reason: string;
19
+ } | {
20
+ readonly kind: "pause";
21
+ } | {
22
+ readonly kind: "resume";
23
+ };
24
+ export interface RunControlTargetInput {
25
+ readonly projectRoot: string;
26
+ /** Canonical run id/session id. */
27
+ readonly runId: string;
28
+ readonly taskId?: string | null;
29
+ readonly purpose?: "attach" | "steer" | "stop" | "pause" | "resume" | "restart" | "delete" | "prune" | "resolve-inbox";
30
+ readonly discoveryFilter?: RunDiscoveryFilter;
31
+ }
32
+ export interface RunControlTarget {
33
+ /** Canonical run id/session id. */
34
+ readonly runId: string;
35
+ readonly taskId: string | null;
36
+ readonly sessionId: string | null;
37
+ readonly sessionPath: string | null;
38
+ readonly joinLink: string | null;
39
+ readonly webLink: string | null;
40
+ readonly relayUrl: string | null;
41
+ readonly collabCwd: string | null;
42
+ readonly live: boolean;
43
+ readonly stale: boolean;
44
+ readonly canDeliver: boolean;
45
+ readonly reason?: string | null;
46
+ }
47
+ export interface RunControlInput {
48
+ readonly projectRoot: string;
49
+ /** Canonical run id/session id. */
50
+ readonly runId: string;
51
+ readonly control: RunControl;
52
+ readonly requestedBy?: string | null;
53
+ readonly discoveryFilter?: RunDiscoveryFilter;
54
+ }
55
+ export interface RunControlResult {
56
+ readonly runId: string;
57
+ readonly kind: RunControl["kind"];
58
+ readonly status: "delivered" | "not-found" | "not-live" | "unsupported";
59
+ readonly delivered: boolean;
60
+ readonly detail?: string | null;
61
+ }
62
+ export interface RunInboxResolutionInput {
63
+ readonly projectRoot: string;
64
+ /** Canonical run id/session id. */
65
+ readonly runId: string;
66
+ readonly resolution: RunInboxResolutionInit;
67
+ readonly requestedBy?: string | null;
68
+ readonly discoveryFilter?: RunDiscoveryFilter;
69
+ }
70
+ export interface RunInboxResolutionResult {
71
+ readonly runId: string;
72
+ readonly requestId: string;
73
+ readonly kind: "approval" | "input";
74
+ readonly status: "resolved" | "not-found" | "not-live" | "unsupported";
75
+ readonly delivered: boolean;
76
+ readonly detail?: string | null;
77
+ }
78
+ export interface RunResumePlanInput {
79
+ readonly projectRoot: string;
80
+ /** Canonical run id/session id. */
81
+ readonly runId: string;
82
+ readonly discoveryFilter?: RunDiscoveryFilter;
83
+ }
84
+ export interface RunLaunchCandidate {
85
+ readonly taskId: string;
86
+ readonly title?: string | null;
87
+ }
88
+ export interface RunLaunchPlanInput {
89
+ readonly projectRoot: string;
90
+ readonly candidates: readonly RunLaunchCandidate[];
91
+ /** Force means all candidates remain launchable; owners may still annotate results. */
92
+ readonly force?: boolean;
93
+ readonly discoveryFilter?: RunDiscoveryFilter;
94
+ }
95
+ export type RunLaunchPlanEntry = {
96
+ readonly kind: "launch";
97
+ readonly taskId: string;
98
+ readonly title: string | null;
99
+ } | {
100
+ readonly kind: "skipped";
101
+ readonly taskId: string;
102
+ readonly title: string | null;
103
+ readonly reason: string;
104
+ readonly activeRunId?: string | null;
105
+ };
106
+ export interface RunLaunchPlan {
107
+ readonly entries: readonly RunLaunchPlanEntry[];
108
+ readonly launch: readonly Extract<RunLaunchPlanEntry, {
109
+ readonly kind: "launch";
110
+ }>[];
111
+ readonly skipped: readonly Extract<RunLaunchPlanEntry, {
112
+ readonly kind: "skipped";
113
+ }>[];
114
+ readonly force: boolean;
115
+ }
116
+ export type RunResumePlan = {
117
+ readonly kind: "deliver-control";
118
+ readonly runId: string;
119
+ readonly run: RunRecord;
120
+ } | {
121
+ readonly kind: "redispatch-task";
122
+ readonly runId: string;
123
+ readonly taskId: string;
124
+ readonly title: string;
125
+ } | {
126
+ readonly kind: "unavailable";
127
+ readonly runId: string;
128
+ readonly reason: string;
129
+ };
130
+ export interface RunRegistryRemovalInput {
131
+ readonly projectRoot: string;
132
+ /** Canonical run id/session id. */
133
+ readonly runId: string;
134
+ }
135
+ export interface RunRegistryRemovalResult {
136
+ /** Canonical run id/session id. */
137
+ readonly runId: string;
138
+ readonly removed: boolean;
139
+ }
140
+ export interface RunDeadPidReconciliationInput {
141
+ readonly projectRoot: string;
142
+ /** Canonical run id/session id. */
143
+ readonly runId: string;
144
+ readonly sessionPath: string;
145
+ readonly reason?: "lazy-reconcile:dead-pid";
146
+ }
147
+ export interface RunDeadPidReconciliationResult {
148
+ /** Canonical run id/session id. */
149
+ readonly runId: string;
150
+ readonly updated: boolean;
151
+ readonly status: "reconciled" | "not-found" | "unavailable";
152
+ readonly detail?: string | null;
153
+ }
154
+ export interface RunControlService {
155
+ readonly resolveControlTarget: (input: RunControlTargetInput) => Promise<RunControlTarget | null>;
156
+ readonly deliverControl: (input: RunControlInput) => Promise<RunControlResult>;
157
+ readonly resolveInboxRequest: (input: RunInboxResolutionInput) => Promise<RunInboxResolutionResult>;
158
+ readonly planLaunches: (input: RunLaunchPlanInput) => Promise<RunLaunchPlan>;
159
+ readonly resolveResumePlan: (input: RunResumePlanInput) => Promise<RunResumePlan | null>;
160
+ readonly removeRunRegistryEntry: (input: RunRegistryRemovalInput) => Promise<RunRegistryRemovalResult>;
161
+ readonly reconcileDeadPid: (input: RunDeadPidReconciliationInput) => Promise<RunDeadPidReconciliationResult>;
162
+ }
163
+ export declare const RUN_CONTROL_CAPABILITY_ID = "rig.runs.control";
164
+ export declare const RUN_CONTROL: CapabilityId<RunControlService>;
@@ -0,0 +1,13 @@
1
+ // @bun
2
+ // packages/contracts/src/capability-id.ts
3
+ function makeCapabilityId(id) {
4
+ return id;
5
+ }
6
+
7
+ // packages/contracts/src/run-control.ts
8
+ var RUN_CONTROL_CAPABILITY_ID = "rig.runs.control";
9
+ var RUN_CONTROL = makeCapabilityId(RUN_CONTROL_CAPABILITY_ID);
10
+ export {
11
+ RUN_CONTROL_CAPABILITY_ID,
12
+ RUN_CONTROL
13
+ };
@@ -22,6 +22,10 @@ export interface RunDiscoveryFilter {
22
22
  selectedRepo?: string;
23
23
  cwd?: string;
24
24
  }
25
+ export type RunRuntimeActivePredicate = (status: unknown) => boolean;
26
+ export interface RunDiscoveryStaleOptions {
27
+ readonly isRuntimeActiveStatus?: RunRuntimeActivePredicate;
28
+ }
25
29
  /** Structural equivalent of @oh-my-pi LiveCollabOwner. */
26
30
  export interface RunDiscoveryOwner {
27
31
  githubUserId?: string;
@@ -66,7 +70,7 @@ export interface RigRunAttachResult {
66
70
  * need snapshot frames must cast through the transport-plugin's richer type.
67
71
  */
68
72
  export interface RunDiscoveryService {
69
- readonly listActiveRunCollab: (projectRoot: string, filter: RunDiscoveryFilter) => Promise<readonly LiveRunCollabProjection[]>;
73
+ readonly listActiveRunCollab: (projectRoot: string, filter: RunDiscoveryFilter, options?: RunDiscoveryStaleOptions) => Promise<readonly LiveRunCollabProjection[]>;
70
74
  readonly runDiscoveryStream: (projectRoot: string) => Stream.Stream<void>;
71
75
  readonly attachViaRelay: (input: RigRunAttachInput) => Promise<RigRunAttachResult | null>;
72
76
  }
@@ -0,0 +1,36 @@
1
+ /**
2
+ * run-queue.ts — scheduler-owned run queue capability vocabulary.
3
+ *
4
+ * Contracts keeps only the typed id and data shapes. Ranking, packing, and
5
+ * admission behavior lives in @rig/scheduler-plugin and is consumed by
6
+ * supervisor/CLI surfaces through this capability.
7
+ */
8
+ import type { CapabilityId } from "./capability-id";
9
+ import type { TaskDependencyProjection } from "./task-graph-primitives";
10
+ import type { SupervisorSelectionPolicy } from "./supervisor-journal";
11
+ export interface RunQueueRankedTask<T extends TaskDependencyProjection = TaskDependencyProjection> {
12
+ readonly task: T;
13
+ readonly score: number;
14
+ readonly priority: number;
15
+ readonly unblockCount: number;
16
+ readonly scope: readonly string[];
17
+ }
18
+ export interface RunQueuePlanInput<T extends TaskDependencyProjection = TaskDependencyProjection> {
19
+ readonly tasks: readonly T[];
20
+ readonly activeTaskIds?: Iterable<string>;
21
+ readonly excludeTaskIds?: Iterable<string>;
22
+ readonly candidateTaskIds?: Iterable<string>;
23
+ readonly selectionPolicy?: SupervisorSelectionPolicy;
24
+ readonly requireDisjointScopes?: boolean;
25
+ readonly disjointWithScopes?: Iterable<string>;
26
+ readonly limit?: number;
27
+ }
28
+ export interface RunQueuePlan<T extends TaskDependencyProjection = TaskDependencyProjection> {
29
+ readonly plannedOrder: readonly string[];
30
+ readonly ranked: readonly RunQueueRankedTask<T>[];
31
+ }
32
+ export interface RunQueueService {
33
+ readonly planReadyTasks: <T extends TaskDependencyProjection>(input: RunQueuePlanInput<T>) => RunQueuePlan<T>;
34
+ }
35
+ export declare const RUN_QUEUE_CAPABILITY_ID = "rig.scheduler.run-queue";
36
+ export declare const RUN_QUEUE: CapabilityId<RunQueueService>;
@@ -0,0 +1,13 @@
1
+ // @bun
2
+ // packages/contracts/src/capability-id.ts
3
+ function makeCapabilityId(id) {
4
+ return id;
5
+ }
6
+
7
+ // packages/contracts/src/run-queue.ts
8
+ var RUN_QUEUE_CAPABILITY_ID = "rig.scheduler.run-queue";
9
+ var RUN_QUEUE = makeCapabilityId(RUN_QUEUE_CAPABILITY_ID);
10
+ export {
11
+ RUN_QUEUE_CAPABILITY_ID,
12
+ RUN_QUEUE
13
+ };
@@ -12,12 +12,12 @@
12
12
  */
13
13
  import type { CapabilityId } from "./capability-id";
14
14
  import type { RigStatsData } from "./cli-output";
15
- import type { RunDiscoveryFilter } from "./run-discovery";
15
+ import type { RunDiscoveryFilter, RunRuntimeActivePredicate } from "./run-discovery";
16
16
  import type { RunJournalProjection } from "./run-journal";
17
17
  import type { RunRegistryRunProjection } from "./run-registry-backbone";
18
- import type { RigRunTimelineEntry } from "./run-timeline";
19
18
  import type { RunRecord, UnifiedInboxRequest } from "./run-record";
20
- import type { RunInboxResolutionInit, RunSessionCustomEntry } from "./run-session-journal";
19
+ import type { RunStatus } from "./runtime";
20
+ import type { RunSessionCustomEntry } from "./run-session-journal";
21
21
  import type { TaskRecord } from "./task-source";
22
22
  export type RunReadModelSource = RunRecord["source"] | "all";
23
23
  export type RunReadModelRunSelector = {
@@ -33,6 +33,13 @@ export interface RunReadModelListInput {
33
33
  readonly includeInactive?: boolean;
34
34
  readonly discoveryFilter?: RunDiscoveryFilter;
35
35
  }
36
+ export type RunReadModelRepresentativePurpose = "inspect";
37
+ export interface RunReadModelRepresentativeRunInput {
38
+ readonly projectRoot: string;
39
+ readonly taskId: string;
40
+ readonly purpose: RunReadModelRepresentativePurpose;
41
+ readonly discoveryFilter?: RunDiscoveryFilter;
42
+ }
36
43
  export interface RunReadModelGetInput {
37
44
  readonly projectRoot: string;
38
45
  readonly selector: RunReadModelRunSelector;
@@ -45,13 +52,19 @@ export interface RunReadModelProjectionInput {
45
52
  readonly sessionPath?: string | null;
46
53
  readonly discoveryFilter?: RunDiscoveryFilter;
47
54
  }
55
+ export interface RunReadModelSessionProjectionInput {
56
+ /** Canonical run id/session id. */
57
+ readonly runId: string;
58
+ /** Raw run-session custom entries; RUN_READ_MODEL owns the fold into a journal projection. */
59
+ readonly entries: readonly RunSessionCustomEntry[];
60
+ }
48
61
  export interface RunReadModelRegistryProjectionInput {
49
62
  /** Canonical run id/session id. */
50
63
  readonly runId: string;
51
- readonly folded: RunJournalProjection;
52
64
  /** Raw run-session custom entries; providers own timeline extraction from them. */
53
65
  readonly entries: readonly RunSessionCustomEntry[];
54
66
  readonly title: string;
67
+ readonly taskId?: string | null;
55
68
  readonly joinLink?: string | null;
56
69
  readonly webLink?: string | null;
57
70
  readonly relayUrl?: string | null;
@@ -60,8 +73,6 @@ export interface RunReadModelRegistryProjectionInput {
60
73
  readonly collabCwd?: string | null;
61
74
  readonly dispatchHandle?: string | null;
62
75
  readonly timelineLimit?: number;
63
- /** Optional caller-supplied timeline for compatibility; providers should prefer entries. */
64
- readonly timeline?: readonly RigRunTimelineEntry[];
65
76
  }
66
77
  export interface RunReadModelDetailsInput extends RunReadModelGetInput {
67
78
  readonly includeLogs?: boolean;
@@ -88,58 +99,6 @@ export interface RunReadModelInspectRowsInput {
88
99
  readonly pendingInbox?: number | null;
89
100
  readonly discoveryFilter?: RunDiscoveryFilter;
90
101
  }
91
- export interface RunReadModelControlTargetInput {
92
- readonly projectRoot: string;
93
- /** Canonical run id/session id. */
94
- readonly runId: string;
95
- readonly taskId?: string | null;
96
- readonly purpose?: "attach" | "steer" | "stop" | "pause" | "resume" | "resolve-inbox";
97
- readonly discoveryFilter?: RunDiscoveryFilter;
98
- }
99
- export type RunReadModelControl = {
100
- readonly kind: "steer";
101
- readonly message: string;
102
- } | {
103
- readonly kind: "stop";
104
- readonly reason: string;
105
- } | {
106
- readonly kind: "pause";
107
- } | {
108
- readonly kind: "resume";
109
- };
110
- export interface RunReadModelControlInput {
111
- readonly projectRoot: string;
112
- /** Canonical run id/session id. */
113
- readonly runId: string;
114
- readonly control: RunReadModelControl;
115
- readonly requestedBy?: string | null;
116
- readonly discoveryFilter?: RunDiscoveryFilter;
117
- }
118
- export interface RunReadModelControlResult {
119
- readonly runId: string;
120
- readonly kind: RunReadModelControl["kind"];
121
- readonly status: "delivered" | "not-found" | "not-live" | "unsupported";
122
- readonly delivered: boolean;
123
- readonly detail?: string | null;
124
- }
125
- export interface RunReadModelInboxResolutionInput {
126
- readonly projectRoot: string;
127
- /** Canonical run id/session id. */
128
- readonly runId: string;
129
- readonly resolution: RunInboxResolutionInit;
130
- readonly requestedBy?: string | null;
131
- readonly discoveryFilter?: RunDiscoveryFilter;
132
- }
133
- export interface RunReadModelRemoveRegistryEntryInput {
134
- readonly projectRoot: string;
135
- /** Canonical run id/session id. */
136
- readonly runId: string;
137
- }
138
- export interface RunReadModelRemoveRegistryEntryResult {
139
- /** Canonical run id/session id. */
140
- readonly runId: string;
141
- readonly removed: boolean;
142
- }
143
102
  export interface RunReadModelInboxCounts {
144
103
  readonly approvals: number;
145
104
  readonly inputs: number;
@@ -158,34 +117,13 @@ export interface RunReadModelInboxRecord {
158
117
  readonly payload: unknown;
159
118
  readonly source: "run";
160
119
  }
161
- export interface RunReadModelInboxResolutionResult {
162
- readonly runId: string;
163
- readonly requestId: string;
164
- readonly kind: "approval" | "input";
165
- readonly status: "resolved" | "not-found" | "not-live" | "unsupported";
166
- readonly delivered: boolean;
167
- readonly detail?: string | null;
168
- }
169
- export interface RunReadModelControlTarget {
170
- /** Canonical run id/session id. */
171
- readonly runId: string;
172
- readonly taskId: string | null;
173
- readonly sessionId: string | null;
174
- readonly sessionPath: string | null;
175
- readonly joinLink: string | null;
176
- readonly webLink: string | null;
177
- readonly relayUrl: string | null;
178
- readonly collabCwd: string | null;
179
- readonly live: boolean;
180
- readonly stale: boolean;
181
- readonly canDeliver: boolean;
182
- readonly reason?: string | null;
183
- }
184
120
  export type RunReadModelStats = RigStatsData;
185
121
  export type RunReadModelStatusPhase = "starting" | "active" | "waiting" | "paused" | "needs-attention" | "completed" | "failed" | "stopped" | "unknown";
186
122
  export type RunReadModelStatusRole = "success" | "action-yellow" | "active-cyan" | "failure" | "muted" | "neutral";
187
123
  export interface RunReadModelRunClassification {
188
124
  readonly status: string;
125
+ /** RUN_READ_MODEL-owned canonical status for consumers that must emit typed run status events. */
126
+ readonly runStatus: RunStatus;
189
127
  readonly phase: RunReadModelStatusPhase;
190
128
  readonly role: RunReadModelStatusRole;
191
129
  readonly rank: number;
@@ -193,6 +131,13 @@ export interface RunReadModelRunClassification {
193
131
  readonly isTerminal: boolean;
194
132
  readonly isNeedsAttention: boolean;
195
133
  }
134
+ export type RunReadModelStageStatus = "pending" | "running" | "completed" | "needs-attention" | "failed" | "stopped" | "paused" | "waiting-approval" | "waiting-input" | "waiting-user-input";
135
+ export interface RunReadModelStageRow {
136
+ readonly id: string;
137
+ readonly label: string;
138
+ readonly currentValue: RunReadModelStageStatus;
139
+ readonly description?: string;
140
+ }
196
141
  export interface RunReadModelInspectRow {
197
142
  readonly id: string;
198
143
  readonly label: string;
@@ -225,26 +170,26 @@ export interface RunReadModelInspectResult {
225
170
  /**
226
171
  * Multi-method run read-model service capability.
227
172
  *
228
- * Providers own the executable discovery/folding/classification/control-target
229
- * lookup. Consumers depend only on this contracts vocabulary and resolve the
230
- * provider through the typed capability seam.
173
+ * Providers own executable discovery, session folding, classification, inbox
174
+ * read projection, stats, and stage/inspect rows. Consumers depend only on this
175
+ * contracts vocabulary and resolve the provider through the typed capability seam.
231
176
  */
232
177
  export interface RunReadModelService {
233
178
  readonly listRuns: (input: RunReadModelListInput) => Promise<readonly RunRecord[]>;
179
+ readonly getRepresentativeRun: (input: RunReadModelRepresentativeRunInput) => Promise<RunRecord | null>;
234
180
  readonly getRun: (input: RunReadModelGetInput) => Promise<RunRecord | null>;
235
181
  readonly getRunProjection: (input: RunReadModelProjectionInput) => Promise<RunJournalProjection | null>;
182
+ readonly buildSessionProjection: (input: RunReadModelSessionProjectionInput) => RunJournalProjection;
236
183
  readonly buildRegistryProjection: (input: RunReadModelRegistryProjectionInput) => RunRegistryRunProjection;
237
184
  readonly getRunDetails: (input: RunReadModelDetailsInput) => Promise<RunReadModelDetails | null>;
238
185
  readonly inspectRun: (input: RunReadModelDetailsInput) => Promise<RunReadModelInspectResult | null>;
239
186
  readonly listInboxRecords: (input: RunReadModelInboxInput) => Promise<readonly RunReadModelInboxRecord[]>;
240
187
  readonly getInboxCounts: (input: RunReadModelInboxInput) => Promise<RunReadModelInboxCounts>;
241
- readonly resolveInboxRequest: (input: RunReadModelInboxResolutionInput) => Promise<RunReadModelInboxResolutionResult>;
242
188
  readonly getStats: (input: RunReadModelStatsInput) => Promise<RunReadModelStats>;
243
189
  readonly getInspectRows: (input: RunReadModelInspectRowsInput) => Promise<readonly RunReadModelInspectRow[]>;
244
- readonly deliverControl: (input: RunReadModelControlInput) => Promise<RunReadModelControlResult>;
190
+ readonly isRuntimeActiveStatus: RunRuntimeActivePredicate;
245
191
  readonly classifyRun: (run: RunRecord) => RunReadModelRunClassification;
246
- readonly resolveControlTarget: (input: RunReadModelControlTargetInput) => Promise<RunReadModelControlTarget | null>;
247
- readonly removeRunRegistryEntry: (input: RunReadModelRemoveRegistryEntryInput) => Promise<RunReadModelRemoveRegistryEntryResult>;
192
+ readonly projectRunStages: (run: RunRecord) => readonly RunReadModelStageRow[];
248
193
  }
249
194
  /** Stable id string for the run read-model service capability. */
250
195
  export declare const RUN_READ_MODEL_CAPABILITY_ID = "rig.runs.read-model";
@@ -1,4 +1,9 @@
1
- import { type RunJournalEvent } from "./run-journal";
1
+ import type { CapabilityId } from "./capability-id";
2
+ import type { JournalCapability } from "./kernel";
3
+ import { type ApprovalDecision, type RunActor, type RunCloseoutPhase, type RunCloseoutPhaseOutcome, type RunJournalEvent, type RunJournalProjection } from "./run-journal";
4
+ import type { RigRunTimelineEntry } from "./run-timeline";
5
+ import type { RunStatus } from "./runtime";
6
+ import type { RigWorkflowStatusChanged } from "./workflow-journal";
2
7
  type DistributiveOmit<T, K extends PropertyKey> = T extends unknown ? Omit<T, K> : never;
3
8
  export type RunJournalEventInit = DistributiveOmit<RunJournalEvent, "v" | "seq" | "at" | "runId">;
4
9
  export declare const RIG_RUN_STATUS_CHANGED = "rig.run.status-changed";
@@ -66,4 +71,84 @@ export type RunSessionCustomEntry = {
66
71
  customType?: string;
67
72
  data?: unknown;
68
73
  };
74
+ /** Minimal session surface a run-journal writer reads from when binding to an OMP
75
+ * session. The writable append surface is intentionally not part of the
76
+ * read-model codec; the run-worker-owned writer narrows live session managers
77
+ * internally so contracts stays free of any `@oh-my-pi` dependency. */
78
+ export interface RunJournalSessionManager {
79
+ getEntries?(): readonly unknown[];
80
+ getBranch?(): readonly unknown[];
81
+ }
82
+ /** A run journal provider bound to one session + run: the kernel `JournalCapability`
83
+ * plus run-event append and the live projection read. */
84
+ export type JournalSessionProvider = JournalCapability & {
85
+ readonly runId: string;
86
+ readonly appendRunEvent: (event: RunJournalEventInit) => Promise<void>;
87
+ readonly readEntries: () => readonly RunSessionCustomEntry[];
88
+ readonly readProjection: () => RunJournalProjection;
89
+ };
90
+ /** The bound run-journal WRITER handed to the run worker. */
91
+ export type RunJournal = {
92
+ readonly kernel: JournalSessionProvider;
93
+ appendStatus(to: RunStatus, opts?: {
94
+ reason?: string | null;
95
+ actor?: RunActor;
96
+ errorText?: string | null;
97
+ force?: boolean;
98
+ }): void;
99
+ appendTimeline(payload: unknown): void;
100
+ appendCloseoutPhase(input: {
101
+ phase: RunCloseoutPhase;
102
+ outcome: RunCloseoutPhaseOutcome;
103
+ detail?: string | null;
104
+ }): void;
105
+ appendApprovalResolved(input: {
106
+ requestId: string;
107
+ decision: ApprovalDecision;
108
+ note?: string | null;
109
+ actor: RunActor;
110
+ }): void;
111
+ appendInputResolved(input: {
112
+ requestId: string;
113
+ answers: Record<string, string>;
114
+ actor: RunActor;
115
+ }): void;
116
+ appendStall(input: {
117
+ detail: string;
118
+ }): void;
119
+ };
120
+ /**
121
+ * The run-session journal codec: fold/projection (read), timeline extraction, and
122
+ * control-sentinel parse. Owned by `@rig/run-read-model-plugin`, consumed
123
+ * provider-anonymously through `RUN_SESSION_JOURNAL`. Writable journal binding is
124
+ * exposed separately by the run-worker/lifecycle writer capability.
125
+ */
126
+ export interface RunSessionJournalCodec {
127
+ foldRunSessionEntries(entries: readonly RunSessionCustomEntry[], runId: string): RunJournalProjection;
128
+ projectRunFromSession(source: {
129
+ getEntries(): readonly RunSessionCustomEntry[];
130
+ } | readonly RunSessionCustomEntry[], runId: string): RunJournalProjection;
131
+ isTerminalRunStatus(status: RunStatus): boolean;
132
+ sessionIdFromSessionFile(sessionPath: string | null | undefined): string | null;
133
+ timelineEntriesFromCustomEntries(entries: readonly RunSessionCustomEntry[]): readonly RigRunTimelineEntry[];
134
+ latestTimelineEntriesFromCustomEntries(entries: readonly RunSessionCustomEntry[], limit: number): readonly RigRunTimelineEntry[];
135
+ parseStopSentinel(text: string, expectedRunId: string): {
136
+ reason: string | null;
137
+ } | null;
138
+ parsePauseSentinel(text: string, expectedRunId: string): {
139
+ requestedBy: string | null;
140
+ } | null;
141
+ parseResumeSentinel(text: string, expectedRunId: string): {
142
+ requestedBy: string | null;
143
+ } | null;
144
+ parseInboxResolutionSentinel(text: string, expectedRunId: string): RunInboxResolutionSentinel | null;
145
+ createWorkflowStatusChanged(input: Omit<RigWorkflowStatusChanged, "schemaVersion" | "changedAt"> & {
146
+ changedAt?: string;
147
+ }): RigWorkflowStatusChanged;
148
+ }
149
+ export declare const RUN_SESSION_JOURNAL_CAPABILITY_ID = "rig.runs.session-journal";
150
+ /** Branded read-only run session-journal codec capability id. The read-model
151
+ * plugin provides it; run surfaces resolve it instead of importing the codec
152
+ * implementation. */
153
+ export declare const RUN_SESSION_JOURNAL: CapabilityId<RunSessionJournalCodec>;
69
154
  export {};