okstra 0.84.0 → 0.86.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.
- package/package.json +1 -1
- package/runtime/BUILD.json +2 -2
- package/runtime/agents/workers/codex-worker.md +1 -1
- package/runtime/agents/workers/gemini-worker.md +1 -1
- package/runtime/bin/okstra-claude-exec.sh +61 -2
- package/runtime/bin/okstra-codex-exec.sh +10 -9
- package/runtime/bin/okstra-gemini-exec.sh +11 -10
- package/runtime/prompts/{okstra-coding-preflight → coding-preflight}/scripts/preedit-check.sh +3 -3
- package/runtime/prompts/lead/convergence.md +3 -2
- package/runtime/prompts/lead/okstra-lead-contract.md +1 -1
- package/runtime/templates/reports/settings.template.json +1 -1
- package/src/doctor.mjs +6 -1
- /package/runtime/prompts/{okstra-coding-preflight → coding-preflight}/architectures/hexagonal.md +0 -0
- /package/runtime/prompts/{okstra-coding-preflight → coding-preflight}/clean-code.md +0 -0
- /package/runtime/prompts/{okstra-coding-preflight → coding-preflight}/frameworks/node-server.md +0 -0
- /package/runtime/prompts/{okstra-coding-preflight → coding-preflight}/languages/java.md +0 -0
- /package/runtime/prompts/{okstra-coding-preflight → coding-preflight}/languages/javascript-typescript.md +0 -0
- /package/runtime/prompts/{okstra-coding-preflight → coding-preflight}/languages/kotlin.md +0 -0
- /package/runtime/prompts/{okstra-coding-preflight → coding-preflight}/languages/python.md +0 -0
- /package/runtime/prompts/{okstra-coding-preflight → coding-preflight}/languages/rust.md +0 -0
- /package/runtime/prompts/{okstra-coding-preflight → coding-preflight}/languages/sql.md +0 -0
- /package/runtime/prompts/{okstra-coding-preflight → coding-preflight}/overview.md +0 -0
package/package.json
CHANGED
package/runtime/BUILD.json
CHANGED
|
@@ -30,7 +30,7 @@ You are a Codex worker agent. Your job is to execute the OpenAI Codex CLI and re
|
|
|
30
30
|
$HOME/.okstra/bin/okstra-codex-exec.sh "<absolute-project-root>" "<assigned-model-execution-value>" "<absolute-prompt-history-path>" [<absolute-worktree-path>] [<role>]
|
|
31
31
|
```
|
|
32
32
|
|
|
33
|
-
The fifth argument `<role>` is folded into both the caller (worker) pane title `codex-<role
|
|
33
|
+
The fifth argument `<role>` is folded into both the caller (worker) pane title `codex-<role>` and the sibling trace-pane title `codex-<role>-tail`. `<role>` carries the dispatched Agent `name` minus the `codex-` prefix, so the pane title equals the FleetView teammate name (`codex-worker-reverify-r1`, `codex-executor`, …) instead of a generic `worker`. Pass the value of the dispatch prompt's `**Pane role:**` line verbatim — Lead injects it on every CLI dispatch: `**Pane role:** worker-reverify-r1` on a convergence reverify, `**Pane role:** worker-critic` on a critic pass, `**Pane role:** executor` on an `implementation` Executor dispatch, `**Pane role:** verifier` on an `implementation` / `final-verification` verifier dispatch, and `**Pane role:** worker` on a plain analysis dispatch. The wrapper defaults to `worker` when the argument is omitted, but pass it explicitly so the pane title is self-describing.
|
|
34
34
|
|
|
35
35
|
The fourth argument is **mandatory for implementation phase** and optional otherwise. It must be the literal `EXECUTOR_WORKTREE_PATH` recorded in the run context; the wrapper forwards it to codex as `--add-dir`, which grants the codex sandbox write access to the worktree (where all implementation-phase mutations occur). Without it, codex's `workspace-write` sandbox is anchored only at `<project-root>` and rejects every Edit/Write that targets the worktree (EPERM), which is the failure pattern that originally motivated this argument.
|
|
36
36
|
|
|
@@ -30,7 +30,7 @@ You are a Gemini worker agent. Your job is to execute the Google Gemini CLI and
|
|
|
30
30
|
$HOME/.okstra/bin/okstra-gemini-exec.sh "<absolute-project-root>" "<assigned-model-execution-value>" "<absolute-prompt-history-path>" [<absolute-worktree-path>] [<role>]
|
|
31
31
|
```
|
|
32
32
|
|
|
33
|
-
The fifth argument `<role>` is folded into both the caller (worker) pane title `gemini-<role
|
|
33
|
+
The fifth argument `<role>` is folded into both the caller (worker) pane title `gemini-<role>` and the sibling trace-pane title `gemini-<role>-tail`. `<role>` carries the dispatched Agent `name` minus the `gemini-` prefix, so the pane title equals the FleetView teammate name (`gemini-worker-reverify-r1`, `gemini-executor`, …) instead of a generic `worker`. Pass the value of the dispatch prompt's `**Pane role:**` line verbatim — Lead injects it on every CLI dispatch: `**Pane role:** worker-reverify-r1` on a convergence reverify, `**Pane role:** worker-critic` on a critic pass, `**Pane role:** executor` on an `implementation` Executor dispatch, `**Pane role:** verifier` on an `implementation` / `final-verification` verifier dispatch, and `**Pane role:** worker` on a plain analysis dispatch. The wrapper defaults to `worker` when the argument is omitted, but pass it explicitly so the pane title is self-describing.
|
|
34
34
|
|
|
35
35
|
The fourth argument is **mandatory for implementation phase** and optional otherwise. It must be the literal `EXECUTOR_WORKTREE_PATH` recorded in the run context; the wrapper appends it to gemini's `--include-directories` list so the model can both read and operate on the worktree alongside project-root.
|
|
36
36
|
|
|
@@ -39,6 +39,25 @@ if ! command -v claude >/dev/null 2>&1; then
|
|
|
39
39
|
exit 127
|
|
40
40
|
fi
|
|
41
41
|
|
|
42
|
+
# Grant tool access to the implementation worktree (and the main repo's shared
|
|
43
|
+
# .git for linked-worktree commits) when one is supplied. The executor mutates
|
|
44
|
+
# a git worktree that lives outside project-root; without --add-dir Claude
|
|
45
|
+
# Code's Edit/Write tools cannot reach it. Mirrors okstra-codex-exec.sh.
|
|
46
|
+
extra_args=()
|
|
47
|
+
if [[ -n "$worktree_path" ]]; then
|
|
48
|
+
extra_args+=(--add-dir "$worktree_path")
|
|
49
|
+
if command -v git >/dev/null 2>&1; then
|
|
50
|
+
common_git_dir=$(git -C "$worktree_path" rev-parse --git-common-dir 2>/dev/null || true)
|
|
51
|
+
if [[ -n "$common_git_dir" ]]; then
|
|
52
|
+
[[ "$common_git_dir" != /* ]] && common_git_dir="$worktree_path/$common_git_dir"
|
|
53
|
+
if [[ -d "$common_git_dir" ]]; then
|
|
54
|
+
common_git_dir=$(cd "$common_git_dir" && pwd -P)
|
|
55
|
+
extra_args+=(--add-dir "$common_git_dir")
|
|
56
|
+
fi
|
|
57
|
+
fi
|
|
58
|
+
fi
|
|
59
|
+
fi
|
|
60
|
+
|
|
42
61
|
log_path="${prompt_path%.md}.log"
|
|
43
62
|
[[ "$log_path" == "$prompt_path" ]] && log_path="${prompt_path}.log"
|
|
44
63
|
: > "$log_path"
|
|
@@ -62,10 +81,50 @@ trap _okstra_status_finish EXIT
|
|
|
62
81
|
|
|
63
82
|
cd "$project_root"
|
|
64
83
|
set +e
|
|
65
|
-
claude -p --model "$model" --output-format=stream-json
|
|
84
|
+
claude -p --model "$model" ${extra_args[@]+"${extra_args[@]}"} --output-format=stream-json \
|
|
85
|
+
< "$prompt_path" \
|
|
66
86
|
> >(tee -a "$log_path") \
|
|
67
|
-
2> >(tee -a "$log_path" >&2)
|
|
87
|
+
2> >(tee -a "$log_path" >&2) &
|
|
88
|
+
claude_pid=$!
|
|
89
|
+
|
|
90
|
+
# Idle watchdog: if the live log sees no write for $idle_timeout_secs, SIGTERM
|
|
91
|
+
# claude (5s grace, then SIGKILL) and mark the status sidecar timed out, so a
|
|
92
|
+
# silent hang is bounded instead of stalling the lead. Pass 0 to disable.
|
|
93
|
+
watchdog_pid=""
|
|
94
|
+
if (( idle_timeout_secs > 0 )); then
|
|
95
|
+
poll_interval=$(( idle_timeout_secs / 20 ))
|
|
96
|
+
(( poll_interval < 5 )) && poll_interval=5
|
|
97
|
+
(( poll_interval > 30 )) && poll_interval=30
|
|
98
|
+
(
|
|
99
|
+
while kill -0 "$claude_pid" 2>/dev/null; do
|
|
100
|
+
sleep "$poll_interval"
|
|
101
|
+
kill -0 "$claude_pid" 2>/dev/null || exit 0
|
|
102
|
+
last_mtime=$(stat -f %m "$log_path" 2>/dev/null || stat -c %Y "$log_path" 2>/dev/null || printf '0')
|
|
103
|
+
now=$(date +%s)
|
|
104
|
+
idle=$(( now - last_mtime ))
|
|
105
|
+
if (( idle >= idle_timeout_secs )); then
|
|
106
|
+
printf '\n[okstra wrapper] idle-watchdog: %ds without stdout — terminating claude (pid=%d)\n' \
|
|
107
|
+
"$idle" "$claude_pid" >> "$log_path" 2>&1 || true
|
|
108
|
+
python3 "$script_dir/okstra-wrapper-status.py" \
|
|
109
|
+
timeout "$status_path" "$now" "$idle" >>"$log_path" 2>&1 || true
|
|
110
|
+
kill -TERM "$claude_pid" 2>/dev/null || true
|
|
111
|
+
sleep 5
|
|
112
|
+
kill -KILL "$claude_pid" 2>/dev/null || true
|
|
113
|
+
exit 0
|
|
114
|
+
fi
|
|
115
|
+
done
|
|
116
|
+
) &
|
|
117
|
+
watchdog_pid=$!
|
|
118
|
+
fi
|
|
119
|
+
|
|
120
|
+
wait "$claude_pid"
|
|
68
121
|
claude_exit=$?
|
|
69
122
|
set -e
|
|
70
123
|
|
|
124
|
+
if [[ -n "$watchdog_pid" ]]; then
|
|
125
|
+
kill "$watchdog_pid" 2>/dev/null || true
|
|
126
|
+
wait "$watchdog_pid" 2>/dev/null || true
|
|
127
|
+
fi
|
|
128
|
+
wait 2>/dev/null || true
|
|
129
|
+
|
|
71
130
|
exit "$claude_exit"
|
|
@@ -211,11 +211,12 @@ if type okstra_resolve_caller_pane >/dev/null 2>&1; then
|
|
|
211
211
|
caller_pane="$(okstra_resolve_caller_pane)"
|
|
212
212
|
fi
|
|
213
213
|
|
|
214
|
-
# Pane titles:
|
|
215
|
-
#
|
|
216
|
-
#
|
|
217
|
-
# the
|
|
218
|
-
|
|
214
|
+
# Pane titles: the caller (worker) pane gets `codex-<role>`; the sibling trace
|
|
215
|
+
# pane is that same caller title with a `-tail` suffix, so the operator can
|
|
216
|
+
# visually pair `<caller> ↔ <caller>-tail`. `role` carries the dispatched Agent
|
|
217
|
+
# name minus the `codex-` prefix (e.g. `worker-reverify-r1`, `executor`), so the
|
|
218
|
+
# pane title equals the FleetView teammate name instead of a generic `worker`.
|
|
219
|
+
pane_label="codex-${role}"
|
|
219
220
|
trace_label="${pane_label}-tail"
|
|
220
221
|
|
|
221
222
|
# Capture the caller pane's current title so the EXIT trap can restore it
|
|
@@ -251,13 +252,13 @@ fi
|
|
|
251
252
|
# for the wrapper to exit. This fires in every phase the wrapper is invoked
|
|
252
253
|
# from (analysis, error-analysis, implementation-planning, implementation,
|
|
253
254
|
# …) — long-running codex dispatches are not implementation-specific. The
|
|
254
|
-
# new pane carries the title `codex-<role
|
|
255
|
-
# pair it with its caller pane (`codex-<role
|
|
255
|
+
# new pane carries the title `codex-<role>-tail` so the operator can
|
|
256
|
+
# pair it with its caller pane (`codex-<role>`). The split is
|
|
256
257
|
# explicitly anchored to the caller pane (`-t "$caller_pane"`) to avoid
|
|
257
258
|
# attaching to tmux's idle active pane. `role` is the optional 5th
|
|
258
259
|
# positional arg (defaults to `worker`); callers that dispatch a different
|
|
259
|
-
# role (e.g. `executor`) must pass it explicitly
|
|
260
|
-
#
|
|
260
|
+
# role (e.g. `executor`, `worker-reverify-r1`) must pass it explicitly so the
|
|
261
|
+
# pane title names the actual job.
|
|
261
262
|
# The pane uses `tail -F` (follow-by-name) so it survives any truncation a
|
|
262
263
|
# re-dispatch performs on the same log path. We gate on a resolved
|
|
263
264
|
# `$caller_pane` (non-empty only when tmux is reachable) rather than the
|
|
@@ -153,11 +153,12 @@ if type okstra_resolve_caller_pane >/dev/null 2>&1; then
|
|
|
153
153
|
caller_pane="$(okstra_resolve_caller_pane)"
|
|
154
154
|
fi
|
|
155
155
|
|
|
156
|
-
# Pane titles:
|
|
157
|
-
#
|
|
158
|
-
#
|
|
159
|
-
# the
|
|
160
|
-
|
|
156
|
+
# Pane titles: the caller (worker) pane gets `gemini-<role>`; the sibling trace
|
|
157
|
+
# pane is that same caller title with a `-tail` suffix, so the operator can
|
|
158
|
+
# visually pair `<caller> ↔ <caller>-tail`. `role` carries the dispatched Agent
|
|
159
|
+
# name minus the `gemini-` prefix (e.g. `worker-reverify-r1`, `executor`), so the
|
|
160
|
+
# pane title equals the FleetView teammate name instead of a generic `worker`.
|
|
161
|
+
pane_label="gemini-${role}"
|
|
161
162
|
trace_label="${pane_label}-tail"
|
|
162
163
|
|
|
163
164
|
# Capture the caller pane's current title so the EXIT trap can restore it
|
|
@@ -191,13 +192,13 @@ fi
|
|
|
191
192
|
# When a tmux session is reachable, split a sibling pane tailing the log so
|
|
192
193
|
# the operator can watch progress live. This fires in every phase the
|
|
193
194
|
# wrapper is invoked from — long-running gemini dispatches are not
|
|
194
|
-
# implementation-specific. Title `gemini-<role
|
|
195
|
-
# can pair it with its caller pane (`gemini-<role
|
|
195
|
+
# implementation-specific. Title `gemini-<role>-tail` so the operator
|
|
196
|
+
# can pair it with its caller pane (`gemini-<role>`). The split is
|
|
196
197
|
# explicitly anchored to the caller pane to avoid attaching to tmux's idle
|
|
197
198
|
# active pane. `role` is the optional 5th positional arg (defaults to
|
|
198
|
-
# `worker`); callers that dispatch a different role
|
|
199
|
-
#
|
|
200
|
-
#
|
|
199
|
+
# `worker`); callers that dispatch a different role (e.g. `worker-reverify-r1`)
|
|
200
|
+
# must pass it explicitly so the pane title names the actual job.
|
|
201
|
+
# We gate on a resolved `$caller_pane`
|
|
201
202
|
# (non-empty only when tmux is reachable) rather than the now-stripped
|
|
202
203
|
# `$TMUX`. See the codex wrapper for the full design rationale and the
|
|
203
204
|
# silent-degrade failure model.
|
package/runtime/prompts/{okstra-coding-preflight → coding-preflight}/scripts/preedit-check.sh
RENAMED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env bash
|
|
2
|
-
# PreToolUse hook for
|
|
2
|
+
# PreToolUse hook for coding-preflight.
|
|
3
3
|
#
|
|
4
4
|
# Inspects the target file path of a Write/Edit/MultiEdit/NotebookEdit
|
|
5
5
|
# call. If the extension matches a language covered by this skill,
|
|
@@ -68,8 +68,8 @@ fi
|
|
|
68
68
|
|
|
69
69
|
: > "$marker"
|
|
70
70
|
|
|
71
|
-
skill_root="$HOME/.okstra/prompts/
|
|
72
|
-
msg="[
|
|
71
|
+
skill_root="$HOME/.okstra/prompts/coding-preflight"
|
|
72
|
+
msg="[coding-preflight] About to edit a ${lang} file (${file_path}). Before writing, you MUST Read ${skill_root}/${ref} plus ${skill_root}/clean-code.md (the skill is user-invocable:false — read the files directly).${extra_hint} If the project uses ports-and-adapters (domain/ + ports/ + adapters/, *.port.* files), also Read ${skill_root}/architecture/hexagonal.md. (Fires once per session per language.)"
|
|
73
73
|
|
|
74
74
|
jq -nc \
|
|
75
75
|
--arg event "PreToolUse" \
|
|
@@ -266,8 +266,9 @@ Agent(
|
|
|
266
266
|
|
|
267
267
|
- Agent Teams mode: Spawn within an existing team
|
|
268
268
|
- Fallback mode: Spawn with `run_in_background: true` and no `team_name`
|
|
269
|
+
- CLI (Codex / Gemini) worker: inject `**Pane role:** worker-reverify-r<N>` (the Agent `name` minus the `<cli>-` prefix) into the reverify prompt body so the tmux trace pane reads `<cli>-worker-reverify-r<N>` per [okstra-lead-contract](./okstra-lead-contract.md) "Agent `name` on dispatch".
|
|
269
270
|
|
|
270
|
-
For `tmux-pane` backend runs, do not use the Agent snippet. For each reverify round, write a jobs file at `runs/<task-type>/state/reverify-jobs-r<N>-<task-type>-<seq>.json` with `dispatchKind: "reverify-r<N>"` and worker entries containing `workerId`, `provider`, `role
|
|
271
|
+
For `tmux-pane` backend runs, do not use the Agent snippet. For each reverify round, write a jobs file at `runs/<task-type>/state/reverify-jobs-r<N>-<task-type>-<seq>.json` with `dispatchKind: "reverify-r<N>"` and worker entries containing `workerId`, `provider`, `role` (set to `worker-reverify-r<N>` for the pane title), `modelExecutionValue`, `promptPath`, `resultPath`, `workerResultPath`, and `completionPaths`; then run `okstra team dispatch --project-root <dir> --run-manifest <path> --dispatch-kind reverify-r<N> --jobs-file <jobs-file>` followed by `okstra team await --project-root <dir> --run-manifest <path>`.
|
|
271
272
|
|
|
272
273
|
|
|
273
274
|
**Completion detection per round (BLOCKING).** Each round dispatches a variable set (1..N) of reverify workers asynchronously; the `Agent(... team_name ...)` calls return `Spawned successfully` immediately, which is NOT completion. Lead MUST detect each round's completion via the self-scheduled polling protocol in [team-contract](./team-contract.md) "Worker-completion detection (self-scheduled polling)", with the pending set reconstructed from that round's dispatched workers' Result Paths — do NOT restate the algorithm here. Lead MUST NOT treat the spawn ack as completion and MUST NOT end its turn with a prose "waiting" statement.
|
|
@@ -523,7 +524,7 @@ The critic input is the Round 0 consolidated finding list. Reverify rounds only
|
|
|
523
524
|
- **Gap verification + merge**: only after BOTH the finding-convergence loop has exited AND the critic result is collected, and BEFORE the Phase 6 report-writer dispatch. If the loop exited `aborted-non-result`, do NOT dispatch a gap-verification round — surface the gaps as unverified `clarification` items per §"Gap verification" and record that fact.
|
|
524
525
|
|
|
525
526
|
### Dispatch (reused worker)
|
|
526
|
-
Dispatch ONE pass to the `config.critic.provider`'s existing subagent (`claude-worker` / `codex-worker` / `gemini-worker`) with `model = config.critic.modelExecutionValue` — no new agent type
|
|
527
|
+
Dispatch ONE pass to the `config.critic.provider`'s existing subagent (`claude-worker` / `codex-worker` / `gemini-worker`) with `model = config.critic.modelExecutionValue` — no new agent type, `name: "<provider>-worker-critic"`. If `config.critic.modelExecutionValue` is null/empty (model could not be resolved), skip the critic pass and record `critic-skipped: model-unresolved` in the convergence state rather than dispatching with no model. For a CLI (Codex / Gemini) critic dispatch, inject `**Pane role:** worker-critic` into the prompt body so the trace pane reads `<cli>-worker-critic` per [okstra-lead-contract](./okstra-lead-contract.md) "Agent `name` on dispatch". Result path: `runs/<task-type>/worker-results/<provider>-critic-<task-type>-<seq>.md`. The critic prompt seeds the consolidated findings and asks ONLY for coverage gaps:
|
|
527
528
|
|
|
528
529
|
```
|
|
529
530
|
You are the coverage critic for <task-key>. Below are the consolidated findings
|
|
@@ -222,7 +222,7 @@ If the launch prompt contains `Tmux Worker Dispatch Gate`, Phase 3 is recorded a
|
|
|
222
222
|
|
|
223
223
|
Spawn **analysis workers only** in the same turn (Phase 4 in Teams mode; Phase 5 with `run_in_background: true` and no `team_name` when Teams unavailable). Preserve exact roster, role labels, assigned models from the task bundle.
|
|
224
224
|
|
|
225
|
-
**Agent `name` on dispatch (BLOCKING — token-usage attribution depends on it).** Every analysis-worker `Agent(...)` call MUST set `name: "<workerId>-worker"` — `name: "claude-worker"` / `name: "codex-worker"` / `name: "gemini-worker"` — exactly as the report-writer dispatch sets `name: "report-writer"` ([report-writer](./report-writer.md)). The Agent harness records this `name` as `agentName` in the subagent session jsonl, and the Phase 7 token collector matches each worker's session by that `agentName` (`okstra_token_usage/collect.py`). A worker dispatched **without** `name` produces a session with no `agentName`; the collector cannot attribute it and records the worker as `source: "unavailable"` even though the session exists and is team-tagged (observed in `dev-9692` error-analysis: `claude`/`codex` workers dispatched without `name` → both `unavailable`, while the named `report-writer` collected normally). Convergence reverify dispatches keep the prefix (`<workerId>-worker-reverify-r<N>`). For `implementation` and `final-verification` dispatches the `name` carries the **functional role** so the FleetView teammate pill and trace panes name the actual job instead of a generic `worker`: the Executor dispatch sets `name: "<workerId>-executor"` (e.g. `codex-executor`) and every verifier dispatch sets `name: "<workerId>-verifier"` (e.g. `claude-verifier`). These role suffixes still attribute correctly — the collector matches any `agentName` beginning `<workerId>-` (`okstra_token_usage/collect.py` `match_prefixes`). **For CLI (Codex / Gemini)
|
|
225
|
+
**Agent `name` on dispatch (BLOCKING — token-usage attribution depends on it).** Every analysis-worker `Agent(...)` call MUST set `name: "<workerId>-worker"` — `name: "claude-worker"` / `name: "codex-worker"` / `name: "gemini-worker"` — exactly as the report-writer dispatch sets `name: "report-writer"` ([report-writer](./report-writer.md)). The Agent harness records this `name` as `agentName` in the subagent session jsonl, and the Phase 7 token collector matches each worker's session by that `agentName` (`okstra_token_usage/collect.py`). A worker dispatched **without** `name` produces a session with no `agentName`; the collector cannot attribute it and records the worker as `source: "unavailable"` even though the session exists and is team-tagged (observed in `dev-9692` error-analysis: `claude`/`codex` workers dispatched without `name` → both `unavailable`, while the named `report-writer` collected normally). Convergence reverify dispatches keep the prefix (`<workerId>-worker-reverify-r<N>`). For `implementation` and `final-verification` dispatches the `name` carries the **functional role** so the FleetView teammate pill and trace panes name the actual job instead of a generic `worker`: the Executor dispatch sets `name: "<workerId>-executor"` (e.g. `codex-executor`) and every verifier dispatch sets `name: "<workerId>-verifier"` (e.g. `claude-verifier`). These role suffixes still attribute correctly — the collector matches any `agentName` beginning `<workerId>-` (`okstra_token_usage/collect.py` `match_prefixes`). **For every CLI (Codex / Gemini) dispatch, Lead MUST inject a `**Pane role:**` line into the dispatched prompt body whose value is the Agent `name` with the leading `<cli>-` prefix removed** — the wrapper subagent reads it and passes it as the wrapper's 5th `<role>` argument so the tmux trace pane title reads `<cli>-<role>` (which equals the FleetView teammate name) instead of a generic `<cli>-worker` (see `agents/workers/_cli-wrapper-template.md`). So `name: "codex-worker"` → `**Pane role:** worker`, `name: "codex-worker-reverify-r1"` → `**Pane role:** worker-reverify-r1`, `name: "codex-executor"` → `**Pane role:** executor`, `name: "codex-verifier"` → `**Pane role:** verifier`. The wrapper defaults to `worker` when the line is absent, but always inject it so the pane names the actual job.
|
|
226
226
|
|
|
227
227
|
**Agent `model:` on dispatch (BLOCKING — assignment is otherwise ignored).** The `Claude worker` `Agent(...)` call MUST set `model: "<family token of that role's modelExecutionValue>"` (`fable` / `opus` / `sonnet` / `haiku`), per [team-contract](./team-contract.md) "Model Assignment Rules" #3–#4. The claude-worker definition is `model: inherit`, so omitting this parameter makes the worker silently run on the lead's model instead of its manifest assignment — the assigned-vs-actual deviation. `Codex worker` / `Gemini worker` are exempt: their CLI model is applied via the wrapper's own `--model` argument, so leave their Agent `model:` at `inherit` (rule #5).
|
|
228
228
|
|
package/src/doctor.mjs
CHANGED
|
@@ -146,9 +146,14 @@ async function loadPhaseDiagnostics(phase, paths) {
|
|
|
146
146
|
")",
|
|
147
147
|
"print(json.dumps(payload, ensure_ascii=False))",
|
|
148
148
|
].join("\n");
|
|
149
|
+
// `home` locates the agent install root (`<home>/.claude/agents`), which is
|
|
150
|
+
// the user home — NOT the okstra home (`paths.home` = ~/.okstra). Agents are
|
|
151
|
+
// installed under `homedir()/.claude/agents` (see install.mjs), so passing
|
|
152
|
+
// paths.home made every worker-agent phase check resolve to a path that
|
|
153
|
+
// never exists and report a false "missing agent".
|
|
149
154
|
const result = await runPythonSnippet({
|
|
150
155
|
script,
|
|
151
|
-
args: [phase, process.cwd(), paths.workspace,
|
|
156
|
+
args: [phase, process.cwd(), paths.workspace, homedir()],
|
|
152
157
|
});
|
|
153
158
|
if (result.code !== 0 && !result.stdout.trim()) {
|
|
154
159
|
return {
|
/package/runtime/prompts/{okstra-coding-preflight → coding-preflight}/architectures/hexagonal.md
RENAMED
|
File without changes
|
|
File without changes
|
/package/runtime/prompts/{okstra-coding-preflight → coding-preflight}/frameworks/node-server.md
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|