okstra 0.32.0 → 0.33.0

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.
@@ -1314,11 +1314,15 @@ STEPS: list[Step] = [
1314
1314
  and s.use_defaults is None),
1315
1315
  build=_build_defaults_or_custom, submit=_submit_defaults_or_custom,
1316
1316
  owns=("use_defaults",)),
1317
- # Customize branch workers override only when the profile actually
1318
- # has analyser-candidate workers (required ∪ optional, minus report-writer).
1317
+ # Worker roster is ALWAYS prompted (independent of the defaults /
1318
+ # customize branch) when the profile has analyser-candidate workers
1319
+ # (required ∪ optional, minus report-writer). Users repeatedly hit
1320
+ # the failure mode where the lead silently picked "Use defaults"
1321
+ # and the worker prompt never appeared — defaults should govern
1322
+ # model choice, not worker selection. `implementation` task-type is
1323
+ # still skipped because it runs lead + executor only.
1319
1324
  Step(S_WORKERS_OVERRIDE,
1320
- applies=lambda s: (s.use_defaults is False
1321
- and s.task_type != "implementation"
1325
+ applies=lambda s: (s.task_type != "implementation"
1322
1326
  and any(
1323
1327
  w != "report-writer"
1324
1328
  for w in (s.profile_workers
@@ -1451,10 +1455,17 @@ def _identity_ready(s: WizardState) -> bool:
1451
1455
  def _ready_for_confirm(s: WizardState) -> bool:
1452
1456
  if s.use_defaults is None:
1453
1457
  return False
1458
+ # Worker roster is required regardless of the defaults / customize
1459
+ # branch. Skipping this check let the lead drop into confirm with no
1460
+ # worker prompt ever shown — the very failure mode this gate exists
1461
+ # to prevent.
1462
+ workers_step = STEP_BY_ID[S_WORKERS_OVERRIDE]
1463
+ if workers_step.applies(s):
1464
+ return False
1454
1465
  if s.use_defaults:
1455
1466
  return True
1456
1467
  # customize: every customize-branch step must be answered or not-applicable.
1457
- custom_ids = [S_WORKERS_OVERRIDE, S_LEAD_MODEL, S_EXECUTOR_MODEL,
1468
+ custom_ids = [S_LEAD_MODEL, S_EXECUTOR_MODEL,
1458
1469
  S_CLAUDE_MODEL, S_CODEX_MODEL, S_GEMINI_MODEL,
1459
1470
  S_REPORT_WRITER_MODEL, S_DIRECTIVE, S_RELATED_TASKS,
1460
1471
  S_CLARIFICATION, S_PR_TEMPLATE, S_PR_TEMPLATE_SCOPE]
@@ -245,7 +245,7 @@ Every worker result file MUST begin with a YAML frontmatter block. The values ar
245
245
  title: OKSTRA <Worker Role> Result - <task-key>
246
246
  id: "<task-key with ':' replaced by '-'>"
247
247
  aliases: ["<id>-<task-type>"]
248
- tags: ["obsidian", "okstra", "worker-result", "<task-type>"]
248
+ tags: ["worker-result", "<task-type>"]
249
249
  taskType: "<task-type>"
250
250
  workerId: "<claude|codex|gemini|report-writer>"
251
251
  task-id: "<task-id>"
@@ -262,7 +262,7 @@ Concrete example for a `claude-worker` result on task-key `fontsninja-classifier
262
262
  title: OKSTRA Claude Worker Result - fontsninja-classifier-v2:DEV-9388:DEV-9429
263
263
  id: "fontsninja-classifier-v2-DEV-9388-DEV-9429"
264
264
  aliases: ["fontsninja-classifier-v2-DEV-9388-DEV-9429-implementation"]
265
- tags: ["obsidian", "okstra", "worker-result", "implementation"]
265
+ tags: ["worker-result", "implementation"]
266
266
  taskType: "implementation"
267
267
  workerId: "claude"
268
268
  task-id: "DEV-9429"
@@ -374,7 +374,7 @@ without proceeding — this is the contractual replacement for the previous
374
374
  empty run-level error logs in production.
375
375
 
376
376
  - `cli-failure` events are recorded by the wrapper subagent itself (Codex / Gemini), but **directly to the run-level error log** via `okstra-error-log.py append-observed --error-type cli-failure ...` — NOT via the sidecar. The sidecar is an in-process tool-failure channel only.
377
- - **Wrapper invocation arity.** Both `okstra-codex-exec.sh` and `okstra-gemini-exec.sh` accept four required positional arguments plus an optional fifth `<role>`: `<project-root> <model> <prompt-path> <worktree-path> [<role>]`. The fourth (worktree) argument is **mandatory for implementation phase** and optional otherwise. For codex it becomes `--add-dir <worktree>` (sandbox write access); for gemini it is appended to `--include-directories`. Omitting it during implementation causes the codex sandbox to reject every Edit/Write targeting the worktree with EPERM. Workers extract the path from the `**Worktree:**` / `EXECUTOR_WORKTREE_PATH` / `cwd for every mutating command:` line in the lead prompt. The optional fifth `<role>` is the trace-pane label suffix (e.g. `codex-<role>-trace`); always pass the literal string `worker` so the dispatch is self-describing (the wrapper defaults to `worker` if omitted).
377
+ - **Wrapper invocation arity.** Both `okstra-codex-exec.sh` and `okstra-gemini-exec.sh` accept four required positional arguments plus an optional fifth `<role>`: `<project-root> <model> <prompt-path> <worktree-path> [<role>]`. The fourth (worktree) argument is **mandatory for implementation phase** and optional otherwise. For codex it becomes `--add-dir <worktree>` (sandbox write access); for gemini it is appended to `--include-directories`. Omitting it during implementation causes the codex sandbox to reject every Edit/Write targeting the worktree with EPERM. Workers extract the path from the `**Worktree:**` / `EXECUTOR_WORKTREE_PATH` / `cwd for every mutating command:` line in the lead prompt. The optional fifth `<role>` is folded into both the caller (worker) pane title `<cli>-<role>-<pid>` and the sibling trace-pane title `<cli>-<role>-<pid>-trace` (e.g. `codex-worker-93421` ↔ `codex-worker-93421-trace`). `<pid>` is the wrapper's own PID and disambiguates concurrent dispatches of the same role. Always pass the literal string `worker` so the dispatch is self-describing (the wrapper defaults to `worker` if omitted).
378
378
  - **Background dispatch + polling contract (Codex / Gemini wrappers).** Both wrapper subagents MUST dispatch `okstra-codex-exec.sh` / `okstra-gemini-exec.sh` via `Bash(run_in_background: true)` and poll with `BashOutput(bash_id)` until the shell reports `status == "completed"`, capped at 30 minutes (1800s) of wall-clock elapsed time. `BashOutput` itself is the wait primitive — call it back-to-back; do NOT insert a standalone `sleep` between polls. The Claude Code harness blocks `sleep` calls of 5 seconds or longer as a circumvention vector and explicitly forbids chaining shorter sleeps inside until-loops to work around the block. Workers that hit the contract bug must NOT self-recover with `until ...; do sleep 2; done` wrappers — that path violates the harness anti-circumvention rule, even though it superficially "works". The legacy "single foreground `Bash` with 120000ms timeout" rule, and the subsequent "60-second cadence with `sleep 60` between polls" rule, are both retired. The current rule applies in **every phase** (analysis runs typically complete in 1–2 `BashOutput` calls, so there is no regression for short jobs). Recording responsibilities:
379
379
  - Successful completion: return the wrapper's accumulated stdout from the final `BashOutput`. No log entry.
380
380
  - Non-zero `exit_code` reported by `BashOutput`: record a `cli-failure` to the run-level error log with the real `exit_code` and observed `duration-ms`.