@bridge_gpt/mcp-server 0.2.58 → 0.2.59

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 (86) hide show
  1. package/README.md +105 -109
  2. package/build/agent-registry.js +15 -0
  3. package/build/agent-utils.js +16 -8
  4. package/build/claude-user-config-doctor.js +1 -35
  5. package/build/codex-bridge-profile.js +1 -1
  6. package/build/commands.generated.js +5 -6
  7. package/build/conductor/bridge-api-client.js +149 -0
  8. package/build/conductor/bring-up-facts.js +1 -1
  9. package/build/conductor/claude-hook.js +16 -16
  10. package/build/conductor/doctor.js +24 -19
  11. package/build/conductor/epic-implementer-cli.js +38 -5
  12. package/build/conductor/epic-reconcile.js +1 -1
  13. package/build/conductor/epic-runtime.js +10 -10
  14. package/build/conductor/errors.js +3 -3
  15. package/build/conductor/file-scope-guard.js +4 -4
  16. package/build/conductor/git-ci-types.js +1 -1
  17. package/build/conductor/git-inspection.js +2 -2
  18. package/build/conductor/install-doctor.js +6 -6
  19. package/build/conductor/merge-ledger.js +2 -2
  20. package/build/conductor/pr-ci-producer.js +6 -6
  21. package/build/conductor/pr-review-producer.js +2 -2
  22. package/build/conductor/producer-ledger.js +2 -0
  23. package/build/conductor/readiness-sections.js +7 -7
  24. package/build/conductor/readiness.js +2 -2
  25. package/build/conductor/recovery-cli.js +243 -12
  26. package/build/conductor/recovery-operations.js +56 -4
  27. package/build/conductor/repair-contract.js +38 -4
  28. package/build/conductor/spec-review-producer.js +6 -6
  29. package/build/conductor/store.js +10 -10
  30. package/build/conductor/supervisor-config.js +14 -14
  31. package/build/conductor/supervisor-ledger.js +2 -2
  32. package/build/conductor/supervisor-message-relay.js +2 -2
  33. package/build/conductor/worker-ledger-cli.js +19 -19
  34. package/build/conductor-bundle-artifacts.js +2 -2
  35. package/build/doctor.js +16 -294
  36. package/build/drive-epic.js +65 -71
  37. package/build/epic-implementer-bin.js +22 -17
  38. package/build/epic-implementer-claude-hook-bin.js +4 -2
  39. package/build/epic-implementer-env.js +155 -0
  40. package/build/epic-integration-pr.js +2 -2
  41. package/build/epic-shared/bridge-client.js +773 -0
  42. package/build/epic-shared/cut-protocol.js +392 -0
  43. package/build/executor/env.js +19 -8
  44. package/build/executor/heartbeat.js +1 -1
  45. package/build/executor/job-errors.js +3 -3
  46. package/build/executor/job-runner.js +1 -1
  47. package/build/executor/merge-job.js +35 -3
  48. package/build/executor/observation.js +1 -1
  49. package/build/executor/preflight.js +1 -1
  50. package/build/executor/prompt-spec.js +1 -1
  51. package/build/executor/reconcile-overlap-job.js +10 -130
  52. package/build/executor/reconcile-overlap-types.js +1 -1
  53. package/build/executor/runner.js +1 -1
  54. package/build/implement-epic/cli.js +1 -1
  55. package/build/index.js +181 -218
  56. package/build/init.js +20 -28
  57. package/build/install-bridge-conductor.js +7 -7
  58. package/build/install-bridge.js +199 -7
  59. package/build/mcp-host-entry-adapter.js +6 -0
  60. package/build/mcp-host-targets.js +2 -0
  61. package/build/mcp-invoke.js +5 -5
  62. package/build/mcp-profile.js +2 -2
  63. package/build/mcp-provisioning.js +2 -2
  64. package/build/mcp-server-invocation.js +3 -3
  65. package/build/merge-pull-request.js +15 -0
  66. package/build/model-routing-host.js +25 -0
  67. package/build/model-routing-preferences.js +99 -0
  68. package/build/pipelines.generated.js +9 -9
  69. package/build/plan-epic-implementer-eligibility.js +215 -0
  70. package/build/plan-execution-ledger.js +8 -0
  71. package/build/plane/member-roster.js +5 -5
  72. package/build/plane/supervisor.js +1 -1
  73. package/build/plane/types.js +5 -5
  74. package/build/readiness-check.js +1 -1
  75. package/build/readme.generated.js +1 -1
  76. package/build/review-tickets.js +4 -4
  77. package/build/setup-epic.js +8 -8
  78. package/build/start-tickets-conductor.js +32 -32
  79. package/build/start-tickets-prereqs.js +4 -9
  80. package/build/start-tickets.js +475 -91
  81. package/build/version.generated.js +3 -3
  82. package/docs/CONDUCTOR.md +69 -18
  83. package/docs/install/mcp-tool-integrations.md +2 -1
  84. package/package.json +2 -2
  85. package/pipelines/implement-ticket.json +1 -1
  86. package/pipelines/plan-epic.json +2 -2
@@ -12,8 +12,8 @@
12
12
  *
13
13
  * Optionally supports a supervisor-driven epic-dispatch path: when an
14
14
  * `EpicDispatchIdentity` is threaded through `ReviewTicketsOptions.epic`, each
15
- * spawned tab receives an epic-identity env block (BAPI_CONDUCTOR_EPIC_KEY /
16
- * BAPI_CONDUCTOR_EPIC_RUN_ID / BAPI_CONDUCTOR_PLAN_VERSION / BAPI_CONDUCTOR_RUN_ID)
15
+ * spawned tab receives an epic-identity env block (BAPI_EPIC_IMPLEMENTER_EPIC_KEY /
16
+ * BAPI_EPIC_IMPLEMENTER_EPIC_RUN_ID / BAPI_EPIC_IMPLEMENTER_PLAN_VERSION / BAPI_EPIC_IMPLEMENTER_RUN_ID)
17
17
  * and dispatch is made idempotent via an injected `claimEpicDispatch` callback.
18
18
  * This path is worktree-free and base-branch-free; the human CLI path leaves
19
19
  * `epic` unset and retains byte-for-byte identical behavior.
@@ -518,7 +518,7 @@ export function buildReviewPlanRows(deps, options, agent, status, overrides = {}
518
518
  if (options.epic) {
519
519
  const mint = overrides.mintRunId ?? mintStartTicketsRunId;
520
520
  runId = mint([key]);
521
- const env = { ...buildEpicIdentityEnv(options.epic), BAPI_CONDUCTOR_RUN_ID: runId };
521
+ const env = { ...buildEpicIdentityEnv(options.epic), BAPI_EPIC_IMPLEMENTER_RUN_ID: runId };
522
522
  command = injectConductorEnvIntoShellCommand(deps.platform, baseCommand, env);
523
523
  }
524
524
  return {
@@ -599,7 +599,7 @@ export async function orchestrateReviewTickets(deps, options, overrides = {}) {
599
599
  if (options.epic) {
600
600
  const mint = overrides.mintRunId ?? mintStartTicketsRunId;
601
601
  runId = mint([key]);
602
- const env = { ...buildEpicIdentityEnv(options.epic), BAPI_CONDUCTOR_RUN_ID: runId };
602
+ const env = { ...buildEpicIdentityEnv(options.epic), BAPI_EPIC_IMPLEMENTER_RUN_ID: runId };
603
603
  shellCommand = injectConductorEnvIntoShellCommand(deps.platform, baseShellCommand, env);
604
604
  if (options.epic.dispatch_key) {
605
605
  if (!overrides.claimEpicDispatch) {
@@ -89,8 +89,8 @@ import { validateBranchName } from "./base-ref.js";
89
89
  // typed clients the pilot already has are the v2 path's clients too, so neither
90
90
  // conductor can drift on a field name or an endpoint shape. No MCP tool, no
91
91
  // input-schema field, and no description changes.
92
- import { getConfigFieldBaseBranch, getIndexScopeLifecycle, getParseStatus, } from "./implement-epic/bridge-client.js";
93
- import { boundScopeLifecycleLabel, createExecFileRunCommand, ensureCommitResolvableLocally, normalizeCommitSha, performExactIndexScopeCut, pollIndexScopeLifecycle, readRemoteBranchHead, runGit, SCOPE_BOOTSTRAP_POLL_INTERVAL_MS, SCOPE_LIFECYCLE_LABELS, } from "./implement-epic/cut-protocol.js";
92
+ import { getConfigFieldBaseBranch, getIndexScopeLifecycle, getParseStatus, } from "./epic-shared/bridge-client.js";
93
+ import { boundScopeLifecycleLabel, createExecFileRunCommand, ensureCommitResolvableLocally, normalizeCommitSha, performExactIndexScopeCut, pollIndexScopeLifecycle, readRemoteBranchHead, runGit, SCOPE_BOOTSTRAP_POLL_INTERVAL_MS, SCOPE_LIFECYCLE_LABELS, } from "./epic-shared/cut-protocol.js";
94
94
  import { hashPlan } from "./conductor/plan.js";
95
95
  import { BRING_UP_REFUSAL_MESSAGES, firstBringUpRefusal, } from "./conductor/bring-up-facts.js";
96
96
  import { MCP_PACKAGE_NAME } from "./mcp-identity.js";
@@ -111,7 +111,7 @@ export const SETUP_EPIC_UNATTENDED_POSTURE = "unattended";
111
111
  /**
112
112
  * The server's stable error code for an unattended-posture refusal (BAPI-734).
113
113
  *
114
- * Mirrors `api.library.epic_conductor.unattended_posture.UNATTENDED_POSTURE_REFUSED_CODE`.
114
+ * Mirrors `api.library.epic_implementer.unattended_posture.UNATTENDED_POSTURE_REFUSED_CODE`.
115
115
  * Matched by EQUALITY on the structured `error_code`, never by searching the
116
116
  * message text: the message is prose that may be rewritten, the code is the
117
117
  * contract.
@@ -239,7 +239,7 @@ export function getSetupEpicUsage() {
239
239
  " 10799; remediate / ci_fix 3599; rebase / smoke 2699;",
240
240
  " merge 1799); the server rejects a higher value with a",
241
241
  " 422 naming the offending field. Full table:",
242
- " docs/claude/epic-conductor-v2-operator-runbook.md §4.",
242
+ " docs/claude/epic-implementer-v2-operator-runbook.md §4.",
243
243
  " --replace-policy Authorize replacing a LIVE run's stored policy with the",
244
244
  " policy file, as a complete replacement. Without it, a",
245
245
  " divergent policy on a reused run is refused with a",
@@ -1130,7 +1130,7 @@ export function resolveFeatureBranchSelection(opts, planNodeCount, policyDeclare
1130
1130
  * refused every unattended run, its own named remedy included.
1131
1131
  *
1132
1132
  * The reason CODES are the server's bounded vocabulary, spelled exactly as
1133
- * `api/library/epic_conductor/unattended_posture.py` spells them. The client adds
1133
+ * `api/library/epic_implementer/unattended_posture.py` spells them. The client adds
1134
1134
  * remediation TEXT around them and invents no aliases — an alias would drift from
1135
1135
  * the server's refusal the first time either side was edited, and an operator
1136
1136
  * comparing a CLI message with an API response would have no way to tell they
@@ -1145,7 +1145,7 @@ export function resolveFeatureBranchSelection(opts, planNodeCount, policyDeclare
1145
1145
  * Does this policy declare a notify webhook the server would probe?
1146
1146
  *
1147
1147
  * BAPI-1102. The shape check mirrors `_extract_webhook_url` in
1148
- * `api/library/epic_conductor/webhook_verification.py` exactly as far as
1148
+ * `api/library/epic_implementer/webhook_verification.py` exactly as far as
1149
1149
  * PRESENCE goes — a `notify` object carrying a non-blank string `webhook_url` —
1150
1150
  * and stops there on purpose. Scheme, host, and reachability are the server's to
1151
1151
  * judge at activation, where the probe actually happens; re-deciding them here
@@ -1492,7 +1492,7 @@ export const SETUP_EPIC_SCOPE_RECOVERY_COMMAND = "re-run this same setup-epic co
1492
1492
  * The canonical one-line recovery for a scope collision (BAPI-1009).
1493
1493
  *
1494
1494
  * Repeated VERBATIM as the epic-run gate snapshot's shadow-hold recovery hint
1495
- * (``api/library/epic_conductor/gate_snapshot_service.py``), so an operator who
1495
+ * (``api/library/epic_implementer/gate_snapshot_service.py``), so an operator who
1496
1496
  * reads the diagnosis on the status surface and an operator who reads it from
1497
1497
  * the CLI are told to do the same thing in the same words.
1498
1498
  */
@@ -2256,7 +2256,7 @@ async function executeSetupEpic(argv, overrides, runIdSink) {
2256
2256
  : ` - feature branch: ${effectiveFeatureBranch} (validated server-side at approval; no request made in dry-run)`);
2257
2257
  if (needsCut && cutCommitSha !== null && scopeBaseBranch !== null) {
2258
2258
  say(` - would open a draft pull request ${effectiveFeatureBranch} → ${scopeBaseBranch} ` +
2259
- "for conductor-ci / gate (BAPI-951; nothing opened in dry-run)");
2259
+ "for epic-implementer-ci / gate (BAPI-951; nothing opened in dry-run)");
2260
2260
  }
2261
2261
  }
2262
2262
  if (opts.reviewPolicy !== undefined) {
@@ -62,20 +62,20 @@ export function mintStartTicketsWorkerId(ticketKey, agentName, fragment = random
62
62
  */
63
63
  export function buildEpicIdentityEnv(epic) {
64
64
  const env = {
65
- BAPI_CONDUCTOR_EPIC_KEY: epic.epic_key,
66
- BAPI_CONDUCTOR_EPIC_RUN_ID: epic.epic_run_id,
67
- BAPI_CONDUCTOR_PLAN_VERSION: String(epic.plan_version),
65
+ BAPI_EPIC_IMPLEMENTER_EPIC_KEY: epic.epic_key,
66
+ BAPI_EPIC_IMPLEMENTER_EPIC_RUN_ID: epic.epic_run_id,
67
+ BAPI_EPIC_IMPLEMENTER_PLAN_VERSION: String(epic.plan_version),
68
68
  };
69
69
  const declared = normalizeDeclaredTouchedFiles(epic.declared_touched_files);
70
70
  if (declared.length > 0) {
71
- env.BAPI_CONDUCTOR_DECLARED_TOUCHED_FILES_JSON = JSON.stringify(declared);
71
+ env.BAPI_EPIC_IMPLEMENTER_DECLARED_TOUCHED_FILES_JSON = JSON.stringify(declared);
72
72
  }
73
73
  return env;
74
74
  }
75
75
  // ---------------------------------------------------------------------------
76
76
  // Conductor context
77
77
  // ---------------------------------------------------------------------------
78
- /** Default gate name when no `BAPI_CONDUCTOR_GATE_NAME` override is present. */
78
+ /** Default gate name when no `BAPI_EPIC_IMPLEMENTER_GATE_NAME` override is present. */
79
79
  export const DEFAULT_CONDUCTOR_GATE_NAME = "implement-ticket";
80
80
  /**
81
81
  * Resolve a packaged build artifact path relative to this compiled module.
@@ -110,11 +110,11 @@ export async function createStartTicketsConductorContext(options, agent, deps) {
110
110
  // Repo resolution must never abort conductor setup; fall back to null.
111
111
  repoName = null;
112
112
  }
113
- const gateName = nonEmpty(deps.env.BAPI_CONDUCTOR_GATE_NAME)
114
- ? deps.env.BAPI_CONDUCTOR_GATE_NAME.trim()
113
+ const gateName = nonEmpty(deps.env.BAPI_EPIC_IMPLEMENTER_GATE_NAME)
114
+ ? deps.env.BAPI_EPIC_IMPLEMENTER_GATE_NAME.trim()
115
115
  : DEFAULT_CONDUCTOR_GATE_NAME;
116
- const supervisorMode = nonEmpty(deps.env.BAPI_CONDUCTOR_SUPERVISOR_MODE)
117
- ? deps.env.BAPI_CONDUCTOR_SUPERVISOR_MODE.trim()
116
+ const supervisorMode = nonEmpty(deps.env.BAPI_EPIC_IMPLEMENTER_SUPERVISOR_MODE)
117
+ ? deps.env.BAPI_EPIC_IMPLEMENTER_SUPERVISOR_MODE.trim()
118
118
  : options.autoApprove
119
119
  ? "auto"
120
120
  : "interactive";
@@ -142,12 +142,12 @@ export async function createStartTicketsConductorContext(options, agent, deps) {
142
142
  // ---------------------------------------------------------------------------
143
143
  /** Conductor store-tuning env keys forwarded only when already set upstream. */
144
144
  const CONDUCTOR_TUNING_ENV_KEYS = [
145
- "BAPI_CONDUCTOR_BUSY_TIMEOUT_MS",
146
- "BAPI_CONDUCTOR_RETENTION_DAYS",
147
- "BAPI_CONDUCTOR_RETENTION_MAX_ROWS",
145
+ "BAPI_EPIC_IMPLEMENTER_BUSY_TIMEOUT_MS",
146
+ "BAPI_EPIC_IMPLEMENTER_RETENTION_DAYS",
147
+ "BAPI_EPIC_IMPLEMENTER_RETENTION_MAX_ROWS",
148
148
  // BAPI-397: per-type relay cooldown — forwarded only when explicitly set so
149
149
  // the supervisor's send config is honoured by the conductor store it writes to.
150
- "BAPI_CONDUCTOR_MESSAGE_COOLDOWN_MS",
150
+ "BAPI_EPIC_IMPLEMENTER_MESSAGE_COOLDOWN_MS",
151
151
  ];
152
152
  /** Truthy predicate for opt-in conductor boolean flags (`1` / `true`). */
153
153
  export function isConductorFlagEnabled(value) {
@@ -164,30 +164,30 @@ export function isConductorFlagEnabled(value) {
164
164
  * upstream.
165
165
  */
166
166
  export function buildConductorWorkerEnv(context, worker, parentEnv) {
167
- // Merge "conductor" into the parent project's profile rather than overwriting it.
167
+ // Merge "epic_implementer" into the parent project's profile rather than overwriting it.
168
168
  // This preserves groups like "sfcc" that the project already has, while adding
169
169
  // the conductor-specific tools. Only validated group tokens from resolveProfiles
170
170
  // are threaded — arbitrary parentEnv keys never leak through.
171
171
  const parentActiveGroups = new Set(resolveProfiles(parentEnv.BRIDGE_MCP_PROFILE));
172
- parentActiveGroups.add("conductor");
172
+ parentActiveGroups.add("epic_implementer");
173
173
  const mergedProfile = Array.from(parentActiveGroups).join(",");
174
174
  const env = {
175
- BAPI_CONDUCTOR_ENABLED: "1",
175
+ BAPI_EPIC_IMPLEMENTER_ENABLED: "1",
176
176
  BRIDGE_MCP_PROFILE: mergedProfile,
177
- BAPI_CONDUCTOR_RUN_ID: context.runId,
178
- BAPI_CONDUCTOR_WORKER_ID: worker.workerId,
179
- BAPI_CONDUCTOR_TICKET_KEY: worker.ticketKey,
180
- BAPI_CONDUCTOR_WORKTREE_PATH: worker.worktreePath,
181
- BAPI_CONDUCTOR_GATE_NAME: context.gateName,
182
- BAPI_CONDUCTOR_SUPERVISOR_MODE: context.supervisorMode,
183
- BAPI_CONDUCTOR_CLI_FILE: context.cliFile,
177
+ BAPI_EPIC_IMPLEMENTER_RUN_ID: context.runId,
178
+ BAPI_EPIC_IMPLEMENTER_WORKER_ID: worker.workerId,
179
+ BAPI_EPIC_IMPLEMENTER_TICKET_KEY: worker.ticketKey,
180
+ BAPI_EPIC_IMPLEMENTER_WORKTREE_PATH: worker.worktreePath,
181
+ BAPI_EPIC_IMPLEMENTER_GATE_NAME: context.gateName,
182
+ BAPI_EPIC_IMPLEMENTER_SUPERVISOR_MODE: context.supervisorMode,
183
+ BAPI_EPIC_IMPLEMENTER_CLI_FILE: context.cliFile,
184
184
  // BAPI-527: the CLI file + Node runtime are a PAIR. The worker runs
185
185
  // conductor-bin.js under this captured conductor Node for every worker-side
186
186
  // ledger op, so the worker Node never loads better-sqlite3. Non-secret.
187
- CONDUCTOR_NODE_PATH: context.conductorNodePath,
187
+ EPIC_IMPLEMENTER_NODE_PATH: context.conductorNodePath,
188
188
  };
189
189
  if (context.repoName) {
190
- env.BAPI_CONDUCTOR_REPO_NAME = context.repoName;
190
+ env.BAPI_EPIC_IMPLEMENTER_REPO_NAME = context.repoName;
191
191
  }
192
192
  if (context.epic) {
193
193
  const epicEnv = buildEpicIdentityEnv(context.epic);
@@ -195,8 +195,8 @@ export function buildConductorWorkerEnv(context, worker, parentEnv) {
195
195
  env[k] = v;
196
196
  }
197
197
  }
198
- if (isConductorFlagEnabled(parentEnv.BAPI_CONDUCTOR_ENABLE_PRE_TOOL_USE)) {
199
- env.BAPI_CONDUCTOR_ENABLE_PRE_TOOL_USE = "1";
198
+ if (isConductorFlagEnabled(parentEnv.BAPI_EPIC_IMPLEMENTER_ENABLE_PRE_TOOL_USE)) {
199
+ env.BAPI_EPIC_IMPLEMENTER_ENABLE_PRE_TOOL_USE = "1";
200
200
  }
201
201
  for (const key of CONDUCTOR_TUNING_ENV_KEYS) {
202
202
  if (nonEmpty(parentEnv[key])) {
@@ -234,13 +234,13 @@ function shellQuotePath(value) {
234
234
  return `'${value.replace(/'/g, "'\\''")}'`;
235
235
  }
236
236
  /**
237
- * Resolve the hook command string. Prefers `BAPI_CONDUCTOR_HOOK_COMMAND`
237
+ * Resolve the hook command string. Prefers `BAPI_EPIC_IMPLEMENTER_HOOK_COMMAND`
238
238
  * verbatim; otherwise runs the packaged hook bin via the current Node
239
239
  * executable.
240
240
  */
241
241
  export function resolveConductorHookCommand(env, hookBinPath, execPath = process.execPath) {
242
- if (nonEmpty(env.BAPI_CONDUCTOR_HOOK_COMMAND)) {
243
- return env.BAPI_CONDUCTOR_HOOK_COMMAND;
242
+ if (nonEmpty(env.BAPI_EPIC_IMPLEMENTER_HOOK_COMMAND)) {
243
+ return env.BAPI_EPIC_IMPLEMENTER_HOOK_COMMAND;
244
244
  }
245
245
  return `${shellQuotePath(execPath)} ${shellQuotePath(hookBinPath)}`;
246
246
  }
@@ -279,7 +279,7 @@ export async function provisionConductorHookForWorktree(worktreePath, command, o
279
279
  */
280
280
  export async function provisionConductorHooksForRows(rows, context, deps) {
281
281
  const isClaude = context.agentName === "claude";
282
- const enablePreToolUse = isConductorFlagEnabled(deps.env.BAPI_CONDUCTOR_ENABLE_PRE_TOOL_USE);
282
+ const enablePreToolUse = isConductorFlagEnabled(deps.env.BAPI_EPIC_IMPLEMENTER_ENABLE_PRE_TOOL_USE);
283
283
  const command = resolveConductorHookCommand(deps.env, context.hookBinPath, deps.execPath);
284
284
  const fragment = deps.workerFragment;
285
285
  const out = [];
@@ -451,7 +451,7 @@ export function buildSupervisorTabCommand(context, platform, nodeExecPath = proc
451
451
  /**
452
452
  * Decide whether the supervisor peer tab should launch. Enabled by default for a
453
453
  * normal packaged conductor context; disabled only when the resolved supervisor
454
- * mode is `off` (i.e. `BAPI_CONDUCTOR_SUPERVISOR_MODE=off`).
454
+ * mode is `off` (i.e. `BAPI_EPIC_IMPLEMENTER_SUPERVISOR_MODE=off`).
455
455
  */
456
456
  export function isSupervisorLaunchEnabled(context) {
457
457
  return context.supervisorMode.trim().toLowerCase() !== "off";
@@ -52,7 +52,7 @@ export const START_TICKETS_DOCTOR_COMMAND = `npx -y ${MCP_PACKAGE_NAME} doctor`;
52
52
  /**
53
53
  * BAPI-527 live-source checkout guard (conductor durable execution).
54
54
  *
55
- * `BAPI_CONDUCTOR_LIVE_SOURCE_PATH` — OPTIONAL operator-set path to the checkout
55
+ * `BAPI_EPIC_IMPLEMENTER_LIVE_SOURCE_PATH` — OPTIONAL operator-set path to the checkout
56
56
  * an operator's live dev server (e.g. `uvicorn main:app --reload`) is running
57
57
  * from. When set, unattended conductor/epic/non-mutating start-tickets dispatch
58
58
  * refuses to run if the conductor base repo it would operate on resolves to the
@@ -62,14 +62,14 @@ export const START_TICKETS_DOCTOR_COMMAND = `npx -y ${MCP_PACKAGE_NAME} doctor`;
62
62
  * discovery, so this local env contract is introduced here. Read only from the
63
63
  * injected `deps.env` (never global `process.env`) so it stays mockable.
64
64
  *
65
- * `BAPI_CONDUCTOR_ALLOW_LIVE_SOURCE_DISPATCH` — explicit escape hatch. When set
65
+ * `BAPI_EPIC_IMPLEMENTER_ALLOW_LIVE_SOURCE_DISPATCH` — explicit escape hatch. When set
66
66
  * to a truthy value (`1`/`true`/`yes`/`on`, case-insensitive) a detected
67
67
  * collision is DOWNGRADED from fatal to a loud warning rather than silently
68
68
  * ignored, so an operator who genuinely wants same-checkout dispatch can opt in
69
69
  * with eyes open.
70
70
  */
71
- export const CONDUCTOR_LIVE_SOURCE_PATH_ENV = "BAPI_CONDUCTOR_LIVE_SOURCE_PATH";
72
- export const CONDUCTOR_ALLOW_LIVE_SOURCE_DISPATCH_ENV = "BAPI_CONDUCTOR_ALLOW_LIVE_SOURCE_DISPATCH";
71
+ export const CONDUCTOR_LIVE_SOURCE_PATH_ENV = "BAPI_EPIC_IMPLEMENTER_LIVE_SOURCE_PATH";
72
+ export const CONDUCTOR_ALLOW_LIVE_SOURCE_DISPATCH_ENV = "BAPI_EPIC_IMPLEMENTER_ALLOW_LIVE_SOURCE_DISPATCH";
73
73
  /** Stable descriptor id for the live-source checkout guard (used in messages + doctor). */
74
74
  export const LIVE_SOURCE_GUARD_ID = "conductor-live-source";
75
75
  /** True only for the three first-class supported platforms. */
@@ -566,11 +566,6 @@ const CLAUDE_MCP_SHADOWING_INSTALL_HINTS = {
566
566
  * - a CONFIRMED foreign registration → `found: true` + advisory detail
567
567
  * - unreadable / malformed config, or an unresolved main
568
568
  * worktree path → `found: true` + detail
569
- *
570
- * Reporting stays deliberately independent of the retired
571
- * `BAPI_CONDUCTOR_ALLOW_CLAUDE_MCP_SHADOWING` override: whether that variable is
572
- * exported has never had any bearing on whether the collision exists, and now it
573
- * has no bearing on anything at all.
574
569
  */
575
570
  export function claudeMcpShadowingDescriptor() {
576
571
  return {