@oisincoveney/pipeline 1.18.0 → 1.18.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/config.d.ts CHANGED
@@ -223,8 +223,8 @@ declare const configSchema: z.ZodObject<{
223
223
  policy: z.ZodOptional<z.ZodObject<{
224
224
  commands: z.ZodOptional<z.ZodEnum<{
225
225
  allow: "allow";
226
- deny: "deny";
227
226
  "trusted-only": "trusted-only";
227
+ deny: "deny";
228
228
  }>>;
229
229
  modules: z.ZodOptional<z.ZodEnum<{
230
230
  allow: "allow";
@@ -279,10 +279,10 @@ declare const configSchema: z.ZodObject<{
279
279
  }, z.core.$strict>>;
280
280
  output: z.ZodOptional<z.ZodObject<{
281
281
  format: z.ZodEnum<{
282
- json_schema: "json_schema";
283
282
  text: "text";
284
283
  json: "json";
285
284
  jsonl: "jsonl";
285
+ json_schema: "json_schema";
286
286
  }>;
287
287
  repair: z.ZodOptional<z.ZodObject<{
288
288
  enabled: z.ZodOptional<z.ZodBoolean>;
@@ -340,10 +340,10 @@ declare const configSchema: z.ZodObject<{
340
340
  disabled: "disabled";
341
341
  }>>>;
342
342
  output_formats: z.ZodOptional<z.ZodArray<z.ZodEnum<{
343
- json_schema: "json_schema";
344
343
  text: "text";
345
344
  json: "json";
346
345
  jsonl: "jsonl";
346
+ json_schema: "json_schema";
347
347
  }>>>;
348
348
  rules: z.ZodOptional<z.ZodBoolean>;
349
349
  skills: z.ZodOptional<z.ZodBoolean>;
@@ -1,6 +1,6 @@
1
1
  import { PipelineConfigError } from "../config.js";
2
2
  import { runPipelineFromConfig } from "../pipeline-runtime.js";
3
- import { RUNNER_PAYLOAD_ENV, parseRunnerJobPayloadWithIssues, resolveRunnerEventSinkAuthToken } from "../runner-job-contract.js";
3
+ import { RUNNER_PAYLOAD_ENV, parseRunnerJobPayloadWithIssues } from "../runner-job-contract.js";
4
4
  import { createRunnerEventSink } from "../runner-event-sink.js";
5
5
  import { compileScheduleArtifact, generateScheduleArtifact } from "../schedule-planner.js";
6
6
  import { createPullRequest } from "./delivery.js";
@@ -14,8 +14,6 @@ const EXIT_FAIL = 1;
14
14
  const EXIT_CANCELLED = 130;
15
15
  const EXIT_VALIDATION = 64;
16
16
  const EXIT_STARTUP = 70;
17
- const RUNNER_EVENT_SINK_URL_ENV = "OISIN_PIPELINE_EVENT_SINK_URL";
18
- const RUNNER_EVENT_SINK_AUTH_HEADER_ENV = "OISIN_PIPELINE_EVENT_AUTH_HEADER";
19
17
  const RUNNER_SCHEDULE_ENTRYPOINT = "pipe";
20
18
  async function runRunnerJob(options = {}) {
21
19
  const prepared = prepareRunnerJob(options);
@@ -30,6 +28,7 @@ async function runRunnerJob(options = {}) {
30
28
  let signalFinalResultRecorded = false;
31
29
  const sink = createRunnerSink({
32
30
  env,
31
+ events: payload.events,
33
32
  fetch: options.fetch,
34
33
  runId: payload.run.id
35
34
  });
@@ -209,6 +208,7 @@ async function reportPreparedValidationFailure(failure, options) {
209
208
  if (failure.recoverable) {
210
209
  const sink = createRunnerSink({
211
210
  env: failure.env,
211
+ events: failure.recoverable.events,
212
212
  fetch: options.fetch,
213
213
  runId: failure.recoverable.run.id
214
214
  });
@@ -217,26 +217,23 @@ async function reportPreparedValidationFailure(failure, options) {
217
217
  }
218
218
  return EXIT_VALIDATION;
219
219
  }
220
- function resolveAuthToken(env, stderr) {
221
- try {
222
- return resolveRunnerEventSinkAuthToken({ env });
223
- } catch (err) {
224
- const message = err instanceof Error ? err.message : String(err);
225
- stderr.write(`${message}\n`);
220
+ function resolveAuthToken(authTokenEnv, env, stderr) {
221
+ const token = env[authTokenEnv]?.trim();
222
+ if (!token) {
223
+ stderr.write(`Runner event auth token is required. Set ${authTokenEnv}.\n`);
226
224
  return null;
227
225
  }
226
+ return token;
228
227
  }
229
228
  function createRunnerSink(options) {
230
- const url = options.env[RUNNER_EVENT_SINK_URL_ENV]?.trim();
231
- if (!url) return createNoopRunnerEventSink();
232
- const authToken = resolveAuthToken(options.env, { write: () => true });
229
+ const authToken = resolveAuthToken(options.events.authTokenEnv, options.env, { write: () => true });
233
230
  if (!authToken) return createNoopRunnerEventSink();
234
231
  return createRunnerEventSink({
235
- authHeader: options.env[RUNNER_EVENT_SINK_AUTH_HEADER_ENV]?.trim() || "Authorization",
232
+ authHeader: options.events.authHeader,
236
233
  authToken,
237
234
  fetch: options.fetch,
238
235
  runId: options.runId,
239
- url
236
+ url: options.events.url
240
237
  });
241
238
  }
242
239
  function createNoopRunnerEventSink() {
@@ -38,6 +38,11 @@ declare const runnerRepositoryContextSchema: z.ZodObject<{
38
38
  declare const runnerDeliverySchema: z.ZodObject<{
39
39
  pullRequest: z.ZodDefault<z.ZodBoolean>;
40
40
  }, z.core.$strict>;
41
+ declare const runnerEventsSchema: z.ZodObject<{
42
+ authHeader: z.ZodDefault<z.ZodString>;
43
+ authTokenEnv: z.ZodString;
44
+ url: z.ZodString;
45
+ }, z.core.$strict>;
41
46
  declare const runnerMomokayaContextSchema: z.ZodObject<{
42
47
  automationNamespace: z.ZodOptional<z.ZodString>;
43
48
  previewEnabled: z.ZodBoolean;
@@ -48,6 +53,11 @@ declare const runnerJobPayloadSchema: z.ZodObject<{
48
53
  delivery: z.ZodDefault<z.ZodObject<{
49
54
  pullRequest: z.ZodDefault<z.ZodBoolean>;
50
55
  }, z.core.$strict>>;
56
+ events: z.ZodObject<{
57
+ authHeader: z.ZodDefault<z.ZodString>;
58
+ authTokenEnv: z.ZodString;
59
+ url: z.ZodString;
60
+ }, z.core.$strict>;
51
61
  momokaya: z.ZodOptional<z.ZodObject<{
52
62
  automationNamespace: z.ZodOptional<z.ZodString>;
53
63
  previewEnabled: z.ZodBoolean;
@@ -75,6 +85,7 @@ declare const runnerJobPayloadSchema: z.ZodObject<{
75
85
  }, z.core.$strict>], "kind">;
76
86
  }, z.core.$strict>;
77
87
  type RunnerDelivery = z.infer<typeof runnerDeliverySchema>;
88
+ type RunnerEvents = z.infer<typeof runnerEventsSchema>;
78
89
  type RunnerJobPayload = z.infer<typeof runnerJobPayloadSchema>;
79
90
  type RunnerMomokayaContext = z.infer<typeof runnerMomokayaContextSchema>;
80
91
  type RunnerRepositoryContext = z.infer<typeof runnerRepositoryContextSchema>;
@@ -87,6 +98,11 @@ declare const runnerJobPayloadJsonSchema: z.core.ZodStandardJSONSchemaPayload<z.
87
98
  delivery: z.ZodDefault<z.ZodObject<{
88
99
  pullRequest: z.ZodDefault<z.ZodBoolean>;
89
100
  }, z.core.$strict>>;
101
+ events: z.ZodObject<{
102
+ authHeader: z.ZodDefault<z.ZodString>;
103
+ authTokenEnv: z.ZodString;
104
+ url: z.ZodString;
105
+ }, z.core.$strict>;
90
106
  momokaya: z.ZodOptional<z.ZodObject<{
91
107
  automationNamespace: z.ZodOptional<z.ZodString>;
92
108
  previewEnabled: z.ZodBoolean;
@@ -119,6 +135,7 @@ interface RunnerJobPayloadValidationIssue {
119
135
  path: string;
120
136
  }
121
137
  interface RecoverableRunnerJobPayloadEnvelope {
138
+ events: RunnerEvents;
122
139
  run: RunnerRunIdentity;
123
140
  }
124
141
  declare class RunnerJobPayloadValidationError extends Error {
@@ -135,12 +152,14 @@ type RunnerJobPayloadParseResult = {
135
152
  };
136
153
  interface BuildRunnerJobPayloadOptions {
137
154
  delivery?: RunnerDelivery;
155
+ events: RunnerEvents;
138
156
  momokaya?: RunnerMomokayaContext;
139
157
  repository: RunnerRepositoryContext;
140
158
  run: RunnerRunIdentity;
141
159
  task: RunnerTask;
142
160
  }
143
161
  interface CreateRunnerJobPayloadEnvOptions {
162
+ events: RunnerEvents;
144
163
  project: string;
145
164
  repository: RunnerRepositoryContext;
146
165
  requestedBy?: string;
@@ -148,8 +167,8 @@ interface CreateRunnerJobPayloadEnvOptions {
148
167
  taskPrompt: string;
149
168
  }
150
169
  interface ResolveRunnerEventSinkAuthTokenOptions {
170
+ authTokenEnv: string;
151
171
  env?: Record<string, string | undefined>;
152
- serviceAccountTokenPath?: string;
153
172
  }
154
173
  interface RunnerEventMappingContext {
155
174
  runId: string;
@@ -276,8 +295,8 @@ type RunnerEventRecord = (RunnerEventEnvelope & {
276
295
  finalResult: RunnerFinalResultDetails;
277
296
  type: "workflow.finish";
278
297
  });
279
- declare function resolveRunnerEventSinkAuthToken(options?: ResolveRunnerEventSinkAuthTokenOptions): string;
280
- declare function resolveRunnerEventSinkAuthHeader(options?: ResolveRunnerEventSinkAuthTokenOptions): string;
298
+ declare function resolveRunnerEventSinkAuthToken(options: ResolveRunnerEventSinkAuthTokenOptions): string;
299
+ declare function resolveRunnerEventSinkAuthHeader(options: ResolveRunnerEventSinkAuthTokenOptions): string;
281
300
  declare function createRunnerJobPayloadEnv(options: CreateRunnerJobPayloadEnvOptions): {
282
301
  name: typeof RUNNER_PAYLOAD_ENV;
283
302
  value: string;
@@ -287,4 +306,4 @@ declare function parseRunnerJobPayload(rawPayload: string): RunnerJobPayload;
287
306
  declare function parseRunnerJobPayloadWithIssues(rawPayload: string): RunnerJobPayloadParseResult;
288
307
  declare function mapRuntimeEventToRunnerEventRecords(event: PipelineRuntimeEvent, context: RunnerEventMappingContext): RunnerEventRecord[];
289
308
  //#endregion
290
- export { BuildRunnerJobPayloadOptions, CreateRunnerJobPayloadEnvOptions, RUNNER_JOB_CONTRACT_VERSION, RUNNER_PAYLOAD_ENV, RecoverableRunnerJobPayloadEnvelope, ResolveRunnerEventSinkAuthTokenOptions, RunnerArtifactDetails, RunnerArtifactStatus, RunnerDelivery, RunnerEventMappingContext, RunnerEventRecord, RunnerFinalResultDetails, RunnerGateDetails, RunnerGateStatus, RunnerHookResultDetails, RunnerJobPayload, RunnerJobPayloadParseResult, RunnerJobPayloadValidationError, RunnerJobPayloadValidationIssue, RunnerLogDetails, RunnerLogLevel, RunnerMomokayaContext, RunnerNodeDetails, RunnerNodeStatus, RunnerRepositoryContext, RunnerRunIdentity, RunnerTask, RunnerTaskPrompt, RunnerTaskTicket, RunnerWorkflowEdgeDetails, RunnerWorkflowEdgeRecordDetails, RunnerWorkflowNodeDetails, RunnerWorkflowPlanDetails, buildRunnerJobPayload, createRunnerJobPayloadEnv, mapRuntimeEventToRunnerEventRecords, parseRunnerJobPayload, parseRunnerJobPayloadWithIssues, resolveRunnerEventSinkAuthHeader, resolveRunnerEventSinkAuthToken, runnerDeliverySchema, runnerJobPayloadJsonSchema, runnerJobPayloadSchema, runnerMomokayaContextSchema, runnerRepositoryContextSchema, runnerRunIdentitySchema, runnerTaskPromptSchema, runnerTaskSchema, runnerTaskTicketSchema };
309
+ export { BuildRunnerJobPayloadOptions, CreateRunnerJobPayloadEnvOptions, RUNNER_JOB_CONTRACT_VERSION, RUNNER_PAYLOAD_ENV, RecoverableRunnerJobPayloadEnvelope, ResolveRunnerEventSinkAuthTokenOptions, RunnerArtifactDetails, RunnerArtifactStatus, RunnerDelivery, RunnerEventMappingContext, RunnerEventRecord, RunnerEvents, RunnerFinalResultDetails, RunnerGateDetails, RunnerGateStatus, RunnerHookResultDetails, RunnerJobPayload, RunnerJobPayloadParseResult, RunnerJobPayloadValidationError, RunnerJobPayloadValidationIssue, RunnerLogDetails, RunnerLogLevel, RunnerMomokayaContext, RunnerNodeDetails, RunnerNodeStatus, RunnerRepositoryContext, RunnerRunIdentity, RunnerTask, RunnerTaskPrompt, RunnerTaskTicket, RunnerWorkflowEdgeDetails, RunnerWorkflowEdgeRecordDetails, RunnerWorkflowNodeDetails, RunnerWorkflowPlanDetails, buildRunnerJobPayload, createRunnerJobPayloadEnv, mapRuntimeEventToRunnerEventRecords, parseRunnerJobPayload, parseRunnerJobPayloadWithIssues, resolveRunnerEventSinkAuthHeader, resolveRunnerEventSinkAuthToken, runnerDeliverySchema, runnerEventsSchema, runnerJobPayloadJsonSchema, runnerJobPayloadSchema, runnerMomokayaContextSchema, runnerRepositoryContextSchema, runnerRunIdentitySchema, runnerTaskPromptSchema, runnerTaskSchema, runnerTaskTicketSchema };
@@ -1,5 +1,4 @@
1
1
  import { parseJson } from "./safe-json.js";
2
- import { existsSync, readFileSync } from "node:fs";
3
2
  import { z } from "zod";
4
3
  //#region src/runner-job-contract.ts
5
4
  const RUNNER_PAYLOAD_ENV = "OISIN_PIPELINE_RUNNER_PAYLOAD_JSON";
@@ -27,6 +26,11 @@ const runnerRepositoryContextSchema = z.object({
27
26
  url: z.string().url()
28
27
  }).strict();
29
28
  const runnerDeliverySchema = z.object({ pullRequest: z.boolean().default(false) }).strict();
29
+ const runnerEventsSchema = z.object({
30
+ authHeader: z.string().min(1).default("Authorization"),
31
+ authTokenEnv: z.string().min(1),
32
+ url: z.string().url()
33
+ }).strict();
30
34
  const runnerMomokayaContextSchema = z.object({
31
35
  automationNamespace: z.string().min(1).optional(),
32
36
  previewEnabled: z.boolean(),
@@ -35,6 +39,7 @@ const runnerMomokayaContextSchema = z.object({
35
39
  const runnerJobPayloadSchema = z.object({
36
40
  contractVersion: z.literal("1", { error: "runner job payload contract version must be 1" }).default("1"),
37
41
  delivery: runnerDeliverySchema.default({ pullRequest: false }),
42
+ events: runnerEventsSchema,
38
43
  momokaya: runnerMomokayaContextSchema.optional(),
39
44
  repository: runnerRepositoryContextSchema,
40
45
  run: runnerRunIdentitySchema,
@@ -49,22 +54,12 @@ var RunnerJobPayloadValidationError = class extends Error {
49
54
  this.issues = issues;
50
55
  }
51
56
  };
52
- const EVENT_AUTH_TOKEN_ENV_KEYS = ["OISIN_PIPELINE_EVENT_AUTH_TOKEN", "PIPELINE_EVENT_API_TOKEN"];
53
- const DEFAULT_SERVICE_ACCOUNT_TOKEN_PATH = "/var/run/secrets/kubernetes.io/serviceaccount/token";
54
- function resolveRunnerEventSinkAuthToken(options = {}) {
55
- const env = options.env ?? process.env;
56
- for (const key of EVENT_AUTH_TOKEN_ENV_KEYS) {
57
- const token = env[key]?.trim();
58
- if (token) return token;
59
- }
60
- const tokenPath = options.serviceAccountTokenPath ?? DEFAULT_SERVICE_ACCOUNT_TOKEN_PATH;
61
- if (existsSync(tokenPath)) {
62
- const token = readFileSync(tokenPath, "utf8").trim();
63
- if (token) return token;
64
- }
65
- throw new Error(`Runner event auth token is required. Set ${EVENT_AUTH_TOKEN_ENV_KEYS.join(" or ")}, or mount a readable Kubernetes service account token at ${tokenPath}.`);
57
+ function resolveRunnerEventSinkAuthToken(options) {
58
+ const token = (options.env ?? process.env)[options.authTokenEnv]?.trim();
59
+ if (token) return token;
60
+ throw new Error(`Runner event auth token is required. Set ${options.authTokenEnv}.`);
66
61
  }
67
- function resolveRunnerEventSinkAuthHeader(options = {}) {
62
+ function resolveRunnerEventSinkAuthHeader(options) {
68
63
  return `Bearer ${resolveRunnerEventSinkAuthToken(options)}`;
69
64
  }
70
65
  function createRunnerJobPayloadEnv(options) {
@@ -74,6 +69,7 @@ function createRunnerJobPayloadEnv(options) {
74
69
  project: options.project,
75
70
  requestedBy: options.requestedBy
76
71
  },
72
+ events: options.events,
77
73
  repository: options.repository,
78
74
  task: {
79
75
  kind: "prompt",
@@ -89,6 +85,7 @@ function buildRunnerJobPayload(options) {
89
85
  return runnerJobPayloadSchema.parse({
90
86
  contractVersion: "1",
91
87
  delivery: options.delivery,
88
+ events: options.events,
92
89
  momokaya: options.momokaya,
93
90
  repository: options.repository,
94
91
  run: options.run,
@@ -393,8 +390,12 @@ function recoverablePayloadEnvelope(payload) {
393
390
  const envelope = readRecord(payload);
394
391
  if (!envelope) return {};
395
392
  const run = runnerRunIdentitySchema.safeParse(envelope.run);
396
- if (!run.success) return {};
397
- return { recoverable: { run: run.data } };
393
+ const events = runnerEventsSchema.safeParse(envelope.events);
394
+ if (!(run.success && events.success)) return {};
395
+ return { recoverable: {
396
+ events: events.data,
397
+ run: run.data
398
+ } };
398
399
  }
399
400
  function omitUndefined(value) {
400
401
  return Object.fromEntries(Object.entries(value).filter(([, item]) => item !== void 0));
@@ -406,4 +407,4 @@ function assertNever(value) {
406
407
  throw new Error(`Unhandled runtime event: ${String(value)}`);
407
408
  }
408
409
  //#endregion
409
- export { RUNNER_JOB_CONTRACT_VERSION, RUNNER_PAYLOAD_ENV, RunnerJobPayloadValidationError, buildRunnerJobPayload, createRunnerJobPayloadEnv, mapRuntimeEventToRunnerEventRecords, parseRunnerJobPayload, parseRunnerJobPayloadWithIssues, resolveRunnerEventSinkAuthHeader, resolveRunnerEventSinkAuthToken, runnerDeliverySchema, runnerJobPayloadJsonSchema, runnerJobPayloadSchema, runnerMomokayaContextSchema, runnerRepositoryContextSchema, runnerRunIdentitySchema, runnerTaskPromptSchema, runnerTaskSchema, runnerTaskTicketSchema };
410
+ export { RUNNER_JOB_CONTRACT_VERSION, RUNNER_PAYLOAD_ENV, RunnerJobPayloadValidationError, buildRunnerJobPayload, createRunnerJobPayloadEnv, mapRuntimeEventToRunnerEventRecords, parseRunnerJobPayload, parseRunnerJobPayloadWithIssues, resolveRunnerEventSinkAuthHeader, resolveRunnerEventSinkAuthToken, runnerDeliverySchema, runnerEventsSchema, runnerJobPayloadJsonSchema, runnerJobPayloadSchema, runnerMomokayaContextSchema, runnerRepositoryContextSchema, runnerRunIdentitySchema, runnerTaskPromptSchema, runnerTaskSchema, runnerTaskTicketSchema };
@@ -122,7 +122,8 @@ Host choices are `all`, `opencode`, and `codex`.
122
122
  Runs the in-pod backend worker entrypoint. The job reads
123
123
  `OISIN_PIPELINE_RUNNER_PAYLOAD_JSON`, prepares `PIPELINE_TARGET_PATH` or clones
124
124
  the requested repository into `/workspace`, generates a task-specific schedule,
125
- and appends runtime events to `OISIN_PIPELINE_EVENT_SINK_URL` when configured.
125
+ and appends runtime events to the Console endpoint configured by payload
126
+ `events.url`.
126
127
 
127
128
  The runner job does not call the Kubernetes API. Validation errors exit `64`,
128
129
  startup errors exit `70`, runtime failure exits `1`, cancellation exits `130`,
@@ -132,9 +133,8 @@ Local dry run:
132
133
 
133
134
  ```shell
134
135
  export PIPELINE_TARGET_PATH=/path/to/target/repo
135
- export OISIN_PIPELINE_EVENT_SINK_URL=http://127.0.0.1:3000/api/pipeline/runs/run-uid-1/events
136
- export OISIN_PIPELINE_EVENT_AUTH_TOKEN=dev-token
137
- export OISIN_PIPELINE_RUNNER_PAYLOAD_JSON='{"contractVersion":"1","run":{"id":"run-uid-1","project":"alpha","requestedBy":"@agent"},"repository":{"url":"https://github.com/oisin-ee/pipeline-runner.git","baseBranch":"main"},"task":{"kind":"prompt","prompt":"PIPE-38"},"delivery":{"pullRequest":false}}'
136
+ export PIPELINE_EVENT_API_TOKEN=dev-token
137
+ export OISIN_PIPELINE_RUNNER_PAYLOAD_JSON='{"contractVersion":"1","run":{"id":"run-uid-1","project":"alpha","requestedBy":"@agent"},"repository":{"url":"https://github.com/oisin-ee/pipeline-runner.git","baseBranch":"main"},"task":{"kind":"prompt","prompt":"PIPE-38"},"delivery":{"pullRequest":false},"events":{"url":"http://127.0.0.1:3000/api/pipeline/runner-events","authHeader":"Authorization","authTokenEnv":"PIPELINE_EVENT_API_TOKEN"}}'
138
138
  pipe runner-job
139
139
  ```
140
140
 
@@ -162,10 +162,8 @@ spec:
162
162
  image: ghcr.io/oisin-ee/pipeline-runner:latest
163
163
  env:
164
164
  - name: OISIN_PIPELINE_RUNNER_PAYLOAD_JSON
165
- value: '{"contractVersion":"1","run":{"id":"run-uid-1","project":"alpha"},"repository":{"url":"https://github.com/oisin-ee/pipeline-runner.git","baseBranch":"main","sha":"0123456789abcdef0123456789abcdef01234567"},"task":{"kind":"prompt","prompt":"PIPE-38"},"delivery":{"pullRequest":true}}'
166
- - name: OISIN_PIPELINE_EVENT_SINK_URL
167
- value: https://console.example/api/pipeline/runs/run-uid-1/events
168
- - name: OISIN_PIPELINE_EVENT_AUTH_TOKEN
165
+ value: '{"contractVersion":"1","run":{"id":"run-uid-1","project":"alpha"},"repository":{"url":"https://github.com/oisin-ee/pipeline-runner.git","baseBranch":"main","sha":"0123456789abcdef0123456789abcdef01234567"},"task":{"kind":"prompt","prompt":"PIPE-38"},"delivery":{"pullRequest":true},"events":{"url":"https://console.example/api/pipeline/runner-events","authHeader":"Authorization","authTokenEnv":"PIPELINE_EVENT_API_TOKEN"}}'
166
+ - name: PIPELINE_EVENT_API_TOKEN
169
167
  valueFrom:
170
168
  secretKeyRef:
171
169
  name: pipeline-runner-event-auth
@@ -175,9 +173,9 @@ spec:
175
173
  The runner image is configured in `pipeline-console` as
176
174
  `pipeline.runner.image`. Console runner settings include queue name, service
177
175
  account, CPU/memory requests and limits, active deadline, TTL, backoff limit,
178
- event sink URL, and auth header. The runner-side `OISIN_PIPELINE_EVENT_SINK_URL`
179
- and `OISIN_PIPELINE_EVENT_AUTH_TOKEN` or `PIPELINE_EVENT_API_TOKEN` must match
180
- the console API `PIPELINE_EVENT_API_TOKEN`.
176
+ event sink URL, auth header, and the token environment variable name. The
177
+ runner-side secret mounted at `events.authTokenEnv` must match the console API
178
+ `PIPELINE_EVENT_API_TOKEN`.
181
179
 
182
180
  The runner payload contract lives at
183
181
  `@oisincoveney/pipeline/runner-job-contract`. `pipeline-console` should create
@@ -37,6 +37,11 @@ subpath exports `parseRunnerJobPayload`, `RUNNER_JOB_CONTRACT_VERSION`, and
37
37
  },
38
38
  "delivery": {
39
39
  "pullRequest": true
40
+ },
41
+ "events": {
42
+ "url": "https://console.example/api/pipeline/runner-events",
43
+ "authHeader": "Authorization",
44
+ "authTokenEnv": "PIPELINE_EVENT_API_TOKEN"
40
45
  }
41
46
  }
42
47
  ```
@@ -51,10 +56,12 @@ subpath exports `parseRunnerJobPayload`, `RUNNER_JOB_CONTRACT_VERSION`, and
51
56
  { "kind": "ticket", "id": "PC-27", "path": "tickets/PC-27.md" }
52
57
  ```
53
58
 
54
- Payloads describe repository and task intent only. They must not carry runner
55
- mechanics such as event sink URLs, workflow selectors, entrypoints, workspace
56
- modes, clone credential env names, repository owner/repo duplicates, or secrets.
57
- The runner clones `repository.url` into `/workspace`, checks out a
59
+ Payloads describe run identity, repository/task intent, delivery intent, and the
60
+ Console event destination. They must not carry workflow selectors, entrypoints,
61
+ workspace modes, clone credential env names, repository owner/repo duplicates, or
62
+ secrets. `events.authTokenEnv` names the environment variable containing the
63
+ Console event API token; the token value itself stays in Kubernetes secrets. The
64
+ runner clones `repository.url` into `/workspace`, checks out a
58
65
  `pipeline/<task-or-run>` branch from `repository.sha` when present or
59
66
  `origin/<repository.baseBranch>` otherwise, sets `PIPELINE_TARGET_PATH`, loads the
60
67
  repository `.pipeline` config, generates a task-specific `pipe` schedule, and
@@ -81,19 +88,9 @@ Console-created Jobs are labeled with `kueue.x-k8s.io/queue-name` and
81
88
 
82
89
  ## Event Batches
83
90
 
84
- Event routing is runner environment/config, not payload. Set
85
- `OISIN_PIPELINE_EVENT_SINK_URL` to the append endpoint. The runner sets the
86
- authorization header from `OISIN_PIPELINE_EVENT_AUTH_HEADER` when present,
87
- otherwise `Authorization`, and resolves the bearer token using this lookup order:
88
-
89
- 1. `OISIN_PIPELINE_EVENT_AUTH_TOKEN`
90
- 2. `PIPELINE_EVENT_API_TOKEN`
91
- 3. `/var/run/secrets/kubernetes.io/serviceaccount/token`
92
-
93
- If the event sink URL or token is unavailable, the runner still executes with a
94
- no-op sink. If a configured terminal sink flush fails, the Job exits `70`.
95
-
96
- The runner posts authenticated JSON batches to `OISIN_PIPELINE_EVENT_SINK_URL`:
91
+ Console supplies `events.url`, `events.authHeader`, and `events.authTokenEnv` in
92
+ the runner payload. The runner reads the token from the named environment
93
+ variable and posts progressive authenticated JSON batches to `events.url`:
97
94
 
98
95
  ```json
99
96
  {
@@ -113,9 +110,10 @@ Each event has a strictly increasing integer `sequence`, a string `type`, an
113
110
  `node`, `gate`, `artifact`, `log`, and `finalResult`. The console stores
114
111
  non-reserved top-level fields as event payload.
115
112
 
116
- If payload validation fails but the runner can recover the run identity, it posts
117
- a `runner.schema.validation` warning event when an event sink is configured, then
118
- posts `workflow.finish` with outcome `FAIL`, and exits `64`. If identity is not
113
+ If a configured terminal sink flush fails, the Job exits `70`. If payload
114
+ validation fails but the runner can recover the run identity and event config, it
115
+ posts a `runner.schema.validation` warning event, then posts `workflow.finish`
116
+ with outcome `FAIL`, and exits `64`. If identity or event config is not
119
117
  recoverable, it writes the validation error to stderr and exits `64` without
120
118
  posting events.
121
119
 
package/package.json CHANGED
@@ -99,7 +99,7 @@
99
99
  "prepack": "bun run build:cli"
100
100
  },
101
101
  "type": "module",
102
- "version": "1.18.0",
102
+ "version": "1.18.1",
103
103
  "description": "Config-driven multi-agent pipeline runner for repository work",
104
104
  "main": "./dist/index.js",
105
105
  "types": "./dist/index.d.ts",