@akagilnc/pi-workflow-roles 0.1.2052 → 0.1.2054

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.
@@ -16380,18 +16380,21 @@ async function writeRoleInvocationLedger(source, role, effectiveModel) {
16380
16380
  "utf8"
16381
16381
  );
16382
16382
  }
16383
- async function recordEffectiveInvocationModel(runDirectory, model) {
16383
+ async function recordEffectiveInvocationModel(runDirectory, model, engine) {
16384
16384
  const ledgerPath = join6(runDirectory, "invocation.json");
16385
16385
  const current = JSON.parse(await readFile4(ledgerPath, "utf8"));
16386
- const next = {
16387
- ...current,
16388
- provider: model.provider,
16389
- model: model.model
16390
- };
16391
- if (model.thinking === void 0) {
16392
- delete next.thinking;
16393
- } else {
16394
- next.thinking = model.thinking;
16386
+ const next = { ...current };
16387
+ if (model !== void 0) {
16388
+ next.provider = model.provider;
16389
+ next.model = model.model;
16390
+ if (model.thinking === void 0) {
16391
+ delete next.thinking;
16392
+ } else {
16393
+ next.thinking = model.thinking;
16394
+ }
16395
+ }
16396
+ if (engine !== void 0) {
16397
+ next.engine = engine;
16395
16398
  }
16396
16399
  await writeFile2(
16397
16400
  ledgerPath,
@@ -18629,9 +18632,13 @@ async function markRunAdmitted(admitted) {
18629
18632
  ...admitted.role === "coder" || admitted.role === "fixer" ? { phase: admitted.phase } : {}
18630
18633
  });
18631
18634
  }
18632
- async function markRunRunning(runDirectory, effectiveModel) {
18633
- if (effectiveModel !== void 0) {
18634
- await recordEffectiveInvocationModel(runDirectory, effectiveModel);
18635
+ async function markRunRunning(runDirectory, effectiveModel, effectiveEngine) {
18636
+ if (effectiveModel !== void 0 || effectiveEngine !== void 0) {
18637
+ await recordEffectiveInvocationModel(
18638
+ runDirectory,
18639
+ effectiveModel,
18640
+ effectiveEngine
18641
+ );
18635
18642
  }
18636
18643
  const current = await readRoleRunState(runDirectory);
18637
18644
  if (current === void 0) {
@@ -23742,7 +23749,7 @@ async function presentControlledFailure6(admitted, failureInput, io) {
23742
23749
  };
23743
23750
  }
23744
23751
  async function dispatchAdmittedJudge(input) {
23745
- const { admitted, env, io, extraArgs, lease } = input;
23752
+ const { admitted, env, io, extraArgs, lease, effectiveEngine } = input;
23746
23753
  try {
23747
23754
  const missingCredential = missingCredentialPreDispatchFailure(
23748
23755
  env.model,
@@ -23755,7 +23762,11 @@ async function dispatchAdmittedJudge(input) {
23755
23762
  io
23756
23763
  );
23757
23764
  }
23758
- await markRunRunning(admitted.runDirectory, env.model);
23765
+ await markRunRunning(
23766
+ admitted.runDirectory,
23767
+ env.model,
23768
+ effectiveEngine
23769
+ );
23759
23770
  await clearTypedProviderHttpObservation(admitted.runDirectory);
23760
23771
  const childEnv = {
23761
23772
  ...process.env,
@@ -23909,7 +23920,9 @@ async function runPublicJudge(argv, env, io, parseJudgeArgv2) {
23909
23920
  },
23910
23921
  io,
23911
23922
  extraArgs,
23912
- lease
23923
+ lease,
23924
+ // #358: only initial Judge dispatch records mechanical engine provenance.
23925
+ ...env.engine === void 0 ? {} : { effectiveEngine: env.engine }
23913
23926
  });
23914
23927
  }
23915
23928
  async function runPublicResume(argv, env, io) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@akagilnc/pi-workflow-roles",
3
- "version": "0.1.2052",
3
+ "version": "0.1.2054",
4
4
  "description": "Soul-bound workflow roles for Pi",
5
5
  "type": "module",
6
6
  "license": "Apache-2.0",
@@ -239,28 +239,35 @@ async function writeRoleInvocationLedger(
239
239
  }
240
240
 
241
241
  /**
242
- * Merge the effective launch model onto the existing invocation identity page
243
- * (resume / temporary override path — same field shape as admission write).
242
+ * Merge the effective launch model (and optional initial engine) onto the
243
+ * existing invocation identity page (resume / temporary override path — same
244
+ * field shape as admission write).
244
245
  * Bare model clears any prior thinking key so absence stays honest.
246
+ * Engine is write-if-present only: undefined leaves any existing key untouched
247
+ * (resume model merge must not erase initial mechanical provenance).
245
248
  */
246
249
  export async function recordEffectiveInvocationModel(
247
250
  runDirectory: string,
248
- model: InvocationEffectiveModel,
251
+ model?: InvocationEffectiveModel,
252
+ engine?: string,
249
253
  ): Promise<void> {
250
254
  const ledgerPath = join(runDirectory, "invocation.json");
251
255
  const current = JSON.parse(await readFile(ledgerPath, "utf8")) as Record<
252
256
  string,
253
257
  unknown
254
258
  >;
255
- const next: Record<string, unknown> = {
256
- ...current,
257
- provider: model.provider,
258
- model: model.model,
259
- };
260
- if (model.thinking === undefined) {
261
- delete next.thinking;
262
- } else {
263
- next.thinking = model.thinking;
259
+ const next: Record<string, unknown> = { ...current };
260
+ if (model !== undefined) {
261
+ next.provider = model.provider;
262
+ next.model = model.model;
263
+ if (model.thinking === undefined) {
264
+ delete next.thinking;
265
+ } else {
266
+ next.thinking = model.thinking;
267
+ }
268
+ }
269
+ if (engine !== undefined) {
270
+ next.engine = engine;
264
271
  }
265
272
  await writeFile(
266
273
  ledgerPath,
@@ -254,12 +254,17 @@ async function dispatchAdmittedJudge(input: {
254
254
  io: CliIo;
255
255
  extraArgs: string[];
256
256
  lease: RunWriterLease;
257
+ /**
258
+ * Mechanical engine provenance for initial Judge dispatch only.
259
+ * Explicit — never read from env.engine here, so resume cannot rewrite it.
260
+ */
261
+ effectiveEngine?: string;
257
262
  }): Promise<{
258
263
  exitCode: number;
259
264
  admitted: AdmittedJudgeInvocation;
260
265
  terminal?: TerminalResult;
261
266
  }> {
262
- const { admitted, env, io, extraArgs, lease } = input;
267
+ const { admitted, env, io, extraArgs, lease, effectiveEngine } = input;
263
268
  try {
264
269
  // Fail closed at the public credential seam before model dispatch: missing
265
270
  // selected-provider auth must not be washed by ambient keys or zero-exit runs.
@@ -274,7 +279,11 @@ async function dispatchAdmittedJudge(input: {
274
279
  io,
275
280
  );
276
281
  }
277
- await markRunRunning(admitted.runDirectory, env.model);
282
+ await markRunRunning(
283
+ admitted.runDirectory,
284
+ env.model,
285
+ effectiveEngine,
286
+ );
278
287
  // Attempt-scoped observation: drop any prior dispatch's 429 evidence so only
279
288
  // the current initial/resume attempt can qualify v1 resume.
280
289
  await clearTypedProviderHttpObservation(admitted.runDirectory);
@@ -459,6 +468,8 @@ export async function runPublicJudge(
459
468
  io,
460
469
  extraArgs,
461
470
  lease,
471
+ // #358: only initial Judge dispatch records mechanical engine provenance.
472
+ ...(env.engine === undefined ? {} : { effectiveEngine: env.engine }),
462
473
  });
463
474
  }
464
475
 
@@ -230,15 +230,23 @@ export async function markRunAdmitted(
230
230
 
231
231
  /**
232
232
  * Shared dispatch execution seam: record the effective launch model (initial or
233
- * resume override) onto invocation.json when known, then transition to running.
233
+ * resume override) and optional initial effective engine onto invocation.json
234
+ * when known, then transition to running.
234
235
  * Role runners must not coordinate lifecycle ledger writes themselves.
236
+ * Engine is write-if-present only — callers that omit it (resume / non-Judge)
237
+ * never touch the engine key.
235
238
  */
236
239
  export async function markRunRunning(
237
240
  runDirectory: string,
238
241
  effectiveModel?: InvocationEffectiveModel,
242
+ effectiveEngine?: string,
239
243
  ): Promise<void> {
240
- if (effectiveModel !== undefined) {
241
- await recordEffectiveInvocationModel(runDirectory, effectiveModel);
244
+ if (effectiveModel !== undefined || effectiveEngine !== undefined) {
245
+ await recordEffectiveInvocationModel(
246
+ runDirectory,
247
+ effectiveModel,
248
+ effectiveEngine,
249
+ );
242
250
  }
243
251
  const current = await readRoleRunState(runDirectory);
244
252
  if (current === undefined) {