@bridge_gpt/mcp-server 0.2.66 → 0.2.68

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 (171) hide show
  1. package/README.md +421 -83
  2. package/build/agent-capabilities/probes.js +15 -5
  3. package/build/agent-launchers/claude-executor-adapter.js +70 -16
  4. package/build/agent-launchers/executor-adapter.js +7 -4
  5. package/build/agents.generated.js +22 -2
  6. package/build/bitbucket-workspace-remote.js +136 -0
  7. package/build/bootstrap-project-identity.js +24 -0
  8. package/build/bounded-wait.js +67 -10
  9. package/build/bridge-permissions.js +829 -0
  10. package/build/claude-settings.js +18 -0
  11. package/build/cli-help.js +21 -0
  12. package/build/command-assets-doctor.js +24 -70
  13. package/build/command-provisioning.js +29 -5
  14. package/build/commands.generated.js +12 -12
  15. package/build/conductor/bridge-api-client.js +857 -1
  16. package/build/conductor/bring-up-facts.js +1 -1
  17. package/build/conductor/command-drift-production.js +92 -0
  18. package/build/conductor/command-drift.js +89 -0
  19. package/build/conductor/doctor.js +72 -29
  20. package/build/conductor/epic-branch-ci-inspection.js +1375 -0
  21. package/build/conductor/epic-implementer-cli.js +98 -28
  22. package/build/conductor/errors.js +4 -3
  23. package/build/conductor/gate-discovery.js +890 -0
  24. package/build/conductor/guided-repair.js +6 -2
  25. package/build/conductor/hook-runtime-qualification.js +1 -1
  26. package/build/conductor/install-doctor.js +15 -3
  27. package/build/conductor/json-output.js +63 -0
  28. package/build/conductor/merge-execution-contract.js +27 -8
  29. package/build/conductor/merge-execution-eligibility.js +3 -2
  30. package/build/conductor/pr-ci-producer.js +1 -1
  31. package/build/conductor/readiness-cli.js +113 -12
  32. package/build/conductor/readiness-sections.js +410 -9
  33. package/build/conductor/readiness.js +388 -33
  34. package/build/conductor/recovery-cli.js +310 -12
  35. package/build/conductor/recovery-operations.js +167 -3
  36. package/build/conductor/repair-contract.js +54 -3
  37. package/build/conductor/repository-workflow-remedy.js +125 -0
  38. package/build/conductor/tools.js +2 -2
  39. package/build/conductor-bundle-artifacts.js +8 -0
  40. package/build/connect-bitbucket-api.js +41 -6
  41. package/build/connect-bitbucket.js +106 -33
  42. package/build/credential-store.js +207 -47
  43. package/build/docs.generated.js +62 -3
  44. package/build/doctor.js +92 -1
  45. package/build/drive-epic-key.js +6 -5
  46. package/build/drive-epic.js +129 -61
  47. package/build/epic-coherence-input.js +2 -1
  48. package/build/epic-coherence-input.test-fixtures.js +4 -3
  49. package/build/epic-implementer-bin.js +1379 -28
  50. package/build/epic-implementer-bundle-cli.js +2 -2
  51. package/build/epic-workarounds-path.js +39 -0
  52. package/build/executor/cli.js +33 -2
  53. package/build/executor/completion-contract.js +66 -10
  54. package/build/executor/completion-supervision.js +4 -0
  55. package/build/executor/deps.js +4 -1
  56. package/build/executor/env.js +19 -0
  57. package/build/executor/gate-qualification-job.js +499 -0
  58. package/build/executor/guarded-fast-forward-push.js +129 -0
  59. package/build/executor/heartbeat.js +1 -1
  60. package/build/executor/http-client.js +20 -0
  61. package/build/executor/integration-job.js +122 -8
  62. package/build/executor/job-errors.js +33 -1
  63. package/build/executor/job-runner.js +813 -87
  64. package/build/executor/likely-tests.js +290 -0
  65. package/build/executor/live-worker-registry.js +1 -1
  66. package/build/executor/observation.js +37 -3
  67. package/build/executor/packaged-recipe.js +106 -0
  68. package/build/executor/permissions.js +115 -28
  69. package/build/executor/platform.js +1 -1
  70. package/build/executor/preflight.js +112 -26
  71. package/build/executor/process-containment.js +36 -12
  72. package/build/executor/process.js +15 -7
  73. package/build/executor/prompt-spec.js +33 -1
  74. package/build/executor/recently-failed-tests-file.js +71 -0
  75. package/build/executor/reconcile-overlap-job.js +41 -23
  76. package/build/executor/required-verification.js +1 -1
  77. package/build/executor/required-work-ledger.js +111 -18
  78. package/build/executor/resume-pre-spawn.js +2 -0
  79. package/build/executor/retirement.js +69 -0
  80. package/build/executor/runner.js +122 -13
  81. package/build/executor/service-unit.js +7 -1
  82. package/build/executor/test-clock.js +15 -0
  83. package/build/executor/types.js +32 -0
  84. package/build/executor/viewer-tabs.js +58 -8
  85. package/build/executor/worker-command.js +23 -7
  86. package/build/executor/worker-diagnostics.js +37 -0
  87. package/build/executor/worker-finalization.js +113 -34
  88. package/build/executor/worker-guard-hook.js +316 -58
  89. package/build/executor/worker-log.js +4 -3
  90. package/build/executor/worker-verification-guidance.js +37 -0
  91. package/build/executor/worktree.js +166 -8
  92. package/build/first-build-advisory.js +97 -0
  93. package/build/generated-assets-advisory.js +14 -0
  94. package/build/generated-assets-catalog.js +66 -0
  95. package/build/generated-assets-context.js +46 -0
  96. package/build/generated-assets-dependencies.js +26 -0
  97. package/build/generated-assets-doctor.js +50 -0
  98. package/build/generated-assets-health.js +65 -0
  99. package/build/generated-assets-host.js +17 -0
  100. package/build/generated-assets-inventory.js +17 -0
  101. package/build/generated-assets-paths.js +60 -0
  102. package/build/generated-assets-publisher.js +133 -0
  103. package/build/generated-assets-remedy.js +25 -0
  104. package/build/generated-assets-repair.js +72 -0
  105. package/build/generated-assets-session.js +71 -0
  106. package/build/generated-assets-test-support.js +35 -0
  107. package/build/index.js +1224 -1054
  108. package/build/init.js +54 -177
  109. package/build/install-bridge-conductor-gate.js +1372 -0
  110. package/build/install-bridge-conductor.js +296 -41
  111. package/build/install-bridge.js +547 -40
  112. package/build/mcp-install-state.js +50 -4
  113. package/build/merge-workflow-install.js +3 -4
  114. package/build/phase-context-git-probe.js +68 -0
  115. package/build/phase-result-artifacts.js +173 -5
  116. package/build/pipeline-utils.js +6 -2
  117. package/build/pipelines.generated.js +34 -160
  118. package/build/plan-execution-ledger.js +2 -32
  119. package/build/plane/alembic-head.js +12 -3
  120. package/build/plane/base-worktree-guard.js +147 -0
  121. package/build/plane/cli.js +217 -17
  122. package/build/plane/code-snapshot.js +468 -0
  123. package/build/plane/defaults.js +48 -3
  124. package/build/plane/endpoint.js +41 -0
  125. package/build/plane/manifest.js +136 -2
  126. package/build/plane/member-roster.js +94 -19
  127. package/build/plane/preflight.js +83 -2
  128. package/build/plane/process-cwd.js +67 -0
  129. package/build/plane/restart.js +542 -0
  130. package/build/plane/shutdown.js +31 -0
  131. package/build/plane/status.js +143 -8
  132. package/build/plane/supervisor.js +586 -179
  133. package/build/plane/types.js +54 -2
  134. package/build/printed-remedy-commands.js +52 -0
  135. package/build/readiness-check.js +1 -1
  136. package/build/readme.generated.js +1 -1
  137. package/build/repair-assets.js +93 -0
  138. package/build/review-generation.js +22 -0
  139. package/build/run-unit-tests-launcher.js +130 -49
  140. package/build/secret-redaction.js +33 -0
  141. package/build/setup-epic.js +152 -22
  142. package/build/sfcc/config.js +9 -0
  143. package/build/sfcc/credentials.js +100 -38
  144. package/build/sfcc/hostname.js +67 -0
  145. package/build/sfcc/permissions.js +17 -13
  146. package/build/sfcc/register.js +1 -1
  147. package/build/sfcc/tool-wrapper.js +39 -43
  148. package/build/sfcc/write-grants.js +17 -11
  149. package/build/sfcc/write-result.js +4 -3
  150. package/build/sfcc/writes-site-preference.js +20 -8
  151. package/build/start-tickets-prereqs.js +70 -16
  152. package/build/start-tickets.js +208 -36
  153. package/build/tool-error-envelope.js +61 -0
  154. package/build/tool-surface-gating.js +36 -0
  155. package/build/upgrade-cli.js +55 -1
  156. package/build/version.generated.js +3 -3
  157. package/build/visual-diff.js +22 -1
  158. package/build/worker-guard-hook-bin.js +4 -6
  159. package/build/worker-guard-hook-main.js +47 -0
  160. package/build/worktree-core.js +145 -6
  161. package/docs/EPIC-IMPLEMENTER-INSTALL.md +867 -0
  162. package/docs/EPIC-IMPLEMENTER.md +728 -0
  163. package/docs/install/mcp-tool-integrations.md +24 -15
  164. package/docs/install/sfcc-integration.md +12 -4
  165. package/package.json +3 -3
  166. package/pipelines/greenfield-setup.json +4 -128
  167. package/pipelines/implement-ticket.json +3 -2
  168. package/pipelines/plan-epic.json +0 -5
  169. package/pipelines/review-ticket.json +1 -1
  170. package/docs/CONDUCTOR.md +0 -605
  171. package/pipelines/idea-to-pr.json +0 -49
@@ -60,6 +60,15 @@
60
60
  * reports its head, publication is `unknown`
61
61
  * (`WorkerFinalizationPublicationUnverified`), never `ok`.
62
62
  *
63
+ * BAPI-1357: "absent" and "could not be checked" are different facts. Only the
64
+ * origin lookup's authoritative "no matching ref" (`git ls-remote --exit-code`
65
+ * exit code 2), or having no expected branch at all, is reported as
66
+ * `WorkerFinalizationMissingRemoteBranchAndPr`; a thrown command, an expired
67
+ * call bound, any other exit, or unusable output leaves publication unknown and is
68
+ * `WorkerFinalizationOriginUnverifiable`, which the server treats as transient.
69
+ * Both keep the `clean_exit` classification the process earned. No-expected-branch
70
+ * and absent-on-origin are still one cause, and may be refined later.
71
+ *
63
72
  * This check is deliberately fail-CLOSED, unlike the BAPI-586 base check it now
64
73
  * shares a lookup with. "The PR could not be verified" and "there is no PR" are
65
74
  * the same thing from the contract's point of view: neither is evidence that the
@@ -67,7 +76,7 @@
67
76
  * this ticket removes. The reconciler stays the decision-maker — the executor
68
77
  * only reports the observation (R14 rule 3).
69
78
  */
70
- import { ReconcileOverlapPushUnfinalized, secretFreeErrorMessage, WorkerFinalizationMissingRemoteBranchAndPr, WorkerFinalizationPrBaseMismatch, WorkerFinalizationPrNotAttached, WorkerFinalizationPublicationUnverified, WorkerFinalizationSavedButUnfinalized, } from "./job-errors.js";
79
+ import { ReconcileOverlapPushUnfinalized, WorkerFinalizationMissingRemoteBranchAndPr, WorkerFinalizationOriginUnverifiable, WorkerFinalizationPrBaseMismatch, WorkerFinalizationPrNotAttached, WorkerFinalizationPublicationUnverified, WorkerFinalizationSavedButUnfinalized, } from "./job-errors.js";
71
80
  import { isImplementationStyleJobType } from "./job-types.js";
72
81
  /** A full, lower-case 40-hex commit SHA. */
73
82
  const FULL_SHA_RE = /^[0-9a-f]{40}$/;
@@ -129,40 +138,56 @@ function parseLsRemoteHeadSha(stdout, expectedRef) {
129
138
  }
130
139
  return null;
131
140
  }
141
+ /** `git ls-remote --exit-code` exits with this status when no ref matched. */
142
+ const LS_REMOTE_NO_MATCHING_REF_EXIT_CODE = 2;
132
143
  /**
133
- * Resolve the origin branch's authoritative current tip SHA (normalized), or
134
- * `null` if the ref is absent. Uses `git ls-remote` against the exact normalized
135
- * ref — never a local `origin/<branch>` remote-tracking ref, which can be stale
136
- * on a recovery worktree. A non-zero exit is treated as "branch not found"
137
- * without copying raw stderr into diagnostics.
144
+ * Resolve the origin branch's authoritative current tip. Uses `git ls-remote`
145
+ * against the exact normalized ref — never a local `origin/<branch>`
146
+ * remote-tracking ref, which can be stale on a recovery worktree.
147
+ *
148
+ * Only exit code 2 (`--exit-code`'s "no matching ref") is `absent`. A thrown
149
+ * command, an expired call bound, every other non-zero exit, and an exit-zero
150
+ * response with no usable SHA for the exact ref are all `unverifiable`: none of
151
+ * them is evidence the branch is missing. Neither stderr nor a thrown error's
152
+ * message is read or copied anywhere.
138
153
  */
139
154
  export async function resolveOriginBranchSha(runCommand, worktreePath, branch, bound) {
140
155
  const normalizedRef = normalizeBranchRef(branch);
141
156
  if (callExpired(bound))
142
- return null;
143
- const result = await runCommand("git", ["ls-remote", "--exit-code", "--heads", "origin", normalizedRef], callOptions(worktreePath, bound));
157
+ return { state: "unverifiable" };
158
+ let result;
159
+ try {
160
+ result = await runCommand("git", ["ls-remote", "--exit-code", "--heads", "origin", normalizedRef], callOptions(worktreePath, bound));
161
+ }
162
+ catch {
163
+ return { state: "unverifiable" };
164
+ }
165
+ if (result.exitCode === LS_REMOTE_NO_MATCHING_REF_EXIT_CODE)
166
+ return { state: "absent" };
144
167
  if (result.exitCode !== 0)
145
- return null;
146
- return parseLsRemoteHeadSha(result.stdout, normalizedRef);
168
+ return { state: "unverifiable" };
169
+ const sha = parseLsRemoteHeadSha(result.stdout, normalizedRef);
170
+ return sha === null ? { state: "unverifiable" } : { state: "found", sha };
147
171
  }
148
172
  /**
149
173
  * Repeatedly resolve the authoritative origin tip until it either satisfies
150
174
  * finalization or the bounded retry budget is exhausted. Stops early (no further
151
175
  * lookups) when the origin tip matches the worker HEAD, or when the branch exists
152
176
  * and the worker HEAD is unavailable (degraded telemetry, existence-only). Retries
153
- * when the tip is `null` (branch not yet visible) or, with a known HEAD, does not
154
- * yet match. Returns the LAST authoritative observation — the caller decides
155
- * loud-failure from that final value, so true negatives are preserved.
177
+ * an observed absence, a found tip that does not yet match a known HEAD, and an
178
+ * unverifiable read (a later read may succeed). Returns the LAST observation with
179
+ * its state intact — an unverifiable read is never turned into an absence here,
180
+ * so the caller decides loud-failure from what was actually established.
156
181
  */
157
182
  async function resolveOriginBranchShaForFinalization(runCommand, worktreePath, branch, trimmedHeadSha, attempts, retryDelayMs, sleep, bound) {
158
183
  const total = Math.max(1, attempts);
159
- let remoteSha = null;
184
+ let lookup = { state: "unverifiable" };
160
185
  for (let attempt = 0; attempt < total; attempt++) {
161
- remoteSha = await resolveOriginBranchSha(runCommand, worktreePath, branch, bound?.());
162
- if (remoteSha !== null) {
186
+ lookup = await resolveOriginBranchSha(runCommand, worktreePath, branch, bound?.());
187
+ if (lookup.state === "found") {
163
188
  // Existence-only success when HEAD is unknown; exact-match success otherwise.
164
- if (!trimmedHeadSha || remoteSha === trimmedHeadSha) {
165
- return { sha: remoteSha, attemptsUsed: attempt + 1 };
189
+ if (!trimmedHeadSha || lookup.sha === trimmedHeadSha) {
190
+ return { lookup, attemptsUsed: attempt + 1 };
166
191
  }
167
192
  }
168
193
  if (attempt < total - 1)
@@ -170,7 +195,7 @@ async function resolveOriginBranchShaForFinalization(runCommand, worktreePath, b
170
195
  }
171
196
  // `attemptsUsed` is reported even on failure so the caller can tell a
172
197
  // first-try answer from one that needed the settling window (BAPI-862).
173
- return { sha: remoteSha, attemptsUsed: total };
198
+ return { lookup, attemptsUsed: total };
174
199
  }
175
200
  /** The bounded, public projection finalization asks the provider for. */
176
201
  const PR_VIEW_JSON_FIELDS = "number,url,baseRefName,body,headRefOid";
@@ -385,12 +410,19 @@ function publicationUnverifiedFailure(job, branch, workerHeadSha, detail) {
385
410
  };
386
411
  }
387
412
  /**
388
- * `detail` describes a state with NO evidence any work reached origin (branch
389
- * unresolved, branch absent from origin, or the origin lookup itself failed).
413
+ * `detail` describes a state with NO evidence any work reached origin, and is
414
+ * used for exactly two cases: no expected branch to verify, or a branch the
415
+ * origin lookup OBSERVED absent (exit code 2). An origin lookup that merely
416
+ * failed is {@link originUnverifiableFailure}, never this. Those two cases stay
417
+ * one cause for now and may be refined later.
390
418
  * `hasPrUrl` only changes the wording — a PR existing is never treated as
391
419
  * evidence of a push, so the message must not claim "no PR URL" when one was
392
420
  * actually present (that would be false and would mislead the operator reading
393
421
  * it toward the wrong recovery step).
422
+ *
423
+ * The classification is `clean_exit` because the worker process did exit
424
+ * cleanly; the finalization failure rides in the error kind, not in a rewritten
425
+ * exit (the same rule the other finalization failures follow).
394
426
  */
395
427
  function missingBranchAndPrFailure(job, detail, hasPrUrl) {
396
428
  const label = job.ticket_key ? `${job.ticket_key} (job ${job.id})` : `job ${job.id}`;
@@ -398,7 +430,23 @@ function missingBranchAndPrFailure(job, detail, hasPrUrl) {
398
430
  return {
399
431
  error_kind: WorkerFinalizationMissingRemoteBranchAndPr,
400
432
  error_message: `${label} exited cleanly but ${prefix} ${detail}`,
401
- classification: "crashed",
433
+ classification: "clean_exit",
434
+ };
435
+ }
436
+ /**
437
+ * BAPI-1357: the origin lookup could not be trusted, so the branch was neither
438
+ * seen nor observed missing. The wording is fixed and bounded: it names only the
439
+ * ticket, job and branch (public identifiers), never a command, stderr, a thrown
440
+ * error's text, a host, or a credential, and it does not claim the branch is
441
+ * absent. The server treats this kind as transient.
442
+ */
443
+ function originUnverifiableFailure(job, branch) {
444
+ const label = job.ticket_key ? `${job.ticket_key} (job ${job.id})` : `job ${job.id}`;
445
+ return {
446
+ error_kind: WorkerFinalizationOriginUnverifiable,
447
+ error_message: `${label} exited cleanly, but whether branch '${branch}' reached origin could not be ` +
448
+ `verified. The branch was not observed to be missing; publication is unknown for this attempt.`,
449
+ classification: "clean_exit",
402
450
  };
403
451
  }
404
452
  /**
@@ -411,14 +459,14 @@ function missingBranchAndPrFailure(job, detail, hasPrUrl) {
411
459
  * existing convention); the full 40-character origin SHA is carried in the
412
460
  * structured `last_commit_sha` field so nothing has to re-derive it from prose.
413
461
  */
414
- function savedButUnfinalizedFailure(job, branch, originSha, workerHeadSha) {
462
+ function savedButUnfinalizedFailure(job, branch, originSha, workerHeadSha, publicationAttempted = false) {
415
463
  const label = job.ticket_key ? `${job.ticket_key} (job ${job.id})` : `job ${job.id}`;
416
464
  return {
417
465
  error_kind: WorkerFinalizationSavedButUnfinalized,
418
466
  error_message: `${label} exited cleanly, but origin branch '${branch}' is at ${originSha.slice(0, 12)}, ` +
419
- `which does not match this worker's HEAD ${workerHeadSha.slice(0, 12)} — the worker's latest ` +
420
- `commit was not pushed. Work already on origin at this SHA is recoverable: resume/finalize ` +
421
- `from '${branch}' instead of re-running from scratch.`,
467
+ `which does not match this worker's HEAD ${workerHeadSha.slice(0, 12)}. The newer commit ` +
468
+ `is retained only in the local worktree and was not pushed. Automatic publication ` +
469
+ `${publicationAttempted ? "was refused" : "was unavailable or not attempted"}; preserve the worktree for recovery.`,
422
470
  classification: "crashed",
423
471
  last_commit_sha: originSha,
424
472
  };
@@ -525,19 +573,50 @@ export async function validateWorkerFinalization(input) {
525
573
  try {
526
574
  origin = await resolveOriginBranchShaForFinalization(runCommand, worktreePath, trimmedBranch, trimmedHeadSha, attempts, retryDelayMs, sleep, bound);
527
575
  }
528
- catch (err) {
529
- return {
530
- ok: false,
531
- failure: missingBranchAndPrFailure(job, `branch '${trimmedBranch}' could not be verified on origin: ${secretFreeErrorMessage(err)}`, hasPrUrl),
532
- };
576
+ catch {
577
+ // BAPI-1357: nothing thrown here says anything about the branch, and its text
578
+ // is never rendered — the fixed unverifiable outcome is the whole report.
579
+ return { ok: false, failure: originUnverifiableFailure(job, trimmedBranch) };
533
580
  }
534
- const remoteSha = origin.sha;
535
- if (remoteSha === null) {
581
+ // BAPI-1357: only an authoritative "no matching ref" is an absence. A lookup
582
+ // that could not be trusted stays unknown and never funds the deterministic
583
+ // missing-branch failure.
584
+ if (origin.lookup.state === "unverifiable") {
585
+ return { ok: false, failure: originUnverifiableFailure(job, trimmedBranch) };
586
+ }
587
+ if (origin.lookup.state === "absent") {
536
588
  return {
537
589
  ok: false,
538
590
  failure: missingBranchAndPrFailure(job, `branch '${trimmedBranch}' is not on origin`, hasPrUrl),
539
591
  };
540
592
  }
593
+ let publicationAttempted = false;
594
+ if (trimmedHeadSha && origin.lookup.sha !== trimmedHeadSha && job.job_type !== "reconcile_overlap" && input.publishRetainedHead) {
595
+ publicationAttempted = true;
596
+ let pushed;
597
+ try {
598
+ pushed = await input.publishRetainedHead();
599
+ }
600
+ catch {
601
+ pushed = { status: "refused", reason: "remote_rejected" };
602
+ }
603
+ // The original lease is never replaced after an intermediate worker push.
604
+ // A timeout/rejected lease may have landed elsewhere; only the ordinary
605
+ // authoritative origin and PR contracts can accept that state, without
606
+ // manufacturing a wrapper publication fact.
607
+ if (pushed.status === "published" || pushed.reason === "lease_rejected" || pushed.reason === "timeout") {
608
+ origin = await resolveOriginBranchShaForFinalization(runCommand, worktreePath, trimmedBranch, trimmedHeadSha, 1, retryDelayMs, sleep, bound);
609
+ if (origin.lookup.state !== "found")
610
+ return { ok: false, failure: originUnverifiableFailure(job, trimmedBranch) };
611
+ pr = await resolvePrForFinalization(runCommand, worktreePath, trimmedBranch, bound());
612
+ const refreshedBase = evaluatePrBase(job, pr, expectedBase);
613
+ if (refreshedBase)
614
+ return { ok: false, failure: refreshedBase };
615
+ }
616
+ }
617
+ if (origin.lookup.state !== "found")
618
+ return { ok: false, failure: originUnverifiableFailure(job, trimmedBranch) };
619
+ const remoteSha = origin.lookup.sha;
541
620
  // BAPI-762: an authoritative origin tip that does not match the worker's HEAD
542
621
  // is positive evidence of RECOVERABLE work — distinct from the sub-cases above,
543
622
  // which have no evidence any work reached origin at all. This is the only
@@ -549,7 +628,7 @@ export async function validateWorkerFinalization(input) {
549
628
  ok: false,
550
629
  failure: job.job_type === "reconcile_overlap"
551
630
  ? reconcilePushUnfinalizedFailure(job, trimmedBranch, remoteSha, trimmedHeadSha)
552
- : savedButUnfinalizedFailure(job, trimmedBranch, remoteSha, trimmedHeadSha),
631
+ : savedButUnfinalizedFailure(job, trimmedBranch, remoteSha, trimmedHeadSha, publicationAttempted),
553
632
  };
554
633
  }
555
634
  // BAPI-862: the work is provably ON ORIGIN. That was the whole of the success