@gajae-code/coding-agent 0.11.4 → 0.11.5

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 (146) hide show
  1. package/CHANGELOG.md +23 -0
  2. package/dist/types/cli/notify-cli.d.ts +5 -1
  3. package/dist/types/config/settings-schema.d.ts +20 -0
  4. package/dist/types/export/html/template.generated.d.ts +1 -1
  5. package/dist/types/gjc-runtime/deep-interview-state.d.ts +28 -0
  6. package/dist/types/gjc-runtime/launch-tmux.d.ts +3 -0
  7. package/dist/types/gjc-runtime/managed-owner-admission.d.ts +42 -0
  8. package/dist/types/gjc-runtime/managed-owner-supervisor.d.ts +41 -0
  9. package/dist/types/gjc-runtime/tmux-owner-isolation.d.ts +9 -0
  10. package/dist/types/gjc-runtime/ultragoal-owner-loss-recovery.d.ts +94 -0
  11. package/dist/types/gjc-runtime/ultragoal-runtime.d.ts +1 -0
  12. package/dist/types/harness-control-plane/owner.d.ts +3 -1
  13. package/dist/types/internal-urls/local-protocol.d.ts +18 -0
  14. package/dist/types/main.d.ts +2 -2
  15. package/dist/types/modes/components/ansi-display-validator.d.ts +2 -0
  16. package/dist/types/modes/components/notifications-settings-editor.d.ts +4 -0
  17. package/dist/types/modes/components/session-observer-overlay.d.ts +3 -1
  18. package/dist/types/modes/components/settings-selector.d.ts +2 -0
  19. package/dist/types/modes/components/tool-transcript-format.d.ts +58 -0
  20. package/dist/types/modes/components/transcript-viewer-overlay.d.ts +3 -0
  21. package/dist/types/modes/controllers/goal-mode-controller.d.ts +8 -1
  22. package/dist/types/modes/controllers/selector-controller.d.ts +15 -0
  23. package/dist/types/modes/shared/agent-wire/workflow-gate-broker.d.ts +3 -0
  24. package/dist/types/modes/shared/agent-wire/workflow-gate-types.d.ts +16 -0
  25. package/dist/types/plan-mode/approved-plan.d.ts +1 -0
  26. package/dist/types/runtime-mcp/manager.d.ts +2 -0
  27. package/dist/types/runtime-mcp/oauth-discovery.d.ts +12 -1
  28. package/dist/types/sdk/bus/chat-daemon-cli.d.ts +3 -1
  29. package/dist/types/sdk/bus/chat-daemon-control.d.ts +39 -4
  30. package/dist/types/sdk/bus/config-commands.d.ts +8 -0
  31. package/dist/types/sdk/bus/config.d.ts +22 -0
  32. package/dist/types/sdk/bus/index.d.ts +162 -2
  33. package/dist/types/sdk/bus/notification-service.d.ts +71 -8
  34. package/dist/types/sdk/bus/session-control.d.ts +11 -8
  35. package/dist/types/sdk/bus/telegram-daemon-cli.d.ts +5 -0
  36. package/dist/types/sdk/bus/telegram-daemon-contract.d.ts +6 -3
  37. package/dist/types/sdk/bus/telegram-daemon-control.d.ts +23 -4
  38. package/dist/types/sdk/bus/telegram-daemon.d.ts +214 -20
  39. package/dist/types/sdk/session.d.ts +16 -1
  40. package/dist/types/secrets/index.d.ts +4 -2
  41. package/dist/types/secrets/obfuscator.d.ts +1 -1
  42. package/dist/types/session/agent-session.d.ts +31 -2
  43. package/dist/types/session/artifacts.d.ts +30 -8
  44. package/dist/types/session/internal/managed-session-scope.d.ts +7 -0
  45. package/dist/types/session/internal/managed-session-storage.d.ts +63 -6
  46. package/dist/types/session/session-manager.d.ts +88 -18
  47. package/dist/types/session/session-storage.d.ts +27 -0
  48. package/dist/types/session/streaming-output.d.ts +4 -0
  49. package/dist/types/task/executor.d.ts +9 -0
  50. package/dist/types/tool-discovery/tool-index.d.ts +2 -0
  51. package/dist/types/tools/ask.d.ts +48 -0
  52. package/dist/types/tools/bash-skill-urls.d.ts +2 -2
  53. package/dist/types/tools/index.d.ts +4 -0
  54. package/package.json +9 -9
  55. package/scripts/generate-sdk-operation-inventory.ts +2 -0
  56. package/src/cli/notify-cli.ts +40 -18
  57. package/src/commands/sdk.ts +7 -2
  58. package/src/config/settings-schema.ts +17 -0
  59. package/src/daemon/runtime.ts +2 -2
  60. package/src/defaults/gjc/skills/deep-interview/SKILL.md +70 -49
  61. package/src/defaults/gjc/skills/ralplan/SKILL.md +0 -6
  62. package/src/defaults/gjc/skills/team/SKILL.md +7 -9
  63. package/src/defaults/gjc/skills/ultragoal/SKILL.md +0 -2
  64. package/src/eval/py/index.ts +2 -2
  65. package/src/export/html/template.generated.ts +1 -1
  66. package/src/extensibility/plugins/marketplace/manager.ts +94 -10
  67. package/src/gjc-runtime/deep-interview-recorder.ts +7 -0
  68. package/src/gjc-runtime/deep-interview-runtime.ts +10 -0
  69. package/src/gjc-runtime/deep-interview-state.ts +127 -3
  70. package/src/gjc-runtime/launch-tmux.ts +61 -6
  71. package/src/gjc-runtime/managed-owner-admission.ts +352 -0
  72. package/src/gjc-runtime/managed-owner-supervisor.ts +162 -0
  73. package/src/gjc-runtime/state-runtime.ts +38 -12
  74. package/src/gjc-runtime/team-runtime.ts +1 -1
  75. package/src/gjc-runtime/tmux-owner-isolation.ts +117 -0
  76. package/src/gjc-runtime/ultragoal-owner-loss-recovery.ts +328 -0
  77. package/src/gjc-runtime/ultragoal-runtime.ts +14 -0
  78. package/src/harness-control-plane/owner.ts +59 -3
  79. package/src/hindsight/client.ts +65 -2
  80. package/src/internal-urls/agent-protocol.ts +76 -5
  81. package/src/internal-urls/docs-index.generated.ts +7 -6
  82. package/src/internal-urls/local-protocol.ts +416 -18
  83. package/src/lsp/index.ts +4 -88
  84. package/src/main.ts +37 -13
  85. package/src/modes/acp/acp-agent.ts +8 -0
  86. package/src/modes/components/ansi-display-validator.ts +54 -0
  87. package/src/modes/components/notifications-settings-editor.ts +26 -2
  88. package/src/modes/components/session-observer-overlay.ts +40 -24
  89. package/src/modes/components/settings-selector.ts +3 -1
  90. package/src/modes/components/tool-transcript-format.ts +321 -0
  91. package/src/modes/components/transcript-viewer-overlay.ts +39 -17
  92. package/src/modes/controllers/goal-mode-controller.ts +20 -1
  93. package/src/modes/controllers/plan-mode-controller.ts +2 -0
  94. package/src/modes/controllers/runtime-mcp-command-controller.ts +3 -0
  95. package/src/modes/controllers/selector-controller.ts +70 -8
  96. package/src/modes/interactive-mode.ts +1 -0
  97. package/src/modes/shared/agent-wire/deep-interview-gate.ts +31 -1
  98. package/src/modes/shared/agent-wire/workflow-gate-broker.ts +17 -1
  99. package/src/modes/shared/agent-wire/workflow-gate-schema.ts +4 -2
  100. package/src/modes/shared/agent-wire/workflow-gate-types.ts +120 -3
  101. package/src/plan-mode/approved-plan.ts +3 -1
  102. package/src/prompts/agents/architect.md +1 -0
  103. package/src/prompts/agents/critic.md +1 -0
  104. package/src/prompts/system/custom-system-prompt.md +1 -1
  105. package/src/prompts/system/system-prompt.md +2 -1
  106. package/src/prompts/tools/lsp.md +3 -3
  107. package/src/runtime-mcp/manager.ts +16 -1
  108. package/src/runtime-mcp/oauth-discovery.ts +116 -26
  109. package/src/sdk/broker/session-index.ts +122 -64
  110. package/src/sdk/bus/chat-daemon-cli.ts +72 -10
  111. package/src/sdk/bus/chat-daemon-control.ts +526 -130
  112. package/src/sdk/bus/chat-daemon-runtime.ts +1 -0
  113. package/src/sdk/bus/config-commands.ts +22 -0
  114. package/src/sdk/bus/config.ts +37 -0
  115. package/src/sdk/bus/index.ts +384 -92
  116. package/src/sdk/bus/lifecycle-control-runtime.ts +53 -3
  117. package/src/sdk/bus/notification-service.ts +284 -62
  118. package/src/sdk/bus/recent-activity.ts +14 -5
  119. package/src/sdk/bus/session-control.ts +150 -44
  120. package/src/sdk/bus/telegram-daemon-cli.ts +20 -14
  121. package/src/sdk/bus/telegram-daemon-contract.ts +6 -3
  122. package/src/sdk/bus/telegram-daemon-control.ts +294 -76
  123. package/src/sdk/bus/telegram-daemon.ts +1788 -267
  124. package/src/sdk/protocol/operation-inventory.generated.json +11 -0
  125. package/src/sdk/session.ts +155 -27
  126. package/src/secrets/index.ts +53 -10
  127. package/src/secrets/obfuscator.ts +21 -18
  128. package/src/secrets/regex.ts +2 -0
  129. package/src/session/agent-session.ts +495 -253
  130. package/src/session/artifacts.ts +188 -23
  131. package/src/session/context-estimation.ts +7 -2
  132. package/src/session/internal/managed-session-scope.ts +200 -38
  133. package/src/session/internal/managed-session-storage.ts +1152 -46
  134. package/src/session/session-manager.ts +1055 -148
  135. package/src/session/session-storage.ts +109 -11
  136. package/src/session/streaming-output.ts +6 -0
  137. package/src/task/executor.ts +71 -26
  138. package/src/task/index.ts +63 -20
  139. package/src/tool-discovery/tool-index.ts +18 -0
  140. package/src/tools/ask.ts +129 -32
  141. package/src/tools/bash-skill-urls.ts +14 -3
  142. package/src/tools/bash.ts +2 -2
  143. package/src/tools/index.ts +4 -0
  144. package/src/tools/plan-mode-guard.ts +1 -0
  145. package/src/tools/sqlite-reader.ts +3 -2
  146. package/src/tools/subagent.ts +2 -0
@@ -7,6 +7,7 @@ import { createInterface } from "node:readline/promises";
7
7
  import { APP_NAME } from "@gajae-code/utils/dirs";
8
8
  import chalk from "chalk";
9
9
  import { Settings, type SettingsAtomicPatch } from "../config/settings";
10
+ import { isProcessIncarnation, processIncarnation } from "../sdk/broker/process-incarnation";
10
11
  import { type EnsureChatDaemonResult, ensureDiscordDaemon, ensureSlackDaemon } from "../sdk/bus/chat-daemon-control";
11
12
  import { getNotificationConfig, maskToken, tokenFingerprint } from "../sdk/bus/config";
12
13
  import {
@@ -29,7 +30,11 @@ import {
29
30
  sanitizeDiagnostic,
30
31
  sendNotificationTest,
31
32
  } from "../sdk/bus/notification-service";
32
- import { ensureTelegramDaemonRunningDetailed, readDaemonState } from "../sdk/bus/telegram-daemon";
33
+ import {
34
+ type EnsureTelegramDaemonDetailedResult,
35
+ ensureTelegramDaemonRunningDetailed,
36
+ readDaemonState,
37
+ } from "../sdk/bus/telegram-daemon";
33
38
  import { runDaemonInternal } from "../sdk/bus/telegram-daemon-cli";
34
39
  import {
35
40
  runTelegramSetup as runTelegramPairingSetup,
@@ -82,10 +87,10 @@ export interface NotifyCommandDeps {
82
87
  setupTimers?: TelegramSetupTimers;
83
88
  setupAbortSignal?: AbortSignal;
84
89
  setupPidAlive?: (pid: number) => boolean;
85
- ensureProviderDaemon?: (
86
- provider: "discord" | "slack",
87
- settings: Settings,
88
- ) => Promise<EnsureChatDaemonResult | "failed">;
90
+ /** Injectable process-start provenance reader for ambient Telegram setup preflight. */
91
+ setupPidIncarnation?: (pid: number) => string | undefined;
92
+ ensureProviderDaemon?: (provider: "discord" | "slack", settings: Settings) => Promise<EnsureChatDaemonResult>;
93
+ ensureTelegramDaemon?: (settings: Settings) => Promise<EnsureTelegramDaemonDetailedResult>;
89
94
  }
90
95
 
91
96
  export function parseNotifyArgs(args: string[]): NotifyCommandArgs | undefined {
@@ -313,12 +318,22 @@ async function ensureConfiguredProviderDaemon(
313
318
  provider: "discord" | "slack",
314
319
  settings: Settings,
315
320
  deps: NotifyCommandDeps,
316
- ): Promise<EnsureChatDaemonResult | "failed"> {
321
+ ): Promise<EnsureChatDaemonResult> {
317
322
  try {
318
323
  if (deps.ensureProviderDaemon) return await deps.ensureProviderDaemon(provider, settings);
319
324
  return provider === "discord" ? await ensureDiscordDaemon(settings) : await ensureSlackDaemon(settings);
320
- } catch {
321
- return "failed";
325
+ } catch (error) {
326
+ const cfg = getNotificationConfig(settings);
327
+ const detail = sanitizeDiagnostic(
328
+ sanitizeDiagnostic(
329
+ error instanceof Error ? error.message : String(error),
330
+ provider === "discord" ? cfg.discord.botToken : cfg.slack.appToken,
331
+ ),
332
+ provider === "discord" ? cfg.discord.botToken : cfg.slack.botToken,
333
+ );
334
+ throw new Error(`${provider === "discord" ? "Discord" : "Slack"} daemon did not become ready: ${detail}`, {
335
+ cause: error,
336
+ });
322
337
  }
323
338
  }
324
339
 
@@ -393,11 +408,13 @@ async function runTelegramSetup(cmd: NotifyCommandArgs, deps: NotifyCommandDeps)
393
408
  reconcileCurrentSession: async () => undefined,
394
409
  },
395
410
  reconnect: async () =>
396
- await ensureTelegramDaemonRunningDetailed({
397
- settings,
398
- cwd: process.cwd(),
399
- sessionId: `notify-cli-${process.pid}`,
400
- }),
411
+ deps.ensureTelegramDaemon
412
+ ? await deps.ensureTelegramDaemon(settings)
413
+ : await ensureTelegramDaemonRunningDetailed({
414
+ settings,
415
+ cwd: process.cwd(),
416
+ sessionId: `notify-cli-${process.pid}`,
417
+ }),
401
418
  persistInactive: async marker => await persistTelegramActivationMarker(settings, marker),
402
419
  clearInactive: async marker => await clearTelegramActivationMarker(settings, marker),
403
420
  marker: activationMarker,
@@ -446,14 +463,19 @@ async function resolveSetupPreflight(settings: Settings, deps: NotifyCommandDeps
446
463
  const state = await readDaemonState(settings);
447
464
  if (!state) return { storedChatId: cfg.chatId };
448
465
  const validPid = Number.isSafeInteger(state.pid) && state.pid > 0;
449
- // Owner-proof: only block discovery for a daemon we can positively prove is
450
- // live (present state with a valid, alive pid). A malformed/no-pid record is
451
- // not evidence of a live poller, mirroring recoverNotifications' semantics.
452
- if (!validPid) return { storedChatId: cfg.chatId };
466
+ if (!validPid || !(deps.setupPidAlive ?? daemonPidAlive)(state.pid)) return { storedChatId: cfg.chatId };
467
+ const persistedIncarnation = state.incarnation;
468
+ const currentIncarnation = (deps.setupPidIncarnation ?? processIncarnation)(state.pid);
469
+ if (
470
+ !isProcessIncarnation(persistedIncarnation) ||
471
+ !isProcessIncarnation(currentIncarnation) ||
472
+ persistedIncarnation !== currentIncarnation
473
+ )
474
+ return { storedChatId: cfg.chatId };
453
475
  return {
454
476
  storedChatId: cfg.chatId,
455
477
  daemon: {
456
- live: (deps.setupPidAlive ?? daemonPidAlive)(state.pid),
478
+ live: true,
457
479
  tokenFingerprint: typeof state.tokenFingerprint === "string" ? state.tokenFingerprint : undefined,
458
480
  chatId: typeof state.chatId === "string" ? state.chatId : undefined,
459
481
  },
@@ -167,7 +167,7 @@ export async function openLifecycleSessionManager(
167
167
  if (request.operation === "session.resume") {
168
168
  const opened = await SessionManager.openExistingStrict(
169
169
  snapshot.identity,
170
- parsed.sessionDir,
170
+ SessionManager.managedDestination(cwd, agentDir),
171
171
  undefined,
172
172
  migrationPolicy,
173
173
  );
@@ -181,7 +181,12 @@ export async function openLifecycleSessionManager(
181
181
  throw error;
182
182
  }
183
183
  } else {
184
- const forked = await SessionManager.forkFromCaptured(snapshot, cwd, parsed.sessionDir, migrationPolicy);
184
+ const forked = await SessionManager.forkFromCaptured(
185
+ snapshot,
186
+ cwd,
187
+ SessionManager.managedDestination(cwd, agentDir),
188
+ migrationPolicy,
189
+ );
185
190
  if (forked.kind === "error")
186
191
  throw new Error("Lifecycle saved session authority changed while the session host forked it.");
187
192
  sessionManager = forked.manager;
@@ -286,6 +286,7 @@ export const SETTINGS_SCHEMA = {
286
286
  "notifications.telegram.chatId": { type: "string", default: undefined },
287
287
  "notifications.telegram.activation": { type: "record", default: {} as Record<string, unknown> },
288
288
  "notifications.telegram.btw.enabled": { type: "boolean", default: true },
289
+ "notifications.telegram.streaming.enabled": { type: "boolean", default: true },
289
290
  "notifications.telegram.rich.enabled": {
290
291
  type: "boolean",
291
292
  default: true,
@@ -306,6 +307,16 @@ export const SETTINGS_SCHEMA = {
306
307
  editing: "notification-atomic",
307
308
  },
308
309
  },
310
+ "notifications.telegram.toolActivity.enabled": {
311
+ type: "boolean",
312
+ default: true,
313
+ ui: {
314
+ tab: "notifications",
315
+ label: "Telegram Tool Activity",
316
+ description: "Send Telegram updates for tool starts and completions.",
317
+ editing: "notification-atomic",
318
+ },
319
+ },
309
320
  "notifications.telegram.topics.nameTemplate": { type: "string", default: undefined },
310
321
  "notifications.discord.botToken": { type: "string", default: undefined },
311
322
  "notifications.discord.applicationId": { type: "string", default: undefined },
@@ -3768,6 +3779,12 @@ export interface NotificationsSettings {
3768
3779
  richDraft: {
3769
3780
  enabled: boolean;
3770
3781
  };
3782
+ toolActivity: {
3783
+ enabled: boolean;
3784
+ };
3785
+ streaming: {
3786
+ enabled: boolean;
3787
+ };
3771
3788
  topics: {
3772
3789
  nameTemplate: string | undefined;
3773
3790
  };
@@ -32,12 +32,12 @@ const COMPILED_RELOAD_WARNING =
32
32
  export function resolveGjcRuntimeSpawnInfo(execPath: string = process.execPath): GjcRuntimeSpawnInfo {
33
33
  const base = path.basename(execPath).toLowerCase();
34
34
  const fromSource = base === "bun" || base === "node" || base.startsWith("bun") || base.startsWith("node");
35
- const mainScript = fromSource && typeof Bun !== "undefined" ? (Bun as unknown as { main?: string }).main : undefined;
35
+ const sourceEntry = fromSource ? path.resolve(import.meta.dir, "../../bin/gjc.js") : undefined;
36
36
  if (fromSource) {
37
37
  return {
38
38
  execPath,
39
39
  mode: "source",
40
- argsPrefix: mainScript ? [mainScript] : [],
40
+ argsPrefix: sourceEntry ? [sourceEntry] : [],
41
41
  reloadPicksUpSourceEdits: true,
42
42
  };
43
43
  }
@@ -10,21 +10,42 @@ level: 3
10
10
  source: "forked from upstream deep-interview skill and rebranded for GJC"
11
11
  ---
12
12
 
13
- <Purpose>
14
- Deep Interview implements Ouroboros-inspired Socratic questioning with mathematical ambiguity scoring. It replaces vague ideas with crystal-clear specifications by asking targeted questions that expose hidden assumptions, measuring clarity across weighted dimensions, and refusing to proceed until ambiguity drops below the resolved threshold for this run. The output feeds into a gated pipeline: **deep-interview → ralplan consensus refinement → pending approval → explicitly approved execution**, ensuring maximum clarity before any mutation starts.
15
- </Purpose>
16
-
17
- <Use_When>
18
- - User has a vague idea and wants thorough requirements gathering before execution
19
- - User says "deep interview", "interview me", "ask me everything", "don't assume", "make sure you understand"
20
- - User says "ouroboros", "socratic", "I have a vague idea", "not sure exactly what I want"
21
- - User wants to avoid "that's not what I meant" outcomes from autonomous execution
22
- - Task is complex enough that jumping to code would waste cycles on scope discovery
23
- - User asks for implementation but the target, scope, acceptance criteria, or safety boundary is ambiguous enough that mutation would require guessing
24
- - User wants mathematically-validated clarity before committing to execution
25
- - User explicitly requests deep-interview even after being told the request is already clear, bounded, and low-risk
26
- - User requests a trace/research pre-step before the interview, e.g. `/skill:deep-interview --trace <idea>`
27
- </Use_When>
13
+ <Purpose_And_Principles>
14
+ **DIPP-1 — Purpose.** Deep Interview applies Socratic questioning with mathematical ambiguity scoring to replace vague ideas with crystal-clear specifications: it exposes hidden assumptions, measures clarity across weighted dimensions, and refuses to proceed until ambiguity drops below the resolved threshold for this run. The output feeds into a gated pipeline: **deep-interview → ralplan consensus refinement → pending approval → explicitly approved execution**, ensuring maximum clarity before any mutation starts. AI can build anything. The hard part is knowing what to build. GJC planning Phase 0 expands ideas into specs via analyst + architect, but this single-pass approach struggles with genuinely vague inputs: it asks "what do you want?" instead of "what are you assuming?" Deep Interview iteratively exposes assumptions and mathematically gates readiness, ensuring the AI has genuine clarity before spending execution cycles. Inspired by the [Ouroboros project](https://github.com/Q00/ouroboros), which demonstrated that specification quality is the primary bottleneck in AI-assisted development.
15
+
16
+ **DIPP-2 — Use when.**
17
+
18
+ > **Use when** the user wants requirements clarified before execution: a vague or exploratory idea ("I have a vague idea", "not sure exactly what I want"); an explicit request to interview ("deep interview", "interview me", "ask me everything", "don't assume", "make sure you understand", "ouroboros", "socratic"); a wish to avoid "that's not what I meant" outcomes from autonomous execution or to reach mathematically-validated clarity before committing to execution; a task complex enough that jumping to code would waste cycles on scope discovery; an implementation ask whose target, scope, acceptance criteria, or safety boundary is ambiguous enough that mutation would require guessing; or an explicit deep-interview request even after being told the request is already clear, bounded, and low-risk.
19
+ > - User requests a trace/research pre-step before the interview, e.g. `/skill:deep-interview --trace <idea>`
20
+
21
+ **DIPP-3 — Question pacing.**
22
+
23
+ - Ask ONE question at a time -- never batch multiple questions
24
+
25
+ **DIPP-4 — Language.**
26
+
27
+ - Default to English when no language preference is explicit or obvious. Preserve the user/session language for every user-facing announcement, topology confirmation, option label, and interview question when state includes `language.instruction`; do not add language-specific special cases
28
+
29
+ **DIPP-5 — Self-proofread.**
30
+
31
+ - Before emitting any user-facing natural-language prose governed by `language.instruction`, perform one silent, best-effort self-proofread in the preserved session language for obvious spelling, spacing, grammar, inflection/particle, and word-choice errors, using the same language-agnostic pass for whatever language is active rather than special-casing any single language. Apply it only to newly generated prose and never announce the proofreading, show before/after text, apologize for it, or re-emit a corrected copy. Do not alter code blocks or identifiers, file paths, CLI commands, JSON/configuration keys, `ask` metadata keys, table/round structure, fixed labels, numeric scores, component ids, status tokens, user quotes or source text, Phase 0 threshold markers such as `Deep Interview threshold: <resolvedThresholdPercent> (source: <resolvedThresholdSource>)`, or fixed paths such as `.gjc/_session-{sessionid}/specs/deep-interview-{slug}.md`; still apply the self-proofread to generated natural-language clauses or cells inside those structures, including Why now rationale, gap text, next-target phrasing, and coverage notes
32
+
33
+ **DIPP-6 — Weakest dimension.**
34
+
35
+ - Target the WEAKEST clarity dimension with each question. Make weakest-dimension targeting explicit every round: name the weakest dimension, state its score/gap, and explain why the next question is aimed there
36
+
37
+ **DIPP-7 — Prompt budget.**
38
+
39
+ > Keep prompt payloads budgeted: summarize or trim oversized initial context/history before composing question, scoring, spec, or handoff prompts. If the user's initial context is oversized or likely to crowd out downstream prompts, create a concise prompt-safe summary first — one that preserves user intent, decisions, constraints, unknowns, cited files/symbols, and any explicit non-goals — and wait until that summary exists before ambiguity scoring, weakest-dimension selection, question generation, brownfield exploration prompts, spec crystallization, or any downstream execution handoff (bridge to `ralplan`, `ultragoal`, or `team`).
40
+
41
+ **DIPP-8 — Artifact writes.**
42
+
43
+ - Use the active GJC workflow/state CLI as the only sanctioned writer for `.gjc/` interview artifacts; do not edit `.gjc/` directly without an explicit force override.
44
+
45
+ **DIPP-9 — Execution threshold.**
46
+
47
+ - Do not proceed to execution until ambiguity ≤ the resolved threshold for this run and the user explicitly approves a scoped execution path
48
+ </Purpose_And_Principles>
28
49
 
29
50
  <Do_Not_Use_When>
30
51
  - User has a detailed, specific request with file paths, function names, or acceptance criteria -- execute directly
@@ -35,27 +56,13 @@ Deep Interview implements Ouroboros-inspired Socratic questioning with mathemati
35
56
  - User already has a PRD or plan file and explicitly asks to execute it -- use the requested execution skill with that plan
36
57
  </Do_Not_Use_When>
37
58
 
38
- <Why_This_Exists>
39
- AI can build anything. The hard part is knowing what to build. GJC planning Phase 0 expands ideas into specs via analyst + architect, but this single-pass approach struggles with genuinely vague inputs. It asks "what do you want?" instead of "what are you assuming?" Deep Interview applies Socratic methodology to iteratively expose assumptions and mathematically gate readiness, ensuring the AI has genuine clarity before spending execution cycles.
40
-
41
- Inspired by the [Ouroboros project](https://github.com/Q00/ouroboros) which demonstrated that specification quality is the primary bottleneck in AI-assisted development.
42
- </Why_This_Exists>
43
-
44
59
  <Execution_Policy>
45
- - Ask ONE question at a time -- never batch multiple questions
46
- - Default to English when no language preference is explicit or obvious. Preserve the user/session language for every user-facing announcement, topology confirmation, option label, and interview question when state includes `language.instruction`; do not add language-specific special cases
47
- - Before emitting any user-facing natural-language prose governed by `language.instruction`, perform one silent, best-effort self-proofread in the preserved session language for obvious spelling, spacing, grammar, inflection/particle, and word-choice errors, using the same language-agnostic pass for whatever language is active rather than special-casing any single language. Apply it only to newly generated prose and never announce the proofreading, show before/after text, apologize for it, or re-emit a corrected copy. Do not alter code blocks or identifiers, file paths, CLI commands, JSON/configuration keys, `ask` metadata keys, table/round structure, fixed labels, numeric scores, component ids, status tokens, user quotes or source text, Phase 0 threshold markers such as `Deep Interview threshold: <resolvedThresholdPercent> (source: <resolvedThresholdSource>)`, or fixed paths such as `.gjc/_session-{sessionid}/specs/deep-interview-{slug}.md`; still apply the self-proofread to generated natural-language clauses or cells inside those structures, including Why now rationale, gap text, next-target phrasing, and coverage notes
48
- - Target the WEAKEST clarity dimension with each question
49
60
  - Before Round 1 ambiguity scoring, run a one-time Round 0 topology enumeration gate that confirms the top-level component list and locks it into state
50
- - Make weakest-dimension targeting explicit every round: name the weakest dimension, state its score/gap, and explain why the next question is aimed there
51
61
  - Gather codebase facts via focused read/search tools or a canonical read-only role agent (`planner`/`architect`) BEFORE asking the user about them
52
62
  - For brownfield confirmation questions, cite the repo evidence that triggered the question (file path, symbol, or pattern) instead of asking the user to rediscover it
53
63
  - Score ambiguity after every answer -- display the score transparently
54
64
  - When the locked topology has multiple active components, score and target each component explicitly so depth-first clarity on one component cannot hide ambiguity in siblings
55
- - Keep prompt payloads budgeted: summarize or trim oversized initial context/history before composing question, scoring, spec, or handoff prompts
56
- - If the user's initial context is oversized, create a concise prompt-safe summary first and wait for that summary before ambiguity scoring, question generation, or downstream execution handoff
57
65
  - Route ambiguous implementation asks to clarification, deep-interview, or downstream `ralplan` before mutation; do not infer missing target, scope, acceptance criteria, or safety boundary just to start coding.
58
- - Do not proceed to execution until ambiguity ≤ the resolved threshold for this run and the user explicitly approves a scoped execution path
59
66
  - Treat user wording such as `implementation`, "implementation plan", Korean `구현`, or "구현 계획" as describing the eventual target, not permission to implement now.
60
67
  - While still in deep-interview, do not implement, edit/write code, launch implementation workers, or start task/skill/ultragoal implementation; continue interviewing for scope, risks, acceptance criteria, and unknowns.
61
68
  - When the user wants interview output for eventual implementation, say: "I can interview for an implementation plan, but I won't implement during deep-interview." Then continue clarifying scope, risks, acceptance criteria, and unknowns.
@@ -165,9 +172,8 @@ Run this phase only when the active deep-interview state or invocation indicates
165
172
  - If any value is missing, return to Phase 0 instead of using a hardcoded threshold.
166
173
  3.6. **Normalize oversized initial context before state init**:
167
174
  - Inspect the initial idea plus any pasted artifacts, logs, transcripts, or file excerpts for prompt-budget risk before writing state or generating the first question.
168
- - If the initial context is oversized or likely to crowd out downstream prompts, produce a concise prompt-safe summary that preserves user intent, decisions, constraints, unknowns, cited files/symbols, and any explicit non-goals.
175
+ - Apply the oversize summarize-first principle (DIPP-7) to produce the prompt-safe summary before state init.
169
176
  - Treat the summary as the canonical `initial_idea` and store the raw oversized material only as external/advisory context if it can be referenced safely; do not paste the raw oversized context into question-generation, ambiguity-scoring, spec-crystallization, or execution-handoff prompts.
170
- - Wait until the summary exists before ambiguity scoring, weakest-dimension selection, brownfield exploration prompts, or any bridge to `ralplan`, `ultragoal`, or `team`.
171
177
  3.7. **Artifact path discipline**:
172
178
  - Final specs MUST resolve to `.gjc/_session-{sessionid}/specs/deep-interview-{slug}.md` exactly.
173
179
  - Write final specs and all ephemeral interview artifacts through the active GJC workflow/state CLI when available.
@@ -228,7 +234,7 @@ The first line of this announcement MUST be exactly the Phase 0 threshold marker
228
234
  > **Project type:** {greenfield|brownfield}
229
235
  > **Current ambiguity:** 100% (we haven't started yet)
230
236
 
231
- Before emitting the prose lines in this announcement, apply the `<Execution_Policy>` self-proofread once; keep the required threshold marker and the quoted `{initial_idea}` unchanged.
237
+ Before emitting the prose lines in this announcement, apply the self-proofread once (DIPP-5); keep the required threshold marker and the quoted `{initial_idea}` unchanged.
232
238
 
233
239
  ## Round 0: Topology Enumeration Gate
234
240
 
@@ -362,7 +368,7 @@ Round {n} | Component: {target_component_name} | Targeting: {weakest_dimension}
362
368
 
363
369
  Options should include contextually relevant choices plus free-text, translated/localized according to `language.instruction` when present.
364
370
 
365
- After applying `language.instruction` to the visible question, options, and generated rationale, apply the self-proofread once to new prose only; preserve only the Round/Component/Targeting/Ambiguity line structure, fixed labels, numeric ambiguity value, component/target identifiers, and `deepInterview.*` metadata keys. Do not exempt generated natural-language rationale such as Why now.
371
+ After applying `language.instruction` to the visible question, options, and generated rationale, apply the self-proofread once to new prose only (DIPP-5); preserve only the Round/Component/Targeting/Ambiguity line structure, fixed labels, numeric ambiguity value, component/target identifiers, and `deepInterview.*` metadata keys. Do not exempt generated natural-language rationale such as Why now.
366
372
 
367
373
  When calling `ask`, SHOULD include optional structured metadata so the runtime can record the round without manual state writes: `deepInterview.round_id?`, `deepInterview.round`, `deepInterview.component`, `deepInterview.dimension`, and `deepInterview.ambiguity`. Keep this metadata aligned with the visible Round/Component/Targeting/Ambiguity line; if metadata cannot be supplied, the legacy formatted question text remains the fallback.
368
374
 
@@ -477,6 +483,7 @@ Respond as JSON. Include an additional "ontology" key containing the entities ar
477
483
 
478
484
  Greenfield: `ambiguity = 1 - (goal × 0.40 + constraints × 0.30 + criteria × 0.30)`
479
485
  Brownfield: `ambiguity = 1 - (goal × 0.35 + constraints × 0.25 + criteria × 0.25 + context × 0.15)`
486
+ Brownfield adds the 15% Context Clarity dimension (Goal/Constraint/Criteria become 35/25/25) because safely modifying existing code requires understanding the system being changed.
480
487
 
481
488
  **Calculate ontology stability:**
482
489
 
@@ -524,18 +531,22 @@ Round {n} complete.
524
531
 
525
532
  Apply `language.instruction` when present before showing this progress report so status text, gaps, and next-target phrasing stay in the preserved session language.
526
533
 
527
- Then apply the self-proofread once to narrative status text, generated prose cells, gaps, and next-target phrasing; preserve only table structure, fixed status labels, scores, weights, component ids, and trigger tokens.
534
+ Then apply the self-proofread once (DIPP-5) to narrative status text, generated prose cells, gaps, and next-target phrasing; preserve only table structure, fixed status labels, scores, weights, component ids, and trigger tokens.
528
535
 
529
536
  ### Step 2e: Update State
530
537
 
531
538
  Update state in two phases. The `ask` answer is first recorded by the runtime as an `answered` shell. Scoring then enriches the same round record to `scored` with global scores, per-component `topology.components[].clarity_scores`, `topology.components[].weakest_dimension`, trigger metadata, established-facts changes, ontology snapshot, `topology.last_targeted_component_id`, `auto_researched_rounds`, `auto_answered_rounds`, and `architect_failures`. When `deepInterview` ask metadata is present, no manual per-round `gjc state write` is required for the answer shell; only scoring enrichment/state maintenance remains. When metadata is absent, use the legacy `gjc state write` path to persist the new round and never patch `.gjc/_session-{sessionid}/state` directly unless an explicit force override is active.
532
539
  Also recompute and persist `ambiguity_milestone` each round (detect band transitions for the Phase 3 panel), and persist `auto_answer_streak`, `refined_rounds`, `lateral_reviews`, and `lateral_panel_failures` alongside the existing fields.
533
540
 
534
- ### Step 2f: Check Soft Limits
541
+ ### Step 2f: Check Tiered Confirmation Cadence
542
+
543
+ Confirmation cadence is tiered by round, adopted from ouroboros's ooo interview, while the hard safety cap is retained:
535
544
 
536
- - **Round 3+**: Allow early exit if user says "enough", "let's go", "build it"
537
- - **Round 10**: Show soft warning: "We're at 10 rounds. Current ambiguity: {score}%. Continue or proceed with current clarity?"
538
- - **Round 100**: Hard cap: "Maximum interview rounds reached. Proceeding with current clarity level ({score}%)."
545
+ - **Rounds 1-3 (auto-continue)**: minimum context gathering — proceed to the next question without a "continue?" prompt.
546
+ - **Rounds 4-15 (ask to continue)**: after each round, ask "Continue, or proceed with current clarity ({score}%)?" so the user controls depth.
547
+ - **Rounds 16+ (diminishing-returns warning)**: keep asking "Continue?" but prefix a diminishing-returns warning: "We're at {n} rounds (ambiguity: {score}%); each further round yields less. Continue or proceed?"
548
+ - **Round 3+ early exit**: still allow immediate exit if the user says "enough", "let's go", "build it".
549
+ - **Round 100 (hard cap)**: "Maximum interview rounds reached. Proceeding with current clarity level ({score}%)." The tiered cadence never removes this hard safety cap.
539
550
 
540
551
  ## Phase 3: Lateral Review Panel (milestone-triggered)
541
552
 
@@ -564,6 +575,24 @@ A transition occurs whenever the band changes versus the prior scored round —
564
575
 
565
576
  **Bookkeeping:** record each convened panel in `state.lateral_reviews` (round, milestone transition or pre-answer trigger, personas dispatched, findings folded). On panel spawn or validation failure, fall back silently to the normal generated question and increment `lateral_panel_failures`; do not expose tool noise unless it changes the next user-facing question. The panel is a prompt-budgeted assist layer — summarize oversized context before dispatch.
566
577
 
578
+ ### Per-question advisory fanout lanes (distinct from the milestone panel)
579
+
580
+ Separate from the milestone-triggered lateral panel above, a lightweight **advisory fanout** may assist any single question the main session is about to synthesize or route — especially when the user is terse, uncertain, or would benefit from selectable options instead of another open-ended prompt. Adopted from ouroboros's ooo interview, the standard lanes are:
581
+
582
+ - `code_context` — inspect repo-local facts and reuse existing exploration before asking the user.
583
+ - `web_context` — browse/search only when current external facts genuinely affect the answer.
584
+ - `ambiguity_contrarian` — find hidden assumptions, vague terms, missing decisions, and risky defaults.
585
+ - `answer_simplifier` — turn the question into 2-3 easy choices or one concise draft answer.
586
+ - `architecture_implications` — check whether the answer changes ownership, interfaces, rollout, or system shape.
587
+
588
+ Advisory fanout is an assist layer, not a decision maker: it never replaces or delays the single user-facing question, never adds a second question, and never forwards a synthesized answer without the user's approval, edit, or explicit auto-confirm request. It differs from the milestone panel in trigger (per-question, not band-transition) and intent (help the human answer this one question). When both would fire on the same round, run the milestone panel and fold advisory lanes into the same single question. Runtimes without a parallel subagent primitive process lanes sequentially; on lane failure, fall back silently to the normal generated question.
589
+
590
+ ### Structured adapter context and input safety (confused_terms / references / FREETEXT_FIELDS)
591
+
592
+ `confused_terms` and `references` are optional structured adapter context queued at interview start. They are **non-behavioral**: they MUST NOT alter the first question, are never inferred from vocabulary density, and glossary help is limited to explicitly-confused terms while references are used only for contrast questions. Referenced `url`/`excerpt` values are inert strings that are **never auto-fetched**. These fields ride the `ask` tool `deepInterview` metadata and are carried into the gate `stage_state` as bounded, optional values.
593
+
594
+ Input safety: user-facing free-text fields (an allowlist including `initial_context`, `user_response`, `goal`, `prompt`, `description`, `statement`) legitimately carry prose with shell metacharacters (`;`, `|`, `&`, backticks, `$()`) and must not be rejected as injection; structural fields (ids, categories, hashes) stay strictly validated. Runtime-ingested initial context, user responses, and each incoming structured adapter/LLM response are bounded by character-count DoS caps of 50,000, 10,000, and 100,000 characters respectively rather than by content inspection.
595
+
567
596
  ## Phase 4: Crystallize Spec
568
597
 
569
598
  When ambiguity ≤ threshold (or hard cap / early exit):
@@ -576,7 +605,7 @@ When ambiguity ≤ threshold (or hard cap / early exit):
576
605
 
577
606
  1. **Generate the specification** using opus model with the prompt-safe transcript. If the full interview transcript or initial context is too large, include the summary plus all concrete decisions, acceptance criteria, unresolved gaps, and ontology snapshots; never overflow the prompt with raw oversized context.
578
607
  - Apply `language.instruction` when present so user-facing prose in the spec preserves the session language; keep code identifiers, file paths, commands, JSON/settings keys, and quoted source text unchanged.
579
- - Apply the self-proofread once to newly generated spec prose before persistence, including generated natural-language table cells such as coverage notes, while preserving transcript answers, quoted/source text, code identifiers, file paths, commands, JSON/settings keys, table structure/fixed labels, and `.gjc/_session-{sessionid}/specs/deep-interview-{slug}.md` unchanged.
608
+ - Apply the self-proofread once (DIPP-5) to newly generated spec prose before persistence, including generated natural-language table cells such as coverage notes, while preserving transcript answers, quoted/source text, code identifiers, file paths, commands, JSON/settings keys, table structure/fixed labels, and `.gjc/_session-{sessionid}/specs/deep-interview-{slug}.md` unchanged.
580
609
  2. **Write the final spec through the workflow CLI**: persist the artifact at `.gjc/_session-{sessionid}/specs/deep-interview-{slug}.md`
581
610
  - Always use this exact final spec path. Prefer passing the spec markdown **inline** as the `--spec` value; only when it is too large to pass inline, stage it as a file in a system temp directory (`os.tmpdir()`/`$TMPDIR`, `/tmp`, `/var/tmp`) outside the project tree and pass that path — never write scratch specs to the repo root, the project tree, or `.gjc/`.
582
611
  - Use the native deep-interview write command with `--write --stage final --slug {slug} --spec <markdown-or-path> [--json]` for artifact and state persistence; direct `.gjc/` file edits are forbidden unless an explicit force override is active.
@@ -865,7 +894,7 @@ Why bad: 45% ambiguity means nearly half the requirements are unclear. The mathe
865
894
 
866
895
  <Escalation_And_Stop_Conditions>
867
896
  - **Hard cap at 100 rounds**: Proceed with whatever clarity exists, noting the risk
868
- - **Soft warning at 10 rounds**: Offer to continue or proceed
897
+ - **Tiered confirmation cadence**: rounds 1-3 auto-continue, rounds 4-15 ask to continue, rounds 16+ ask with a diminishing-returns warning
869
898
  - **Early exit (round 3+)**: Allow with warning if ambiguity > threshold
870
899
  - **User says "stop", "cancel", "abort"**: Stop immediately, save state for resume
871
900
  - **Ambiguity stalls** (same score +-0.05 for 3 rounds): Activate Ontologist mode to reframe
@@ -900,7 +929,7 @@ Optional settings in `.gjc/settings.json`:
900
929
  "deepInterview": {
901
930
  "ambiguityThreshold": <resolvedThreshold>,
902
931
  "maxRounds": 100,
903
- "softWarningRounds": 10,
932
+ "softWarningRounds": 16,
904
933
  "minRoundsBeforeExit": 3,
905
934
  "enableChallengeAgents": true,
906
935
  "autoExecuteOnComplete": false,
@@ -939,14 +968,6 @@ The ralplan pre-approval gate already redirects vague prompts to planning. Deep
939
968
  Vague prompt → ralplan gate → deep-interview (if extremely vague) → ralplan (with clear spec) → pending approval → explicitly approved execution
940
969
  ```
941
970
 
942
- ## Brownfield vs Greenfield Weights
943
-
944
- See "Calculate ambiguity" in Step 2c for the weighted formulas. Brownfield adds a 15% Context Clarity dimension (Goal/Constraint/Criteria become 35/25/25) because safely modifying existing code requires understanding the system being changed.
945
-
946
- ## Lateral Review Panel
947
-
948
- See Phase 3 for the full persona set (researcher/contrarian/simplifier, plus architect on scope change), the milestone bands, and the parallel independent-context dispatch.
949
-
950
971
  ## Ambiguity Score Interpretation
951
972
 
952
973
  | Score Range | Meaning | Action |
@@ -24,12 +24,6 @@ Ralplan is the consensus planning workflow. It triggers iterative planning with
24
24
  - `--architect openai-code` / `--critic openai-code`: Use OpenAI code for that review pass when available; otherwise note the fallback and use default GJC review.
25
25
  - `--write --stage <type> --stage_n <N> --artifact <markdown file path or markdown string>`: Native writer for Planner/Architect/Critic/revision/ADR/final pending-approval markdown under `.gjc/_session-{sessionid}/plans/ralplan/<run-id>/`; do not edit `.gjc/` directly.
26
26
 
27
- ## Usage with interactive mode
28
-
29
- ```
30
- /skill:ralplan --interactive "task description"
31
- ```
32
-
33
27
  ## Corrupt current-session state recovery
34
28
 
35
29
  For corrupt, tampered, unreadable, or stale current-session ralplan state, run `gjc state clear --force --mode ralplan` scoped by `--session-id`, command payload, or `GJC_SESSION_ID`; it clears only ralplan state for that session.
@@ -7,25 +7,23 @@ source: "forked from upstream team skill and rebranded for GJC"
7
7
 
8
8
  # Team Skill
9
9
 
10
+ ## Purpose & Principles
11
+
10
12
  `$team` is the tmux-based multi-worker execution mode for GJC. It starts real GJC worker CLI sessions by splitting the current tmux leader window and coordinates them through `.gjc/_session-{sessionid}/state/team/...` files plus CLI team interop (`gjc team api ...`) and state files.
11
13
 
12
14
  This skill is operationally sensitive. Treat it as an operator workflow, not a generic prompt pattern. In GJC App or plain outside-tmux sessions, do not present `$team` / `gjc team` as directly available; launch GJC CLI from shell first, or stay on the nearest app-safe surface until the user explicitly wants the tmux runtime.
13
15
 
14
- ## Corrupt current-session state recovery
15
-
16
- When team detects its own current-session state is corrupt, tampered, unreadable, or stale on resume, run `gjc state clear --force --mode team` before reseeding or restarting. Scope the clear to the current session via `--session-id`, the command payload, or `GJC_SESSION_ID`; it clears only team state for that session and never clears other skills or sessions.
17
-
18
- ## Team vs Native Subagents
19
-
20
16
  - Use **GJC native subagents** for bounded, in-session parallelism where one leader thread can fan out a few independent subtasks and wait for them directly.
21
17
  - Use **`gjc team`** when you need durable visible tmux workers, shared task state, worker mailbox files, worktrees, explicit lifecycle control, or long-running execution that must survive beyond one local reasoning burst.
22
18
  - Native subagents can complement team execution, but they do **not** replace the tmux team runtime's stateful coordination contract.
23
19
 
24
- ## What This Skill Must Do
20
+ Use the shared workflow guidance pattern: outcome-first framing, concise visible updates for multi-step work, local overrides for the active workflow branch, validation proportional to risk, explicit stop rules, and automatic continuation for safe reversible steps. Ask only for material, destructive, credentialed, external-production, or preference-dependent branches.
25
21
 
26
- ## GPT-5.5 Guidance Alignment
22
+ ## Corrupt current-session state recovery
27
23
 
28
- Use the shared workflow guidance pattern: outcome-first framing, concise visible updates for multi-step work, local overrides for the active workflow branch, validation proportional to risk, explicit stop rules, and automatic continuation for safe reversible steps. Ask only for material, destructive, credentialed, external-production, or preference-dependent branches.
24
+ When team detects its own current-session state is corrupt, tampered, unreadable, or stale on resume, run `gjc state clear --force --mode team` before reseeding or restarting. Scope the clear to the current session via `--session-id`, the command payload, or `GJC_SESSION_ID`; it clears only team state for that session and never clears other skills or sessions.
25
+
26
+ ## What This Skill Must Do
29
27
 
30
28
  When user triggers `$team`, the agent must:
31
29
 
@@ -50,8 +50,6 @@ goal({"op":"resume"})
50
50
  ```
51
51
  `drop` clears the active goal without exiting goal mode; `resume` reactivates a paused goal.
52
52
 
53
- Durable completion is single-source: `goals.json` defines which goals exist and their required state, while `ledger.jsonl` provides the receipt proof used to verify completion. Inline goal state is UX-only and is reconciled by the agent after durable completion, not by CLI checkpoints or hooks.
54
-
55
53
  ## Create goals
56
54
 
57
55
  1. Decide on the brief. To produce **multiple** stories, separate them with a reserved `@goal:` delimiter line; the title follows on the same line and the objective is everything beneath it until the next delimiter:
@@ -32,8 +32,8 @@ export default {
32
32
  signal: opts.signal,
33
33
  sessionId: namespaceSessionId(opts.sessionId),
34
34
  kernelMode,
35
- sessionFile: opts.sessionFile,
36
- artifactsDir: opts.session.getArtifactsDir?.() ?? undefined,
35
+ sessionFile: undefined,
36
+ artifactsDir: undefined,
37
37
  kernelOwnerId: opts.kernelOwnerId,
38
38
  reset: opts.reset,
39
39
  artifactPath: opts.artifactPath,