@cat-factory/contracts 0.232.0 → 0.234.0
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.
- package/dist/debug-api.d.ts.map +1 -1
- package/dist/debug-api.js +2 -1
- package/dist/debug-api.js.map +1 -1
- package/dist/entities.d.ts +2 -1
- package/dist/entities.d.ts.map +1 -1
- package/dist/entities.js +2 -1
- package/dist/entities.js.map +1 -1
- package/dist/execution.d.ts +10 -111
- package/dist/execution.d.ts.map +1 -1
- package/dist/execution.js +10 -89
- package/dist/execution.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/notification-webhooks.d.ts +61 -4
- package/dist/notification-webhooks.d.ts.map +1 -1
- package/dist/notification-webhooks.js +35 -4
- package/dist/notification-webhooks.js.map +1 -1
- package/dist/requests.js +1 -1
- package/dist/requests.js.map +1 -1
- package/dist/routes/agent-runs.d.ts +2 -2
- package/dist/routes/bug-hunt.d.ts +2 -2
- package/dist/routes/execution.d.ts +8 -8
- package/dist/routes/human-review.d.ts +1 -1
- package/dist/routes/human-test.d.ts +5 -5
- package/dist/routes/notification-webhooks.d.ts +129 -1
- package/dist/routes/notification-webhooks.d.ts.map +1 -1
- package/dist/routes/notification-webhooks.js +49 -6
- package/dist/routes/notification-webhooks.js.map +1 -1
- package/dist/routes/visual-confirm.d.ts +3 -3
- package/dist/routes/workspaces.d.ts +2 -2
- package/dist/run-provenance.d.ts +107 -0
- package/dist/run-provenance.d.ts.map +1 -0
- package/dist/run-provenance.js +140 -0
- package/dist/run-provenance.js.map +1 -0
- package/dist/snapshot.d.ts +1 -1
- package/dist/tracker.d.ts +4 -3
- package/dist/tracker.d.ts.map +1 -1
- package/dist/tracker.js +4 -3
- package/dist/tracker.js.map +1 -1
- package/package.json +1 -1
|
@@ -43,7 +43,7 @@ export declare const putNotificationWebhookContract: {
|
|
|
43
43
|
readonly method: "put";
|
|
44
44
|
readonly pathResolver: () => string;
|
|
45
45
|
readonly requestBodySchema: v.ObjectSchema<{
|
|
46
|
-
readonly url: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.TrimAction, v.UrlAction<string, undefined>, v.StartsWithAction<string, "https://", "The webhook endpoint must be an https:// URL">, v.MaxLengthAction<string, 2000, undefined>]>;
|
|
46
|
+
readonly url: v.OptionalSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.TrimAction, v.UrlAction<string, undefined>, v.StartsWithAction<string, "https://", "The webhook endpoint must be an https:// URL">, v.MaxLengthAction<string, 2000, undefined>]>, undefined>;
|
|
47
47
|
readonly types: v.OptionalSchema<v.ArraySchema<v.PicklistSchema<["merge_review", "pipeline_complete", "ci_failed", "test_failed", "requirement_review", "clarity_review", "release_regression", "decision_required", "human_test_ready", "visual_confirmation_ready", "human_review", "followup_pending", "fork_decision_pending", "judge_review", "pr_review_ready", "initiative", "platform_health", "infra_unreachable", "budget_paused", "key_drift", "merge_tag_request"], undefined>, undefined>, undefined>;
|
|
48
48
|
readonly runEvents: v.OptionalSchema<v.ArraySchema<v.PicklistSchema<["run.started", "run.completed", "run.failed"], undefined>, undefined>, undefined>;
|
|
49
49
|
readonly alertEvents: v.OptionalSchema<v.ArraySchema<v.PicklistSchema<["platform_health.firing", "platform_health.resolved"], undefined>, undefined>, undefined>;
|
|
@@ -114,4 +114,132 @@ export declare const deleteNotificationWebhookContract: {
|
|
|
114
114
|
readonly 204: typeof ContractNoBody;
|
|
115
115
|
};
|
|
116
116
|
};
|
|
117
|
+
/**
|
|
118
|
+
* Read the workspace's registered endpoint. `{ webhook: null }` when none is registered: a real
|
|
119
|
+
* answer rather than a 404, so a caller's startup self-check ("am I already wired up?") reads one
|
|
120
|
+
* response shape instead of branching on a status the surface also uses for a bad path.
|
|
121
|
+
*/
|
|
122
|
+
export declare const getPublicNotificationWebhookContract: {
|
|
123
|
+
readonly method: "get";
|
|
124
|
+
readonly pathResolver: () => string;
|
|
125
|
+
readonly responsesByStatusCode: {
|
|
126
|
+
readonly '4xx': v.ObjectSchema<{
|
|
127
|
+
readonly error: v.ObjectSchema<{
|
|
128
|
+
readonly code: v.StringSchema<undefined>;
|
|
129
|
+
readonly message: v.StringSchema<undefined>;
|
|
130
|
+
readonly details: v.OptionalSchema<v.UnknownSchema, undefined>;
|
|
131
|
+
readonly issues: v.OptionalSchema<v.ArraySchema<v.ObjectSchema<{
|
|
132
|
+
readonly path: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
|
|
133
|
+
readonly message: v.StringSchema<undefined>;
|
|
134
|
+
}, undefined>, undefined>, undefined>;
|
|
135
|
+
}, undefined>;
|
|
136
|
+
}, undefined>;
|
|
137
|
+
readonly '5xx': v.ObjectSchema<{
|
|
138
|
+
readonly error: v.ObjectSchema<{
|
|
139
|
+
readonly code: v.StringSchema<undefined>;
|
|
140
|
+
readonly message: v.StringSchema<undefined>;
|
|
141
|
+
readonly details: v.OptionalSchema<v.UnknownSchema, undefined>;
|
|
142
|
+
readonly issues: v.OptionalSchema<v.ArraySchema<v.ObjectSchema<{
|
|
143
|
+
readonly path: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
|
|
144
|
+
readonly message: v.StringSchema<undefined>;
|
|
145
|
+
}, undefined>, undefined>, undefined>;
|
|
146
|
+
}, undefined>;
|
|
147
|
+
}, undefined>;
|
|
148
|
+
readonly 200: v.ObjectSchema<{
|
|
149
|
+
readonly webhook: v.NullableSchema<v.ObjectSchema<{
|
|
150
|
+
readonly url: v.StringSchema<undefined>;
|
|
151
|
+
readonly types: v.ArraySchema<v.PicklistSchema<["merge_review", "pipeline_complete", "ci_failed", "test_failed", "requirement_review", "clarity_review", "release_regression", "decision_required", "human_test_ready", "visual_confirmation_ready", "human_review", "followup_pending", "fork_decision_pending", "judge_review", "pr_review_ready", "initiative", "platform_health", "infra_unreachable", "budget_paused", "key_drift", "merge_tag_request"], undefined>, undefined>;
|
|
152
|
+
readonly runEvents: v.ArraySchema<v.PicklistSchema<["run.started", "run.completed", "run.failed"], undefined>, undefined>;
|
|
153
|
+
readonly alertEvents: v.ArraySchema<v.PicklistSchema<["platform_health.firing", "platform_health.resolved"], undefined>, undefined>;
|
|
154
|
+
readonly enabled: v.BooleanSchema<undefined>;
|
|
155
|
+
readonly hasSecret: v.BooleanSchema<undefined>;
|
|
156
|
+
readonly updatedAt: v.NumberSchema<undefined>;
|
|
157
|
+
}, undefined>, undefined>;
|
|
158
|
+
}, undefined>;
|
|
159
|
+
};
|
|
160
|
+
};
|
|
161
|
+
/**
|
|
162
|
+
* Register or update the endpoint. Returns the stored projection directly (not the `webhook`
|
|
163
|
+
* wrapper the read uses): a successful write always has an endpoint to describe, so wrapping it
|
|
164
|
+
* would hand every client a null to check that cannot occur.
|
|
165
|
+
*
|
|
166
|
+
* `secret` is write-only on this surface exactly as it is on the session one: supplied here,
|
|
167
|
+
* never returned by the read. An `admin` key can therefore ROTATE the signing secret but can
|
|
168
|
+
* never exfiltrate the one already stored.
|
|
169
|
+
*/
|
|
170
|
+
export declare const putPublicNotificationWebhookContract: {
|
|
171
|
+
readonly method: "put";
|
|
172
|
+
readonly pathResolver: () => string;
|
|
173
|
+
readonly requestBodySchema: v.ObjectSchema<{
|
|
174
|
+
readonly url: v.OptionalSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.TrimAction, v.UrlAction<string, undefined>, v.StartsWithAction<string, "https://", "The webhook endpoint must be an https:// URL">, v.MaxLengthAction<string, 2000, undefined>]>, undefined>;
|
|
175
|
+
readonly types: v.OptionalSchema<v.ArraySchema<v.PicklistSchema<["merge_review", "pipeline_complete", "ci_failed", "test_failed", "requirement_review", "clarity_review", "release_regression", "decision_required", "human_test_ready", "visual_confirmation_ready", "human_review", "followup_pending", "fork_decision_pending", "judge_review", "pr_review_ready", "initiative", "platform_health", "infra_unreachable", "budget_paused", "key_drift", "merge_tag_request"], undefined>, undefined>, undefined>;
|
|
176
|
+
readonly runEvents: v.OptionalSchema<v.ArraySchema<v.PicklistSchema<["run.started", "run.completed", "run.failed"], undefined>, undefined>, undefined>;
|
|
177
|
+
readonly alertEvents: v.OptionalSchema<v.ArraySchema<v.PicklistSchema<["platform_health.firing", "platform_health.resolved"], undefined>, undefined>, undefined>;
|
|
178
|
+
readonly enabled: v.OptionalSchema<v.BooleanSchema<undefined>, undefined>;
|
|
179
|
+
readonly secret: v.OptionalSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.TrimAction, v.MinLengthAction<string, 16, undefined>, v.MaxLengthAction<string, 200, undefined>]>, undefined>;
|
|
180
|
+
}, undefined>;
|
|
181
|
+
readonly responsesByStatusCode: {
|
|
182
|
+
readonly '4xx': v.ObjectSchema<{
|
|
183
|
+
readonly error: v.ObjectSchema<{
|
|
184
|
+
readonly code: v.StringSchema<undefined>;
|
|
185
|
+
readonly message: v.StringSchema<undefined>;
|
|
186
|
+
readonly details: v.OptionalSchema<v.UnknownSchema, undefined>;
|
|
187
|
+
readonly issues: v.OptionalSchema<v.ArraySchema<v.ObjectSchema<{
|
|
188
|
+
readonly path: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
|
|
189
|
+
readonly message: v.StringSchema<undefined>;
|
|
190
|
+
}, undefined>, undefined>, undefined>;
|
|
191
|
+
}, undefined>;
|
|
192
|
+
}, undefined>;
|
|
193
|
+
readonly '5xx': v.ObjectSchema<{
|
|
194
|
+
readonly error: v.ObjectSchema<{
|
|
195
|
+
readonly code: v.StringSchema<undefined>;
|
|
196
|
+
readonly message: v.StringSchema<undefined>;
|
|
197
|
+
readonly details: v.OptionalSchema<v.UnknownSchema, undefined>;
|
|
198
|
+
readonly issues: v.OptionalSchema<v.ArraySchema<v.ObjectSchema<{
|
|
199
|
+
readonly path: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
|
|
200
|
+
readonly message: v.StringSchema<undefined>;
|
|
201
|
+
}, undefined>, undefined>, undefined>;
|
|
202
|
+
}, undefined>;
|
|
203
|
+
}, undefined>;
|
|
204
|
+
readonly 200: v.ObjectSchema<{
|
|
205
|
+
readonly url: v.StringSchema<undefined>;
|
|
206
|
+
readonly types: v.ArraySchema<v.PicklistSchema<["merge_review", "pipeline_complete", "ci_failed", "test_failed", "requirement_review", "clarity_review", "release_regression", "decision_required", "human_test_ready", "visual_confirmation_ready", "human_review", "followup_pending", "fork_decision_pending", "judge_review", "pr_review_ready", "initiative", "platform_health", "infra_unreachable", "budget_paused", "key_drift", "merge_tag_request"], undefined>, undefined>;
|
|
207
|
+
readonly runEvents: v.ArraySchema<v.PicklistSchema<["run.started", "run.completed", "run.failed"], undefined>, undefined>;
|
|
208
|
+
readonly alertEvents: v.ArraySchema<v.PicklistSchema<["platform_health.firing", "platform_health.resolved"], undefined>, undefined>;
|
|
209
|
+
readonly enabled: v.BooleanSchema<undefined>;
|
|
210
|
+
readonly hasSecret: v.BooleanSchema<undefined>;
|
|
211
|
+
readonly updatedAt: v.NumberSchema<undefined>;
|
|
212
|
+
}, undefined>;
|
|
213
|
+
};
|
|
214
|
+
};
|
|
215
|
+
/** Remove the endpoint (deliveries stop). Idempotent: 204 whether or not one was registered. */
|
|
216
|
+
export declare const deletePublicNotificationWebhookContract: {
|
|
217
|
+
readonly method: "delete";
|
|
218
|
+
readonly pathResolver: () => string;
|
|
219
|
+
readonly responsesByStatusCode: {
|
|
220
|
+
readonly '4xx': v.ObjectSchema<{
|
|
221
|
+
readonly error: v.ObjectSchema<{
|
|
222
|
+
readonly code: v.StringSchema<undefined>;
|
|
223
|
+
readonly message: v.StringSchema<undefined>;
|
|
224
|
+
readonly details: v.OptionalSchema<v.UnknownSchema, undefined>;
|
|
225
|
+
readonly issues: v.OptionalSchema<v.ArraySchema<v.ObjectSchema<{
|
|
226
|
+
readonly path: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
|
|
227
|
+
readonly message: v.StringSchema<undefined>;
|
|
228
|
+
}, undefined>, undefined>, undefined>;
|
|
229
|
+
}, undefined>;
|
|
230
|
+
}, undefined>;
|
|
231
|
+
readonly '5xx': v.ObjectSchema<{
|
|
232
|
+
readonly error: v.ObjectSchema<{
|
|
233
|
+
readonly code: v.StringSchema<undefined>;
|
|
234
|
+
readonly message: v.StringSchema<undefined>;
|
|
235
|
+
readonly details: v.OptionalSchema<v.UnknownSchema, undefined>;
|
|
236
|
+
readonly issues: v.OptionalSchema<v.ArraySchema<v.ObjectSchema<{
|
|
237
|
+
readonly path: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
|
|
238
|
+
readonly message: v.StringSchema<undefined>;
|
|
239
|
+
}, undefined>, undefined>, undefined>;
|
|
240
|
+
}, undefined>;
|
|
241
|
+
}, undefined>;
|
|
242
|
+
readonly 204: typeof ContractNoBody;
|
|
243
|
+
};
|
|
244
|
+
};
|
|
117
245
|
//# sourceMappingURL=notification-webhooks.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"notification-webhooks.d.ts","sourceRoot":"","sources":["../../src/routes/notification-webhooks.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAqB,MAAM,yBAAyB,CAAA;AAC3E,OAAO,KAAK,CAAC,MAAM,SAAS,CAAA;
|
|
1
|
+
{"version":3,"file":"notification-webhooks.d.ts","sourceRoot":"","sources":["../../src/routes/notification-webhooks.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAqB,MAAM,yBAAyB,CAAA;AAC3E,OAAO,KAAK,CAAC,MAAM,SAAS,CAAA;AA0B5B,8FAA8F;AAC9F,eAAO,MAAM,8BAA8B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAOzC,CAAA;AAEF,yFAAyF;AACzF,eAAO,MAAM,8BAA8B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAKzC,CAAA;AAEF,wDAAwD;AACxD,eAAO,MAAM,iCAAiC;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAI5C,CAAA;AAIF;;;;GAIG;AACH,eAAO,MAAM,oCAAoC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAI/C,CAAA;AAEF;;;;;;;;GAQG;AACH,eAAO,MAAM,oCAAoC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAK/C,CAAA;AAEF,gGAAgG;AAChG,eAAO,MAAM,uCAAuC;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAIlD,CAAA"}
|
|
@@ -1,13 +1,24 @@
|
|
|
1
1
|
import { ContractNoBody, defineApiContract } from '@toad-contracts/valibot';
|
|
2
2
|
import * as v from 'valibot';
|
|
3
|
-
import { notificationWebhookSchema, putNotificationWebhookSchema, } from '../notification-webhooks.js';
|
|
3
|
+
import { notificationWebhookSchema, publicNotificationWebhookSchema, putNotificationWebhookSchema, } from '../notification-webhooks.js';
|
|
4
4
|
import { errorResponses } from './_shared.js';
|
|
5
|
-
// Management routes for a workspace's OUTBOUND notification webhook
|
|
6
|
-
// under `/workspaces/:workspaceId` (so paths are relative), like the tracker/Slack settings. The
|
|
7
|
-
// endpoint they configure is consumed by `WebhookNotificationChannel`, not by these routes.
|
|
5
|
+
// Management routes for a workspace's OUTBOUND notification webhook, on TWO surfaces:
|
|
8
6
|
//
|
|
9
|
-
//
|
|
10
|
-
//
|
|
7
|
+
// 1. Session-authed, mounted under `/workspaces/:workspaceId` (so paths are relative), like the
|
|
8
|
+
// tracker/Slack settings. These are writes to an integration's configuration, so they sit
|
|
9
|
+
// behind the `integrations.manage` workspace permission like every other admin controller.
|
|
10
|
+
// 2. `/api/v1/notification-webhook`, on absolute paths, authenticated in-controller by an
|
|
11
|
+
// `admin`-scope public-API key. Same three verbs against the same service.
|
|
12
|
+
//
|
|
13
|
+
// The endpoint they configure is consumed by `WebhookNotificationChannel` and the run-lifecycle /
|
|
14
|
+
// platform-alert sinks beside it, not by these routes.
|
|
15
|
+
//
|
|
16
|
+
// The second surface exists because the FIRST one made the push channel unreachable to exactly
|
|
17
|
+
// the caller it was built for. A deployment whose operator is headless has no browser session, so
|
|
18
|
+
// the receiver that run-lifecycle push exists to feed could only be registered by a human clicking
|
|
19
|
+
// through an app the feature deliberately does not need. Both surfaces are thin delegates over
|
|
20
|
+
// `NotificationWebhookService` (same URL guard, same write-only secret, same
|
|
21
|
+
// one-row-per-workspace rule), so neither can admit an endpoint the other would reject.
|
|
11
22
|
/** The workspace's registered webhook, or null when none is set. Never returns the secret. */
|
|
12
23
|
export const getNotificationWebhookContract = defineApiContract({
|
|
13
24
|
method: 'get',
|
|
@@ -30,4 +41,36 @@ export const deleteNotificationWebhookContract = defineApiContract({
|
|
|
30
41
|
pathResolver: () => '/notification-webhook',
|
|
31
42
|
responsesByStatusCode: { 204: ContractNoBody, ...errorResponses },
|
|
32
43
|
});
|
|
44
|
+
// ---- the external `/api/v1` surface (absolute paths, key-authenticated) ----
|
|
45
|
+
/**
|
|
46
|
+
* Read the workspace's registered endpoint. `{ webhook: null }` when none is registered: a real
|
|
47
|
+
* answer rather than a 404, so a caller's startup self-check ("am I already wired up?") reads one
|
|
48
|
+
* response shape instead of branching on a status the surface also uses for a bad path.
|
|
49
|
+
*/
|
|
50
|
+
export const getPublicNotificationWebhookContract = defineApiContract({
|
|
51
|
+
method: 'get',
|
|
52
|
+
pathResolver: () => '/api/v1/notification-webhook',
|
|
53
|
+
responsesByStatusCode: { 200: publicNotificationWebhookSchema, ...errorResponses },
|
|
54
|
+
});
|
|
55
|
+
/**
|
|
56
|
+
* Register or update the endpoint. Returns the stored projection directly (not the `webhook`
|
|
57
|
+
* wrapper the read uses): a successful write always has an endpoint to describe, so wrapping it
|
|
58
|
+
* would hand every client a null to check that cannot occur.
|
|
59
|
+
*
|
|
60
|
+
* `secret` is write-only on this surface exactly as it is on the session one: supplied here,
|
|
61
|
+
* never returned by the read. An `admin` key can therefore ROTATE the signing secret but can
|
|
62
|
+
* never exfiltrate the one already stored.
|
|
63
|
+
*/
|
|
64
|
+
export const putPublicNotificationWebhookContract = defineApiContract({
|
|
65
|
+
method: 'put',
|
|
66
|
+
pathResolver: () => '/api/v1/notification-webhook',
|
|
67
|
+
requestBodySchema: putNotificationWebhookSchema,
|
|
68
|
+
responsesByStatusCode: { 200: notificationWebhookSchema, ...errorResponses },
|
|
69
|
+
});
|
|
70
|
+
/** Remove the endpoint (deliveries stop). Idempotent: 204 whether or not one was registered. */
|
|
71
|
+
export const deletePublicNotificationWebhookContract = defineApiContract({
|
|
72
|
+
method: 'delete',
|
|
73
|
+
pathResolver: () => '/api/v1/notification-webhook',
|
|
74
|
+
responsesByStatusCode: { 204: ContractNoBody, ...errorResponses },
|
|
75
|
+
});
|
|
33
76
|
//# sourceMappingURL=notification-webhooks.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"notification-webhooks.js","sourceRoot":"","sources":["../../src/routes/notification-webhooks.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAA;AAC3E,OAAO,KAAK,CAAC,MAAM,SAAS,CAAA;AAC5B,OAAO,EACL,yBAAyB,EACzB,4BAA4B,GAC7B,MAAM,6BAA6B,CAAA;AACpC,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAA;AAE7C,
|
|
1
|
+
{"version":3,"file":"notification-webhooks.js","sourceRoot":"","sources":["../../src/routes/notification-webhooks.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAA;AAC3E,OAAO,KAAK,CAAC,MAAM,SAAS,CAAA;AAC5B,OAAO,EACL,yBAAyB,EACzB,+BAA+B,EAC/B,4BAA4B,GAC7B,MAAM,6BAA6B,CAAA;AACpC,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAA;AAE7C,sFAAsF;AACtF,EAAE;AACF,iGAAiG;AACjG,8FAA8F;AAC9F,+FAA+F;AAC/F,2FAA2F;AAC3F,+EAA+E;AAC/E,EAAE;AACF,kGAAkG;AAClG,uDAAuD;AACvD,EAAE;AACF,+FAA+F;AAC/F,kGAAkG;AAClG,mGAAmG;AACnG,+FAA+F;AAC/F,6EAA6E;AAC7E,wFAAwF;AAExF,8FAA8F;AAC9F,MAAM,CAAC,MAAM,8BAA8B,GAAG,iBAAiB,CAAC;IAC9D,MAAM,EAAE,KAAK;IACb,YAAY,EAAE,GAAG,EAAE,CAAC,uBAAuB;IAC3C,qBAAqB,EAAE;QACrB,GAAG,EAAE,CAAC,CAAC,QAAQ,CAAC,yBAAyB,CAAC;QAC1C,GAAG,cAAc;KAClB;CACF,CAAC,CAAA;AAEF,yFAAyF;AACzF,MAAM,CAAC,MAAM,8BAA8B,GAAG,iBAAiB,CAAC;IAC9D,MAAM,EAAE,KAAK;IACb,YAAY,EAAE,GAAG,EAAE,CAAC,uBAAuB;IAC3C,iBAAiB,EAAE,4BAA4B;IAC/C,qBAAqB,EAAE,EAAE,GAAG,EAAE,yBAAyB,EAAE,GAAG,cAAc,EAAE;CAC7E,CAAC,CAAA;AAEF,wDAAwD;AACxD,MAAM,CAAC,MAAM,iCAAiC,GAAG,iBAAiB,CAAC;IACjE,MAAM,EAAE,QAAQ;IAChB,YAAY,EAAE,GAAG,EAAE,CAAC,uBAAuB;IAC3C,qBAAqB,EAAE,EAAE,GAAG,EAAE,cAAc,EAAE,GAAG,cAAc,EAAE;CAClE,CAAC,CAAA;AAEF,+EAA+E;AAE/E;;;;GAIG;AACH,MAAM,CAAC,MAAM,oCAAoC,GAAG,iBAAiB,CAAC;IACpE,MAAM,EAAE,KAAK;IACb,YAAY,EAAE,GAAG,EAAE,CAAC,8BAA8B;IAClD,qBAAqB,EAAE,EAAE,GAAG,EAAE,+BAA+B,EAAE,GAAG,cAAc,EAAE;CACnF,CAAC,CAAA;AAEF;;;;;;;;GAQG;AACH,MAAM,CAAC,MAAM,oCAAoC,GAAG,iBAAiB,CAAC;IACpE,MAAM,EAAE,KAAK;IACb,YAAY,EAAE,GAAG,EAAE,CAAC,8BAA8B;IAClD,iBAAiB,EAAE,4BAA4B;IAC/C,qBAAqB,EAAE,EAAE,GAAG,EAAE,yBAAyB,EAAE,GAAG,cAAc,EAAE;CAC7E,CAAC,CAAA;AAEF,gGAAgG;AAChG,MAAM,CAAC,MAAM,uCAAuC,GAAG,iBAAiB,CAAC;IACvE,MAAM,EAAE,QAAQ;IAChB,YAAY,EAAE,GAAG,EAAE,CAAC,8BAA8B;IAClD,qBAAqB,EAAE,EAAE,GAAG,EAAE,cAAc,EAAE,GAAG,cAAc,EAAE;CAClE,CAAC,CAAA"}
|
|
@@ -1015,7 +1015,7 @@ export declare const approveVisualConfirmContract: {
|
|
|
1015
1015
|
readonly initiatedBy: v.OptionalSchema<v.NullableSchema<v.StringSchema<undefined>, undefined>, undefined>;
|
|
1016
1016
|
readonly initiatedByRole: v.OptionalSchema<v.NullableSchema<v.PicklistSchema<readonly ["admin", "member", "viewer"], undefined>, undefined>, undefined>;
|
|
1017
1017
|
readonly mode: v.OptionalSchema<v.PicklistSchema<["live", "dry_run"], undefined>, undefined>;
|
|
1018
|
-
readonly intakeOrigin: v.OptionalSchema<v.PicklistSchema<["ui", "public-api"], undefined>, undefined>;
|
|
1018
|
+
readonly intakeOrigin: v.OptionalSchema<v.PicklistSchema<["ui", "public-api", "tracker", "schedule"], undefined>, undefined>;
|
|
1019
1019
|
readonly createdAt: v.OptionalSchema<v.NumberSchema<undefined>, undefined>;
|
|
1020
1020
|
readonly rev: v.OptionalSchema<v.NumberSchema<undefined>, undefined>;
|
|
1021
1021
|
readonly diagnostics: v.OptionalSchema<v.ObjectSchema<{
|
|
@@ -2067,7 +2067,7 @@ export declare const requestVisualConfirmFixContract: {
|
|
|
2067
2067
|
readonly initiatedBy: v.OptionalSchema<v.NullableSchema<v.StringSchema<undefined>, undefined>, undefined>;
|
|
2068
2068
|
readonly initiatedByRole: v.OptionalSchema<v.NullableSchema<v.PicklistSchema<readonly ["admin", "member", "viewer"], undefined>, undefined>, undefined>;
|
|
2069
2069
|
readonly mode: v.OptionalSchema<v.PicklistSchema<["live", "dry_run"], undefined>, undefined>;
|
|
2070
|
-
readonly intakeOrigin: v.OptionalSchema<v.PicklistSchema<["ui", "public-api"], undefined>, undefined>;
|
|
2070
|
+
readonly intakeOrigin: v.OptionalSchema<v.PicklistSchema<["ui", "public-api", "tracker", "schedule"], undefined>, undefined>;
|
|
2071
2071
|
readonly createdAt: v.OptionalSchema<v.NumberSchema<undefined>, undefined>;
|
|
2072
2072
|
readonly rev: v.OptionalSchema<v.NumberSchema<undefined>, undefined>;
|
|
2073
2073
|
readonly diagnostics: v.OptionalSchema<v.ObjectSchema<{
|
|
@@ -3117,7 +3117,7 @@ export declare const recaptureVisualConfirmContract: {
|
|
|
3117
3117
|
readonly initiatedBy: v.OptionalSchema<v.NullableSchema<v.StringSchema<undefined>, undefined>, undefined>;
|
|
3118
3118
|
readonly initiatedByRole: v.OptionalSchema<v.NullableSchema<v.PicklistSchema<readonly ["admin", "member", "viewer"], undefined>, undefined>, undefined>;
|
|
3119
3119
|
readonly mode: v.OptionalSchema<v.PicklistSchema<["live", "dry_run"], undefined>, undefined>;
|
|
3120
|
-
readonly intakeOrigin: v.OptionalSchema<v.PicklistSchema<["ui", "public-api"], undefined>, undefined>;
|
|
3120
|
+
readonly intakeOrigin: v.OptionalSchema<v.PicklistSchema<["ui", "public-api", "tracker", "schedule"], undefined>, undefined>;
|
|
3121
3121
|
readonly createdAt: v.OptionalSchema<v.NumberSchema<undefined>, undefined>;
|
|
3122
3122
|
readonly rev: v.OptionalSchema<v.NumberSchema<undefined>, undefined>;
|
|
3123
3123
|
readonly diagnostics: v.OptionalSchema<v.ObjectSchema<{
|
|
@@ -1518,7 +1518,7 @@ export declare const createWorkspaceContract: {
|
|
|
1518
1518
|
readonly initiatedBy: v.OptionalSchema<v.NullableSchema<v.StringSchema<undefined>, undefined>, undefined>;
|
|
1519
1519
|
readonly initiatedByRole: v.OptionalSchema<v.NullableSchema<v.PicklistSchema<readonly ["admin", "member", "viewer"], undefined>, undefined>, undefined>;
|
|
1520
1520
|
readonly mode: v.OptionalSchema<v.PicklistSchema<["live", "dry_run"], undefined>, undefined>;
|
|
1521
|
-
readonly intakeOrigin: v.OptionalSchema<v.PicklistSchema<["ui", "public-api"], undefined>, undefined>;
|
|
1521
|
+
readonly intakeOrigin: v.OptionalSchema<v.PicklistSchema<["ui", "public-api", "tracker", "schedule"], undefined>, undefined>;
|
|
1522
1522
|
readonly createdAt: v.OptionalSchema<v.NumberSchema<undefined>, undefined>;
|
|
1523
1523
|
readonly rev: v.OptionalSchema<v.NumberSchema<undefined>, undefined>;
|
|
1524
1524
|
readonly diagnostics: v.OptionalSchema<v.ObjectSchema<{
|
|
@@ -4786,7 +4786,7 @@ export declare const getWorkspaceContract: {
|
|
|
4786
4786
|
readonly initiatedBy: v.OptionalSchema<v.NullableSchema<v.StringSchema<undefined>, undefined>, undefined>;
|
|
4787
4787
|
readonly initiatedByRole: v.OptionalSchema<v.NullableSchema<v.PicklistSchema<readonly ["admin", "member", "viewer"], undefined>, undefined>, undefined>;
|
|
4788
4788
|
readonly mode: v.OptionalSchema<v.PicklistSchema<["live", "dry_run"], undefined>, undefined>;
|
|
4789
|
-
readonly intakeOrigin: v.OptionalSchema<v.PicklistSchema<["ui", "public-api"], undefined>, undefined>;
|
|
4789
|
+
readonly intakeOrigin: v.OptionalSchema<v.PicklistSchema<["ui", "public-api", "tracker", "schedule"], undefined>, undefined>;
|
|
4790
4790
|
readonly createdAt: v.OptionalSchema<v.NumberSchema<undefined>, undefined>;
|
|
4791
4791
|
readonly rev: v.OptionalSchema<v.NumberSchema<undefined>, undefined>;
|
|
4792
4792
|
readonly diagnostics: v.OptionalSchema<v.ObjectSchema<{
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import * as v from 'valibot';
|
|
2
|
+
/**
|
|
3
|
+
* How a run entered the system. See `ExecutionInstance.intakeOrigin`.
|
|
4
|
+
*
|
|
5
|
+
* - `ui`: someone started it in the app, on their own board. The read-time default, and what
|
|
6
|
+
* every legacy run is.
|
|
7
|
+
* - `public-api`: started headlessly through the `/api/v1` surface.
|
|
8
|
+
* - `tracker`: dispatched from a pushed ticket by a per-ticket issue-intake schedule.
|
|
9
|
+
* - `schedule`: a recurring schedule fired it, either on its cadence or because a tracker push
|
|
10
|
+
* drained its queue early. Both are the same run against the same reused block (ADR 0032), so
|
|
11
|
+
* they deliberately share one origin; what differs is only what made the tick happen.
|
|
12
|
+
*
|
|
13
|
+
* `ui` is the DEFAULT, which makes it a positive claim that a human is watching in the app, not
|
|
14
|
+
* a catch-all for "nothing said". Every UNATTENDED start path names itself, so a path that
|
|
15
|
+
* states nothing is the app: the one caller allowed to rely on the default. That rule exists
|
|
16
|
+
* because the opposite reading is silent, and it already cost one bug (a webhook-dispatched run
|
|
17
|
+
* defaulted into `ui` and its parked review's questions never reached the requester's ticket).
|
|
18
|
+
*/
|
|
19
|
+
export declare const intakeOriginSchema: v.PicklistSchema<["ui", "public-api", "tracker", "schedule"], undefined>;
|
|
20
|
+
export type IntakeOrigin = v.InferOutput<typeof intakeOriginSchema>;
|
|
21
|
+
/**
|
|
22
|
+
* Whether a run entered headlessly ({@link HEADLESS_INTAKE}). `undefined` is every legacy run
|
|
23
|
+
* and degrades to `ui`, the safe reading: no outbound writeback for a run whose intake cannot
|
|
24
|
+
* be proven headless.
|
|
25
|
+
*
|
|
26
|
+
* `=== true` rather than the bare lookup, which the type says is already a `boolean`. The value
|
|
27
|
+
* reaches here off a run's persisted `detail` JSON, and the picklist is a CLOSED vocabulary whose
|
|
28
|
+
* members outlive their retirement in stored rows: a run written under a member later dropped
|
|
29
|
+
* from the type indexes to `undefined` at runtime, and the declared `boolean` would be a lie the
|
|
30
|
+
* caller reads as "not headless" anyway. Saying so explicitly makes unrecognised and absent one
|
|
31
|
+
* answer on purpose rather than by luck.
|
|
32
|
+
*/
|
|
33
|
+
export declare function isHeadlessIntake(origin: IntakeOrigin | undefined): boolean;
|
|
34
|
+
/**
|
|
35
|
+
* Whether a run may LAND its work. `live` (the default, and every run before this existed) is the
|
|
36
|
+
* historical behaviour. `dry_run` is the sandboxed mode: the pipeline runs in full and opens its
|
|
37
|
+
* pull request, so the human sees a real diff on a real branch, but nothing merges: neither the
|
|
38
|
+
* `merger` step's auto-merge nor the manual merge endpoint.
|
|
39
|
+
*
|
|
40
|
+
* The PR is deliberately still opened. The deliverable a non-developer initiator needs to SEE is the diff,
|
|
41
|
+
* and withholding the push would leave them reading prose about work they cannot inspect; what
|
|
42
|
+
* makes the mode a sandbox is that the change cannot reach the default branch, not that it stays
|
|
43
|
+
* invisible.
|
|
44
|
+
*
|
|
45
|
+
* Requested per run at start, and FORCED for the roles a task's merge preset lists in
|
|
46
|
+
* `dryRunRoles`. The two compose one way only: a live request from a sandboxed role is a dry run,
|
|
47
|
+
* and there is no way to ask out of it, or the setting would be advisory.
|
|
48
|
+
*/
|
|
49
|
+
export declare const runModeSchema: v.PicklistSchema<["live", "dry_run"], undefined>;
|
|
50
|
+
export type RunMode = v.InferOutput<typeof runModeSchema>;
|
|
51
|
+
/**
|
|
52
|
+
* Whether a run is sandboxed. A helper rather than `=== 'dry_run'` scattered across the merge path
|
|
53
|
+
* and the SPA, so every place that must refuse to land work (or must say that a run will never
|
|
54
|
+
* land any) reads the mode the same way, and so a run persisted before the mode existed
|
|
55
|
+
* (absent ⇒ `live`) can never be mistaken for one.
|
|
56
|
+
*/
|
|
57
|
+
export declare function isDryRun(mode: RunMode | null | undefined): boolean;
|
|
58
|
+
/**
|
|
59
|
+
* Per-run diagnostic context captured for AFTER-THE-FACT investigation of a run (esp. a
|
|
60
|
+
* failure): the "where/what did this run actually execute on" facts that were previously
|
|
61
|
+
* spread across the DB (repo↔service↔installation joins), the harness transcript (model), or
|
|
62
|
+
* lost entirely (which backend a step ran on). Stamped by the engine at dispatch and refined
|
|
63
|
+
* on the first poll; it reflects the MOST RECENT container-step dispatch (the step most likely
|
|
64
|
+
* relevant to a failure), not a per-step history. Rides in the run's `detail` JSON (no dedicated
|
|
65
|
+
* column), like `ExecutionInstance.notes`/`frontendBindings`. Absent on legacy runs and on
|
|
66
|
+
* runs with no container step (pure inline/gate pipelines). NEVER carries a token or secret.
|
|
67
|
+
*/
|
|
68
|
+
export declare const runDiagnosticsSchema: v.ObjectSchema<{
|
|
69
|
+
/** Context of the most recent container-step dispatch. */
|
|
70
|
+
readonly lastDispatch: v.OptionalSchema<v.ObjectSchema<{
|
|
71
|
+
/** Index of the dispatched step within the pipeline. */
|
|
72
|
+
readonly stepIndex: v.NumberSchema<undefined>;
|
|
73
|
+
/** The step's agent kind (`coder`, `merger`, a custom kind, …). */
|
|
74
|
+
readonly agentKind: v.StringSchema<undefined>;
|
|
75
|
+
/** Resolved model ref `provider:model` (e.g. `anthropic:claude-opus-4-8`); null if unresolved. */
|
|
76
|
+
readonly model: v.OptionalSchema<v.NullableSchema<v.StringSchema<undefined>, undefined>, undefined>;
|
|
77
|
+
/**
|
|
78
|
+
* Which runner backend the step actually ran on, the datum that distinguishes a native
|
|
79
|
+
* host-process run from a sandboxed container: `local-native` | `local-container` |
|
|
80
|
+
* `runner-pool` | `cloudflare-container`. Filled on the first poll (the transport reports
|
|
81
|
+
* it); absent until then or on an older runtime.
|
|
82
|
+
*/
|
|
83
|
+
readonly executionBackend: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
|
|
84
|
+
/** The repo the step operated on. */
|
|
85
|
+
readonly repo: v.OptionalSchema<v.ObjectSchema<{
|
|
86
|
+
readonly owner: v.StringSchema<undefined>;
|
|
87
|
+
readonly name: v.StringSchema<undefined>;
|
|
88
|
+
/** The base branch the work branched from. */
|
|
89
|
+
readonly baseBranch: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
|
|
90
|
+
/** VCS provider (`github` | `gitlab`), resolved from the run's repo origin. */
|
|
91
|
+
readonly provider: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
|
|
92
|
+
}, undefined>, undefined>;
|
|
93
|
+
/** Epoch ms the dispatch was recorded. */
|
|
94
|
+
readonly at: v.NumberSchema<undefined>;
|
|
95
|
+
}, undefined>, undefined>;
|
|
96
|
+
/**
|
|
97
|
+
* The control-plane (orchestrator) host running the engine, NOT necessarily where the agent
|
|
98
|
+
* ran (a container step runs elsewhere; see `lastDispatch.executionBackend`). `platform` is the
|
|
99
|
+
* orchestrator's `process.platform` (e.g. `win32` pins a Windows local deployment, the class
|
|
100
|
+
* of host that surfaced the native-Windows git-auth break). Best-effort.
|
|
101
|
+
*/
|
|
102
|
+
readonly host: v.OptionalSchema<v.ObjectSchema<{
|
|
103
|
+
readonly platform: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
|
|
104
|
+
}, undefined>, undefined>;
|
|
105
|
+
}, undefined>;
|
|
106
|
+
export type RunDiagnostics = v.InferOutput<typeof runDiagnosticsSchema>;
|
|
107
|
+
//# sourceMappingURL=run-provenance.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"run-provenance.d.ts","sourceRoot":"","sources":["../src/run-provenance.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,SAAS,CAAA;AAQ5B;;;;;;;;;;;;;;;;GAgBG;AACH,eAAO,MAAM,kBAAkB,0EAA0D,CAAA;AACzF,MAAM,MAAM,YAAY,GAAG,CAAC,CAAC,WAAW,CAAC,OAAO,kBAAkB,CAAC,CAAA;AA8BnE;;;;;;;;;;;GAWG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,YAAY,GAAG,SAAS,GAAG,OAAO,CAE1E;AAED;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,aAAa,kDAAkC,CAAA;AAC5D,MAAM,MAAM,OAAO,GAAG,CAAC,CAAC,WAAW,CAAC,OAAO,aAAa,CAAC,CAAA;AAEzD;;;;;GAKG;AACH,wBAAgB,QAAQ,CAAC,IAAI,EAAE,OAAO,GAAG,IAAI,GAAG,SAAS,GAAG,OAAO,CAElE;AAED;;;;;;;;;GASG;AACH,eAAO,MAAM,oBAAoB;IAC/B,0DAA0D;;QAGtD,wDAAwD;;QAExD,mEAAmE;;QAEnE,kGAAkG;;QAElG;;;;;WAKG;;QAEH,qCAAqC;;;;YAKjC,8CAA8C;;YAE9C,+EAA+E;;;QAInF,0CAA0C;;;IAI9C;;;;;OAKG;;;;aAMH,CAAA;AACF,MAAM,MAAM,cAAc,GAAG,CAAC,CAAC,WAAW,CAAC,OAAO,oBAAoB,CAAC,CAAA"}
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
import * as v from 'valibot';
|
|
2
|
+
// A run's PROVENANCE: how it entered the system, whether it may land its work, and where it
|
|
3
|
+
// actually executed. Three small vocabularies that answer questions about the run rather than
|
|
4
|
+
// about the work, all of them riding the run's `detail` JSON rather than a column, and all read
|
|
5
|
+
// by policy (admission, the merge decision, the clarification writeback) or by an investigator
|
|
6
|
+
// after the fact. Split out of `execution.ts`, which describes the STEPS.
|
|
7
|
+
/**
|
|
8
|
+
* How a run entered the system. See `ExecutionInstance.intakeOrigin`.
|
|
9
|
+
*
|
|
10
|
+
* - `ui`: someone started it in the app, on their own board. The read-time default, and what
|
|
11
|
+
* every legacy run is.
|
|
12
|
+
* - `public-api`: started headlessly through the `/api/v1` surface.
|
|
13
|
+
* - `tracker`: dispatched from a pushed ticket by a per-ticket issue-intake schedule.
|
|
14
|
+
* - `schedule`: a recurring schedule fired it, either on its cadence or because a tracker push
|
|
15
|
+
* drained its queue early. Both are the same run against the same reused block (ADR 0032), so
|
|
16
|
+
* they deliberately share one origin; what differs is only what made the tick happen.
|
|
17
|
+
*
|
|
18
|
+
* `ui` is the DEFAULT, which makes it a positive claim that a human is watching in the app, not
|
|
19
|
+
* a catch-all for "nothing said". Every UNATTENDED start path names itself, so a path that
|
|
20
|
+
* states nothing is the app: the one caller allowed to rely on the default. That rule exists
|
|
21
|
+
* because the opposite reading is silent, and it already cost one bug (a webhook-dispatched run
|
|
22
|
+
* defaulted into `ui` and its parked review's questions never reached the requester's ticket).
|
|
23
|
+
*/
|
|
24
|
+
export const intakeOriginSchema = v.picklist(['ui', 'public-api', 'tracker', 'schedule']);
|
|
25
|
+
/**
|
|
26
|
+
* Whether an intake origin means the run's questions have to be pushed back OUT to where it came
|
|
27
|
+
* from, because there is no human overseer in the app to answer them (the parked requirements
|
|
28
|
+
* review's questions, above all).
|
|
29
|
+
*
|
|
30
|
+
* A `Record` rather than a `!== 'ui'` test on purpose: this is the classification the whole
|
|
31
|
+
* clarification writeback keys off, and a new intake surface must state which side of it falls
|
|
32
|
+
* on rather than inheriting an answer by being new. Adding a member to the picklist above fails
|
|
33
|
+
* to compile until it is answered here.
|
|
34
|
+
*
|
|
35
|
+
* `schedule` is the entry worth explaining, because "unattended" would predict `true` and the
|
|
36
|
+
* answer is `false`. A cadence fire runs against the schedule's REUSED block, and in queue mode
|
|
37
|
+
* `BugIntakeService` REPLACE-links each pick onto it: the block's linked ticket is dropped and
|
|
38
|
+
* re-pointed on the next fire, by design, so the block never accumulates stale context. Posting
|
|
39
|
+
* questions there would open a conversation on a channel that closes underneath it, since a
|
|
40
|
+
* reply arriving after the link moved resolves to no block and is dropped. What the writeback
|
|
41
|
+
* needs is not "was anyone present" but "is there a STABLE place to hold a conversation", and a
|
|
42
|
+
* reused block does not have one. Per-ticket dispatch does, which is why it is `true`: one
|
|
43
|
+
* permanent block per ticket. Giving queue mode the same treatment is a change to the LINKAGE
|
|
44
|
+
* (a per-run link, or a block per pick), never a flip of this flag.
|
|
45
|
+
*/
|
|
46
|
+
const HEADLESS_INTAKE = {
|
|
47
|
+
ui: false,
|
|
48
|
+
'public-api': true,
|
|
49
|
+
tracker: true,
|
|
50
|
+
schedule: false,
|
|
51
|
+
};
|
|
52
|
+
/**
|
|
53
|
+
* Whether a run entered headlessly ({@link HEADLESS_INTAKE}). `undefined` is every legacy run
|
|
54
|
+
* and degrades to `ui`, the safe reading: no outbound writeback for a run whose intake cannot
|
|
55
|
+
* be proven headless.
|
|
56
|
+
*
|
|
57
|
+
* `=== true` rather than the bare lookup, which the type says is already a `boolean`. The value
|
|
58
|
+
* reaches here off a run's persisted `detail` JSON, and the picklist is a CLOSED vocabulary whose
|
|
59
|
+
* members outlive their retirement in stored rows: a run written under a member later dropped
|
|
60
|
+
* from the type indexes to `undefined` at runtime, and the declared `boolean` would be a lie the
|
|
61
|
+
* caller reads as "not headless" anyway. Saying so explicitly makes unrecognised and absent one
|
|
62
|
+
* answer on purpose rather than by luck.
|
|
63
|
+
*/
|
|
64
|
+
export function isHeadlessIntake(origin) {
|
|
65
|
+
return origin != null && HEADLESS_INTAKE[origin] === true;
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Whether a run may LAND its work. `live` (the default, and every run before this existed) is the
|
|
69
|
+
* historical behaviour. `dry_run` is the sandboxed mode: the pipeline runs in full and opens its
|
|
70
|
+
* pull request, so the human sees a real diff on a real branch, but nothing merges: neither the
|
|
71
|
+
* `merger` step's auto-merge nor the manual merge endpoint.
|
|
72
|
+
*
|
|
73
|
+
* The PR is deliberately still opened. The deliverable a non-developer initiator needs to SEE is the diff,
|
|
74
|
+
* and withholding the push would leave them reading prose about work they cannot inspect; what
|
|
75
|
+
* makes the mode a sandbox is that the change cannot reach the default branch, not that it stays
|
|
76
|
+
* invisible.
|
|
77
|
+
*
|
|
78
|
+
* Requested per run at start, and FORCED for the roles a task's merge preset lists in
|
|
79
|
+
* `dryRunRoles`. The two compose one way only: a live request from a sandboxed role is a dry run,
|
|
80
|
+
* and there is no way to ask out of it, or the setting would be advisory.
|
|
81
|
+
*/
|
|
82
|
+
export const runModeSchema = v.picklist(['live', 'dry_run']);
|
|
83
|
+
/**
|
|
84
|
+
* Whether a run is sandboxed. A helper rather than `=== 'dry_run'` scattered across the merge path
|
|
85
|
+
* and the SPA, so every place that must refuse to land work (or must say that a run will never
|
|
86
|
+
* land any) reads the mode the same way, and so a run persisted before the mode existed
|
|
87
|
+
* (absent ⇒ `live`) can never be mistaken for one.
|
|
88
|
+
*/
|
|
89
|
+
export function isDryRun(mode) {
|
|
90
|
+
return mode === 'dry_run';
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Per-run diagnostic context captured for AFTER-THE-FACT investigation of a run (esp. a
|
|
94
|
+
* failure): the "where/what did this run actually execute on" facts that were previously
|
|
95
|
+
* spread across the DB (repo↔service↔installation joins), the harness transcript (model), or
|
|
96
|
+
* lost entirely (which backend a step ran on). Stamped by the engine at dispatch and refined
|
|
97
|
+
* on the first poll; it reflects the MOST RECENT container-step dispatch (the step most likely
|
|
98
|
+
* relevant to a failure), not a per-step history. Rides in the run's `detail` JSON (no dedicated
|
|
99
|
+
* column), like `ExecutionInstance.notes`/`frontendBindings`. Absent on legacy runs and on
|
|
100
|
+
* runs with no container step (pure inline/gate pipelines). NEVER carries a token or secret.
|
|
101
|
+
*/
|
|
102
|
+
export const runDiagnosticsSchema = v.object({
|
|
103
|
+
/** Context of the most recent container-step dispatch. */
|
|
104
|
+
lastDispatch: v.optional(v.object({
|
|
105
|
+
/** Index of the dispatched step within the pipeline. */
|
|
106
|
+
stepIndex: v.number(),
|
|
107
|
+
/** The step's agent kind (`coder`, `merger`, a custom kind, …). */
|
|
108
|
+
agentKind: v.string(),
|
|
109
|
+
/** Resolved model ref `provider:model` (e.g. `anthropic:claude-opus-4-8`); null if unresolved. */
|
|
110
|
+
model: v.optional(v.nullable(v.string())),
|
|
111
|
+
/**
|
|
112
|
+
* Which runner backend the step actually ran on, the datum that distinguishes a native
|
|
113
|
+
* host-process run from a sandboxed container: `local-native` | `local-container` |
|
|
114
|
+
* `runner-pool` | `cloudflare-container`. Filled on the first poll (the transport reports
|
|
115
|
+
* it); absent until then or on an older runtime.
|
|
116
|
+
*/
|
|
117
|
+
executionBackend: v.optional(v.string()),
|
|
118
|
+
/** The repo the step operated on. */
|
|
119
|
+
repo: v.optional(v.object({
|
|
120
|
+
owner: v.string(),
|
|
121
|
+
name: v.string(),
|
|
122
|
+
/** The base branch the work branched from. */
|
|
123
|
+
baseBranch: v.optional(v.string()),
|
|
124
|
+
/** VCS provider (`github` | `gitlab`), resolved from the run's repo origin. */
|
|
125
|
+
provider: v.optional(v.string()),
|
|
126
|
+
})),
|
|
127
|
+
/** Epoch ms the dispatch was recorded. */
|
|
128
|
+
at: v.number(),
|
|
129
|
+
})),
|
|
130
|
+
/**
|
|
131
|
+
* The control-plane (orchestrator) host running the engine, NOT necessarily where the agent
|
|
132
|
+
* ran (a container step runs elsewhere; see `lastDispatch.executionBackend`). `platform` is the
|
|
133
|
+
* orchestrator's `process.platform` (e.g. `win32` pins a Windows local deployment, the class
|
|
134
|
+
* of host that surfaced the native-Windows git-auth break). Best-effort.
|
|
135
|
+
*/
|
|
136
|
+
host: v.optional(v.object({
|
|
137
|
+
platform: v.optional(v.string()),
|
|
138
|
+
})),
|
|
139
|
+
});
|
|
140
|
+
//# sourceMappingURL=run-provenance.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"run-provenance.js","sourceRoot":"","sources":["../src/run-provenance.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,SAAS,CAAA;AAE5B,4FAA4F;AAC5F,8FAA8F;AAC9F,gGAAgG;AAChG,+FAA+F;AAC/F,0EAA0E;AAE1E;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,CAAC,QAAQ,CAAC,CAAC,IAAI,EAAE,YAAY,EAAE,SAAS,EAAE,UAAU,CAAC,CAAC,CAAA;AAGzF;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,MAAM,eAAe,GAAkC;IACrD,EAAE,EAAE,KAAK;IACT,YAAY,EAAE,IAAI;IAClB,OAAO,EAAE,IAAI;IACb,QAAQ,EAAE,KAAK;CAChB,CAAA;AAED;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,gBAAgB,CAAC,MAAgC;IAC/D,OAAO,MAAM,IAAI,IAAI,IAAI,eAAe,CAAC,MAAM,CAAC,KAAK,IAAI,CAAA;AAC3D,CAAC;AAED;;;;;;;;;;;;;;GAcG;AACH,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,CAAC,QAAQ,CAAC,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC,CAAA;AAG5D;;;;;GAKG;AACH,MAAM,UAAU,QAAQ,CAAC,IAAgC;IACvD,OAAO,IAAI,KAAK,SAAS,CAAA;AAC3B,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAAC,CAAC,MAAM,CAAC;IAC3C,0DAA0D;IAC1D,YAAY,EAAE,CAAC,CAAC,QAAQ,CACtB,CAAC,CAAC,MAAM,CAAC;QACP,wDAAwD;QACxD,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE;QACrB,mEAAmE;QACnE,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE;QACrB,kGAAkG;QAClG,KAAK,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC;QACzC;;;;;WAKG;QACH,gBAAgB,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC;QACxC,qCAAqC;QACrC,IAAI,EAAE,CAAC,CAAC,QAAQ,CACd,CAAC,CAAC,MAAM,CAAC;YACP,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE;YACjB,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE;YAChB,8CAA8C;YAC9C,UAAU,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC;YAClC,+EAA+E;YAC/E,QAAQ,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC;SACjC,CAAC,CACH;QACD,0CAA0C;QAC1C,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE;KACf,CAAC,CACH;IACD;;;;;OAKG;IACH,IAAI,EAAE,CAAC,CAAC,QAAQ,CACd,CAAC,CAAC,MAAM,CAAC;QACP,QAAQ,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC;KACjC,CAAC,CACH;CACF,CAAC,CAAA"}
|
package/dist/snapshot.d.ts
CHANGED
|
@@ -1456,7 +1456,7 @@ export declare const workspaceSnapshotSchema: v.ObjectSchema<{
|
|
|
1456
1456
|
readonly initiatedBy: v.OptionalSchema<v.NullableSchema<v.StringSchema<undefined>, undefined>, undefined>;
|
|
1457
1457
|
readonly initiatedByRole: v.OptionalSchema<v.NullableSchema<v.PicklistSchema<readonly ["admin", "member", "viewer"], undefined>, undefined>, undefined>;
|
|
1458
1458
|
readonly mode: v.OptionalSchema<v.PicklistSchema<["live", "dry_run"], undefined>, undefined>;
|
|
1459
|
-
readonly intakeOrigin: v.OptionalSchema<v.PicklistSchema<["ui", "public-api"], undefined>, undefined>;
|
|
1459
|
+
readonly intakeOrigin: v.OptionalSchema<v.PicklistSchema<["ui", "public-api", "tracker", "schedule"], undefined>, undefined>;
|
|
1460
1460
|
readonly createdAt: v.OptionalSchema<v.NumberSchema<undefined>, undefined>;
|
|
1461
1461
|
readonly rev: v.OptionalSchema<v.NumberSchema<undefined>, undefined>;
|
|
1462
1462
|
readonly diagnostics: v.OptionalSchema<v.ObjectSchema<{
|
package/dist/tracker.d.ts
CHANGED
|
@@ -25,9 +25,10 @@ export declare const trackerSettingsSchema: v.ObjectSchema<{
|
|
|
25
25
|
* issue(s), so the loop is answerable from where the work was requested. Per-task
|
|
26
26
|
* overridable via `Block.trackerQuestionsOnPark`. Default off.
|
|
27
27
|
*
|
|
28
|
-
* Deliberately scoped to runs whose `ExecutionInstance.intakeOrigin` is
|
|
29
|
-
* a
|
|
30
|
-
* surface is unchanged
|
|
28
|
+
* Deliberately scoped to runs whose `ExecutionInstance.intakeOrigin` is HEADLESS
|
|
29
|
+
* (`isHeadlessIntake`: a `/api/v1` start or a per-ticket tracker dispatch): a task started
|
|
30
|
+
* in the SPA has a human overseer in the app and its clarification surface is unchanged
|
|
31
|
+
* (see `docs/initiatives/headless-clarification-loop.md`).
|
|
31
32
|
*/
|
|
32
33
|
readonly writebackQuestionsOnPark: v.BooleanSchema<undefined>;
|
|
33
34
|
readonly updatedAt: v.NumberSchema<undefined>;
|
package/dist/tracker.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tracker.d.ts","sourceRoot":"","sources":["../src/tracker.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,SAAS,CAAA;AAY5B,eAAO,MAAM,iBAAiB,2DAA2C,CAAA;AACzE,MAAM,MAAM,WAAW,GAAG,CAAC,CAAC,WAAW,CAAC,OAAO,iBAAiB,CAAC,CAAA;AAEjE,oFAAoF;AACpF,eAAO,MAAM,qBAAqB;;IAEhC,mFAAmF;;IAEnF,uEAAuE;;IAEvE;;;OAGG;;IAEH;;;;OAIG;;IAEH
|
|
1
|
+
{"version":3,"file":"tracker.d.ts","sourceRoot":"","sources":["../src/tracker.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,SAAS,CAAA;AAY5B,eAAO,MAAM,iBAAiB,2DAA2C,CAAA;AACzE,MAAM,MAAM,WAAW,GAAG,CAAC,CAAC,WAAW,CAAC,OAAO,iBAAiB,CAAC,CAAA;AAEjE,oFAAoF;AACpF,eAAO,MAAM,qBAAqB;;IAEhC,mFAAmF;;IAEnF,uEAAuE;;IAEvE;;;OAGG;;IAEH;;;;OAIG;;IAEH;;;;;;;;;;OAUG;;;aAGH,CAAA;AACF,MAAM,MAAM,eAAe,GAAG,CAAC,CAAC,WAAW,CAAC,OAAO,qBAAqB,CAAC,CAAA;AAEzE,iDAAiD;AACjD,eAAO,MAAM,wBAAwB;;;;;;;aAOnC,CAAA;AACF,MAAM,MAAM,uBAAuB,GAAG,CAAC,CAAC,WAAW,CAAC,OAAO,wBAAwB,CAAC,CAAA"}
|
package/dist/tracker.js
CHANGED
|
@@ -33,9 +33,10 @@ export const trackerSettingsSchema = v.object({
|
|
|
33
33
|
* issue(s), so the loop is answerable from where the work was requested. Per-task
|
|
34
34
|
* overridable via `Block.trackerQuestionsOnPark`. Default off.
|
|
35
35
|
*
|
|
36
|
-
* Deliberately scoped to runs whose `ExecutionInstance.intakeOrigin` is
|
|
37
|
-
* a
|
|
38
|
-
* surface is unchanged
|
|
36
|
+
* Deliberately scoped to runs whose `ExecutionInstance.intakeOrigin` is HEADLESS
|
|
37
|
+
* (`isHeadlessIntake`: a `/api/v1` start or a per-ticket tracker dispatch): a task started
|
|
38
|
+
* in the SPA has a human overseer in the app and its clarification surface is unchanged
|
|
39
|
+
* (see `docs/initiatives/headless-clarification-loop.md`).
|
|
39
40
|
*/
|
|
40
41
|
writebackQuestionsOnPark: v.boolean(),
|
|
41
42
|
updatedAt: v.number(),
|
package/dist/tracker.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tracker.js","sourceRoot":"","sources":["../src/tracker.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,SAAS,CAAA;AAE5B,8EAA8E;AAC9E,8EAA8E;AAC9E,gFAAgF;AAChF,yEAAyE;AACzE,kFAAkF;AAClF,0EAA0E;AAC1E,8EAA8E;AAC9E,oEAAoE;AACpE,8EAA8E;AAE9E,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,CAAC,QAAQ,CAAC,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAA;AAGzE,oFAAoF;AACpF,MAAM,CAAC,MAAM,qBAAqB,GAAG,CAAC,CAAC,MAAM,CAAC;IAC5C,OAAO,EAAE,CAAC,CAAC,QAAQ,CAAC,iBAAiB,CAAC;IACtC,mFAAmF;IACnF,cAAc,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC;IACtC,uEAAuE;IACvE,YAAY,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC;IACpC;;;OAGG;IACH,wBAAwB,EAAE,CAAC,CAAC,OAAO,EAAE;IACrC;;;;OAIG;IACH,uBAAuB,EAAE,CAAC,CAAC,OAAO,EAAE;IACpC
|
|
1
|
+
{"version":3,"file":"tracker.js","sourceRoot":"","sources":["../src/tracker.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,SAAS,CAAA;AAE5B,8EAA8E;AAC9E,8EAA8E;AAC9E,gFAAgF;AAChF,yEAAyE;AACzE,kFAAkF;AAClF,0EAA0E;AAC1E,8EAA8E;AAC9E,oEAAoE;AACpE,8EAA8E;AAE9E,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,CAAC,QAAQ,CAAC,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAA;AAGzE,oFAAoF;AACpF,MAAM,CAAC,MAAM,qBAAqB,GAAG,CAAC,CAAC,MAAM,CAAC;IAC5C,OAAO,EAAE,CAAC,CAAC,QAAQ,CAAC,iBAAiB,CAAC;IACtC,mFAAmF;IACnF,cAAc,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC;IACtC,uEAAuE;IACvE,YAAY,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC;IACpC;;;OAGG;IACH,wBAAwB,EAAE,CAAC,CAAC,OAAO,EAAE;IACrC;;;;OAIG;IACH,uBAAuB,EAAE,CAAC,CAAC,OAAO,EAAE;IACpC;;;;;;;;;;OAUG;IACH,wBAAwB,EAAE,CAAC,CAAC,OAAO,EAAE;IACrC,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE;CACtB,CAAC,CAAA;AAGF,iDAAiD;AACjD,MAAM,CAAC,MAAM,wBAAwB,GAAG,CAAC,CAAC,MAAM,CAAC;IAC/C,OAAO,EAAE,CAAC,CAAC,QAAQ,CAAC,iBAAiB,CAAC;IACtC,cAAc,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;IACpE,YAAY,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;IAClE,wBAAwB,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC;IACjD,uBAAuB,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC;IAChD,wBAAwB,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC;CAClD,CAAC,CAAA"}
|