@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.
Files changed (42) hide show
  1. package/dist/debug-api.d.ts.map +1 -1
  2. package/dist/debug-api.js +2 -1
  3. package/dist/debug-api.js.map +1 -1
  4. package/dist/entities.d.ts +2 -1
  5. package/dist/entities.d.ts.map +1 -1
  6. package/dist/entities.js +2 -1
  7. package/dist/entities.js.map +1 -1
  8. package/dist/execution.d.ts +10 -111
  9. package/dist/execution.d.ts.map +1 -1
  10. package/dist/execution.js +10 -89
  11. package/dist/execution.js.map +1 -1
  12. package/dist/index.d.ts +1 -0
  13. package/dist/index.d.ts.map +1 -1
  14. package/dist/index.js +1 -0
  15. package/dist/index.js.map +1 -1
  16. package/dist/notification-webhooks.d.ts +61 -4
  17. package/dist/notification-webhooks.d.ts.map +1 -1
  18. package/dist/notification-webhooks.js +35 -4
  19. package/dist/notification-webhooks.js.map +1 -1
  20. package/dist/requests.js +1 -1
  21. package/dist/requests.js.map +1 -1
  22. package/dist/routes/agent-runs.d.ts +2 -2
  23. package/dist/routes/bug-hunt.d.ts +2 -2
  24. package/dist/routes/execution.d.ts +8 -8
  25. package/dist/routes/human-review.d.ts +1 -1
  26. package/dist/routes/human-test.d.ts +5 -5
  27. package/dist/routes/notification-webhooks.d.ts +129 -1
  28. package/dist/routes/notification-webhooks.d.ts.map +1 -1
  29. package/dist/routes/notification-webhooks.js +49 -6
  30. package/dist/routes/notification-webhooks.js.map +1 -1
  31. package/dist/routes/visual-confirm.d.ts +3 -3
  32. package/dist/routes/workspaces.d.ts +2 -2
  33. package/dist/run-provenance.d.ts +107 -0
  34. package/dist/run-provenance.d.ts.map +1 -0
  35. package/dist/run-provenance.js +140 -0
  36. package/dist/run-provenance.js.map +1 -0
  37. package/dist/snapshot.d.ts +1 -1
  38. package/dist/tracker.d.ts +4 -3
  39. package/dist/tracker.d.ts.map +1 -1
  40. package/dist/tracker.js +4 -3
  41. package/dist/tracker.js.map +1 -1
  42. 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;AAc5B,8FAA8F;AAC9F,eAAO,MAAM,8BAA8B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAOzC,CAAA;AAEF,yFAAyF;AACzF,eAAO,MAAM,8BAA8B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAKzC,CAAA;AAEF,wDAAwD;AACxD,eAAO,MAAM,iCAAiC;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAI5C,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 session-authed and mounted
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
- // These are writes to an integration's configuration, so they sit behind the
10
- // `integrations.manage` workspace permission like every other admin controller.
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,iGAAiG;AACjG,iGAAiG;AACjG,4FAA4F;AAC5F,EAAE;AACF,6EAA6E;AAC7E,gFAAgF;AAEhF,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"}
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"}
@@ -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 `public-api`:
29
- * a task started in the SPA has a human overseer in the app and its clarification
30
- * surface is unchanged (see `docs/initiatives/headless-clarification-loop.md`).
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>;
@@ -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;;;;;;;;;OASG;;;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"}
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 `public-api`:
37
- * a task started in the SPA has a human overseer in the app and its clarification
38
- * surface is unchanged (see `docs/initiatives/headless-clarification-loop.md`).
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(),
@@ -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;;;;;;;;;OASG;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"}
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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cat-factory/contracts",
3
- "version": "0.232.0",
3
+ "version": "0.234.0",
4
4
  "description": "Valibot wire contract shared between the Agent Architecture Board frontend and backend.",
5
5
  "repository": {
6
6
  "type": "git",