okstra 0.49.0 → 0.51.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/README.kr.md +8 -7
- package/README.md +8 -7
- package/bin/okstra +2 -0
- package/docs/kr/architecture.md +23 -24
- package/docs/kr/cli.md +6 -6
- package/docs/project-structure-overview.md +13 -9
- package/docs/superpowers/plans/2026-06-05-wizard-batch-prompts.md +559 -0
- package/docs/superpowers/specs/2026-06-05-wizard-batch-prompts-design.md +121 -0
- package/docs/task-process/error-analysis.md +1 -1
- package/docs/task-process/final-verification.md +1 -1
- package/docs/task-process/release-handoff.md +1 -1
- package/docs/task-process/requirements-discovery.md +1 -1
- package/package.json +1 -1
- package/runtime/BUILD.json +2 -2
- package/runtime/agents/SKILL.md +18 -14
- package/runtime/agents/workers/claude-worker.md +4 -4
- package/runtime/agents/workers/codex-worker.md +3 -3
- package/runtime/agents/workers/gemini-worker.md +3 -3
- package/runtime/agents/workers/report-writer-worker.md +3 -3
- package/runtime/bin/lib/okstra/cli.sh +8 -1
- package/runtime/bin/lib/okstra/globals.sh +3 -0
- package/runtime/bin/lib/okstra/interactive.sh +14 -12
- package/runtime/bin/lib/okstra/usage.sh +6 -0
- package/runtime/bin/okstra-render-report-views.py +1 -1
- package/runtime/bin/okstra-team-reconcile.sh +28 -0
- package/runtime/bin/okstra.sh +2 -0
- package/runtime/prompts/launch.template.md +4 -2
- package/runtime/prompts/profiles/_common-contract.md +15 -15
- package/runtime/prompts/profiles/_implementation-deliverable.md +1 -1
- package/runtime/prompts/profiles/_implementation-executor.md +3 -3
- package/runtime/prompts/profiles/_implementation-verifier.md +2 -2
- package/runtime/prompts/profiles/error-analysis.md +1 -1
- package/runtime/prompts/profiles/final-verification.md +2 -2
- package/runtime/prompts/profiles/implementation-planning.md +10 -9
- package/runtime/prompts/profiles/implementation.md +1 -1
- package/runtime/prompts/profiles/improvement-discovery.md +5 -5
- package/runtime/prompts/profiles/release-handoff.md +2 -2
- package/runtime/prompts/profiles/requirements-discovery.md +2 -2
- package/runtime/python/okstra_ctl/analysis_packet.py +259 -0
- package/runtime/python/okstra_ctl/clarification_items.py +11 -11
- package/runtime/python/okstra_ctl/context_cost.py +308 -0
- package/runtime/python/okstra_ctl/migrate.py +2 -12
- package/runtime/python/okstra_ctl/paths.py +22 -0
- package/runtime/python/okstra_ctl/render.py +285 -126
- package/runtime/python/okstra_ctl/render_final_report.py +32 -1
- package/runtime/python/okstra_ctl/report_views.py +12 -12
- package/runtime/python/okstra_ctl/run.py +510 -248
- package/runtime/python/okstra_ctl/sequence.py +2 -5
- package/runtime/python/okstra_ctl/team_reconcile.py +131 -0
- package/runtime/python/okstra_ctl/wizard.py +219 -136
- package/runtime/python/okstra_ctl/workflow.py +1 -1
- package/runtime/python/okstra_ctl/worktree.py +13 -5
- package/runtime/schemas/final-report-v1.0.schema.json +4 -0
- package/runtime/skills/okstra-brief/SKILL.md +1 -1
- package/runtime/skills/okstra-coding-preflight/SKILL.md +69 -0
- package/runtime/skills/okstra-coding-preflight/architecture/hexagonal.md +116 -0
- package/runtime/skills/okstra-coding-preflight/clean-code.md +254 -0
- package/runtime/skills/okstra-coding-preflight/languages/java.md +64 -0
- package/runtime/skills/okstra-coding-preflight/languages/javascript-typescript.md +87 -0
- package/runtime/skills/okstra-coding-preflight/languages/kotlin.md +69 -0
- package/runtime/skills/okstra-coding-preflight/languages/nodejs.md +66 -0
- package/runtime/skills/okstra-coding-preflight/languages/python.md +179 -0
- package/runtime/skills/okstra-coding-preflight/languages/rust.md +105 -0
- package/runtime/skills/okstra-coding-preflight/languages/sql.md +68 -0
- package/runtime/skills/okstra-context-loader/SKILL.md +12 -6
- package/runtime/skills/okstra-convergence/SKILL.md +8 -8
- package/runtime/skills/okstra-inspect/SKILL.md +100 -1
- package/runtime/skills/okstra-report-writer/SKILL.md +27 -23
- package/runtime/skills/okstra-run/SKILL.md +3 -1
- package/runtime/skills/okstra-team-contract/SKILL.md +8 -5
- package/runtime/templates/reports/final-report.template.md +188 -187
- package/runtime/templates/reports/i18n/en.json +4 -4
- package/runtime/templates/reports/i18n/ko.json +4 -4
- package/runtime/templates/reports/implementation-planning-input.template.md +1 -1
- package/runtime/templates/reports/release-handoff-input.template.md +1 -1
- package/runtime/templates/reports/user-response.template.md +1 -1
- package/runtime/templates/worker-prompt-preamble.md +4 -4
- package/runtime/validators/lib/fixtures.sh +2 -2
- package/runtime/validators/validate-implementation-plan-stages.py +9 -9
- package/runtime/validators/validate-report-views.py +10 -10
- package/runtime/validators/validate-run.py +36 -36
- package/runtime/validators/validate_improvement_report.py +8 -8
- package/src/_python-helper.mjs +3 -3
- package/src/context-cost.mjs +27 -0
- package/src/install.mjs +1 -0
- package/src/uninstall.mjs +1 -0
|
@@ -108,7 +108,7 @@ flowchart TD
|
|
|
108
108
|
Blockers --> Followup
|
|
109
109
|
```
|
|
110
110
|
|
|
111
|
-
`##
|
|
111
|
+
`## 7. Final Verdict`에는 `Verdict Token` field가 정확히 하나 들어가야 하며 값은 다음 셋 중 하나다.
|
|
112
112
|
|
|
113
113
|
- `accepted`: release-handoff로 넘겨도 되는 상태
|
|
114
114
|
- `conditional-accept`: 조건을 모두 명시해야 하며, 조건이 gate면 다음 phase를 막는다
|
|
@@ -83,7 +83,7 @@ flowchart TD
|
|
|
83
83
|
lead는 사용자에게 push/PR 여부를 묻기 전에 다음을 확인한다.
|
|
84
84
|
|
|
85
85
|
- task brief가 `## Source Verification Report`를 가리킨다.
|
|
86
|
-
- 그 report의 `##
|
|
86
|
+
- 그 report의 `## 7. Final Verdict`에 `Verdict Token = accepted`가 정확히 있다.
|
|
87
87
|
- working tree가 clean이다.
|
|
88
88
|
- 현재 branch가 `main`, `master`, `prod`, `preprod`, `staging`, `dev` 같은 base branch가 아니다.
|
|
89
89
|
- `<base>..HEAD` commit range가 비어 있지 않다.
|
|
@@ -100,7 +100,7 @@ final report는 다음을 특히 강조한다.
|
|
|
100
100
|
- missing input과 uncertainty boundary
|
|
101
101
|
- 다음 phase 및 safe resume guidance
|
|
102
102
|
- `terminology:*` brief item에 대한 canonical term resolution
|
|
103
|
-
- blocking input이 있으면 `##
|
|
103
|
+
- blocking input이 있으면 `## 1. Clarification Items` unified table에 `Blocks=next-phase`
|
|
104
104
|
|
|
105
105
|
Non-goal은 source edit, plan authoring, build, deployment다.
|
|
106
106
|
|
package/package.json
CHANGED
package/runtime/BUILD.json
CHANGED
package/runtime/agents/SKILL.md
CHANGED
|
@@ -44,7 +44,7 @@ This SKILL.md is the operating contract and phase index. Detailed procedures liv
|
|
|
44
44
|
| 5.5 Convergence | Cross-verify findings across workers | `okstra-convergence` |
|
|
45
45
|
| 5.6 Critic pass | (opt-in) reused-worker critic pass: coverage gaps (discovery/error-analysis/impl-planning) or acceptance devil's-advocate (final-verification), each verified one round | `okstra-convergence` "Coverage critic pass" / "Acceptance critic pass" |
|
|
46
46
|
| 6. Synthesis | Dispatch Report writer worker, review draft. **For `implementation-planning`: then run the Phase 6 plan-body verification sub-step (see Phase 6 section below).** | `okstra-report-writer` + `okstra-convergence` (sub-step) |
|
|
47
|
-
| 7. Persist | Run token-usage collector, update manifests, then disband the worker team (
|
|
47
|
+
| 7. Persist | Run token-usage collector, update manifests, then disband the worker team (reconcile stale members + `TeamDelete`, after collection) | `okstra-report-writer` + `_common-contract.md` "Run-end team teardown" |
|
|
48
48
|
|
|
49
49
|
## Core operating contract
|
|
50
50
|
|
|
@@ -96,7 +96,7 @@ Required checkpoints:
|
|
|
96
96
|
- `PROGRESS: phase-5.6-critic provider=<provider> gaps=<n>` — when the coverage critic pass runs (Phase 5.6, opt-in). Omitted when `convergence.critic.enabled == false`.
|
|
97
97
|
- `PROGRESS: phase-6-synthesis dispatching report-writer-worker` — at the start of Phase 6.
|
|
98
98
|
- `PROGRESS: phase-7-persist updating manifests` — at the start of Phase 7.
|
|
99
|
-
- `PROGRESS: phase-7-teardown disbanding team` — after token-usage collection, immediately before
|
|
99
|
+
- `PROGRESS: phase-7-teardown disbanding team` — after token-usage collection, immediately before reconciling stale members + `TeamDelete` (Teams mode only; see `_common-contract.md` "Run-end team teardown"). Skipped in the no-`team_name` fallback.
|
|
100
100
|
- `PROGRESS: complete final-report=<relative-path>` — final summary line, after all persistence.
|
|
101
101
|
|
|
102
102
|
These lines are the only structured signal the user has during a long run. Do NOT replace them with prose ("Now I'm starting Phase 2..."), do NOT skip a checkpoint because "the previous message already said that", and do NOT batch multiple checkpoints into one. Each line stands alone so the user (or any operator scraping stdout) can timestamp it externally.
|
|
@@ -107,6 +107,8 @@ These lines are the only structured signal the user has during a long run. Do NO
|
|
|
107
107
|
|
|
108
108
|
**The lead never invents a model.** Every role's model is read from `task-manifest.json` → `resultContract.requiredWorkerRoles[*].modelExecutionValue` (and the lead model metadata). A missing assignment is a manifest defect, not a license to fall back — see [okstra-team-contract](./skills/okstra-team-contract/SKILL.md) "Model Assignment Rules". The manifest is always populated at run-prep time by the CLI, which seeds these values from `OKSTRA_DEFAULT_*_MODEL` (`scripts/okstra_ctl/run.py`).
|
|
109
109
|
|
|
110
|
+
**Reading the assignment is not enough — it must be applied at spawn.** For the in-process Claude subagents (`Claude worker`, `Report writer worker`), the manifest value is bound only when lead passes it as the `Agent(...)` `model:` parameter; their `model: inherit` frontmatter otherwise follows the lead's own model. See "Model Assignment Rules" #3–#5 in [okstra-team-contract](./skills/okstra-team-contract/SKILL.md) for the spawn rule, the family-token mapping, and the Codex/Gemini exemption.
|
|
111
|
+
|
|
110
112
|
The table below documents those prep-time seed values **for reference only** — it is NOT a lead-applied fallback:
|
|
111
113
|
|
|
112
114
|
| Role | Seed model | subagent_type | Source definition |
|
|
@@ -152,21 +154,21 @@ Executor is chosen at run-prep time via `--executor <claude|codex|gemini>` (or `
|
|
|
152
154
|
|
|
153
155
|
Treat cross verify input as a task bundle, not as a single file. If the user did not specify an explicit task key or task path, use `.okstra/discovery/latest-task.json` as the current-task convenience pointer. If task browsing, task-id disambiguation, or project-level task inventory is needed, inspect `.okstra/discovery/task-catalog.json` first.
|
|
154
156
|
|
|
155
|
-
After context-loader completes, read **only the
|
|
157
|
+
After context-loader completes, read **only the compact intake files below** in a single parallel-Read message at the start of Phase 1. The other instruction-set files are loaded lazily at the phase that actually needs them — see "Lazy reading discipline" below. This split came from observed lead-token bloat: in `fontsninja-classifier-v2:dev-9461:dev-9495` RD-001 the lead burned 71 M tokens (97 % cache_read) largely because every phase entry re-absorbed a 93 KB instruction-set baseline that included files only one downstream phase ever actually used.
|
|
156
158
|
|
|
157
159
|
**Mandatory at Phase 1 start (parallel Read, one message):**
|
|
158
160
|
|
|
159
161
|
1. `task-manifest.json` (found by context-loader)
|
|
160
|
-
2. `
|
|
161
|
-
3. `instruction-set/analysis-profile.md` — needed to
|
|
162
|
-
4.
|
|
163
|
-
5. the current run team-state artifact
|
|
162
|
+
2. `runs/<task-type>/state/active-run-context-<task-type>-<seq>.json` — compact current-run intake; if absent, fall back to the current run manifest + team-state artifact
|
|
163
|
+
3. `instruction-set/analysis-profile.md` — needed to pick the right `Required workers:` block and phase rules
|
|
164
|
+
4. `instruction-set/analysis-packet.md` — primary compact input for analysis worker dispatch
|
|
164
165
|
|
|
165
166
|
**Lazy reading discipline (do NOT read at Phase 1):**
|
|
166
167
|
|
|
167
168
|
- `task-index.md` — only when the user explicitly asks for a human summary or when history disambiguation is required.
|
|
168
|
-
- `instruction-set/
|
|
169
|
-
- `instruction-set/
|
|
169
|
+
- `instruction-set/task-brief.md` — read only if the packet is insufficient, a cited source needs verification, or report-writer synthesis requires the full source.
|
|
170
|
+
- `instruction-set/analysis-material.md` — read only if the packet is insufficient or a source citation needs verification. Many task bundles have no meaningful material file beyond a duplicate brief wrapper.
|
|
171
|
+
- `instruction-set/reference-expectations.md` — read at Phase 6 synthesis (or whenever the report-writer worker is dispatched) — it informs the match/gap assessment. Analysis workers use the packet excerpt unless they need source verification.
|
|
170
172
|
- `instruction-set/final-report-template.md` — never read by Lead. The Report writer worker reads it as part of its own [Required reading]; Lead only references its path when dispatching.
|
|
171
173
|
- `history/timeline.json` — read only on user request or when carry-in resolution requires it.
|
|
172
174
|
|
|
@@ -186,7 +188,7 @@ The guard is not satisfied by remembering content from a prior run — each impl
|
|
|
186
188
|
|
|
187
189
|
This pattern is implementation-only. Other profiles (`requirements-discovery`, `error-analysis`, `implementation-planning`, `final-verification`, `release-handoff`) load their whole profile body at Phase 1 as before — they are short enough not to benefit from a split.
|
|
188
190
|
|
|
189
|
-
Extract from the
|
|
191
|
+
Extract from the compact intake files: task key, task type, work category, workflow lifecycle snapshot, selected worker roster, assigned models, worker result paths, worker prompt history paths, current run prompt directory, final report path, final status path, validator path, resume helper path, config-file references, deployment-manifest references, and their expected values or invariants.
|
|
190
192
|
|
|
191
193
|
If previous run reports exist, use as historical context only. If discovery metadata or current artifacts conflict with a newer user instruction, prefer the user instruction. If `reference-expectations.md` explicitly says expectations were not provided (you can confirm this without reading the file if the brief's "Expected state" section is empty), treat that as missing information and say `I don't know` rather than inventing expected states.
|
|
192
194
|
|
|
@@ -195,7 +197,7 @@ If previous run reports exist, use as historical context only. If discovery meta
|
|
|
195
197
|
These phases are governed by [okstra-team-contract](./skills/okstra-team-contract/SKILL.md). It is the canonical source for:
|
|
196
198
|
|
|
197
199
|
- Worker prompt anchor headers and body composition rules.
|
|
198
|
-
- The `[Required reading]` clause (
|
|
200
|
+
- The `[Required reading]` clause (analysis-packet primary input for analysis workers, full source files for report-writer, scoped inputs for reverify dispatches).
|
|
199
201
|
- The `[Error reporting]` clause and the asymmetry between claude-worker and codex/gemini-worker prompts.
|
|
200
202
|
- Worker output contract (sections 0–5), header standard, terminal statuses, errors-sidecar schema.
|
|
201
203
|
- Token-usage tracking conventions.
|
|
@@ -220,6 +222,8 @@ Spawn **analysis workers only** in the same turn (Phase 4 in Teams mode; Phase 5
|
|
|
220
222
|
|
|
221
223
|
**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"` ([okstra-report-writer](./skills/okstra-report-writer/SKILL.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>`); implementation executor/verifier variants keep `<workerId>-worker` / `<workerId>-executor`.
|
|
222
224
|
|
|
225
|
+
**Agent `model:` on dispatch (BLOCKING — assignment is otherwise ignored).** The `Claude worker` `Agent(...)` call MUST set `model: "<family token of that role's modelExecutionValue>"` (`opus` / `sonnet` / `haiku`), per [okstra-team-contract](./skills/okstra-team-contract/SKILL.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).
|
|
226
|
+
|
|
223
227
|
The no-`team_name` fallback (Phase 5) is only legal when team-state's `teamCreate.status` is `"error"` for this run. If `teamCreate` is missing or `attempted: false`, the correct action when an Agent dispatch is rejected for a missing team is to GO BACK to Phase 3 and call `TeamCreate` — never to strip `team_name` and continue.
|
|
224
228
|
|
|
225
229
|
### Errors log path wiring (BLOCKING)
|
|
@@ -310,12 +314,12 @@ Distinct from Phase 5.5 finding convergence:
|
|
|
310
314
|
|
|
311
315
|
Lead's responsibilities in this sub-step (in order):
|
|
312
316
|
|
|
313
|
-
1. Extract `P-*` plan items from the draft report's `##
|
|
317
|
+
1. Extract `P-*` plan items from the draft report's `## 5.5 Implementation Plan Deliverables` per the prefix → source-section mapping in the convergence skill.
|
|
314
318
|
2. Dispatch a single plan-body reverify round to every analyser worker in the roster (`claude`, `codex`, and `gemini` when opted in). `Report writer worker` is NOT a participant in this round.
|
|
315
319
|
3. Aggregate verdicts and resolve the gate result to one of `passed` / `passed-with-dissent` / `blocked-by-disagreement` / `aborted-non-result`.
|
|
316
320
|
4. Write `runs/<task-type>/state/plan-body-verification.json` (schema in the convergence skill).
|
|
317
|
-
5. Populate `###
|
|
318
|
-
6. For every `majority-disagree` plan item, append a row to `##
|
|
321
|
+
5. Populate `### 5.5.9 Plan Body Verification` in the final-report file (template at `templates/reports/final-report.template.md` §5.5.9 — Round count, Gate result, Verdict table, Dissent log).
|
|
322
|
+
6. For every `majority-disagree` plan item, append a row to `## 1. Clarification Items` with `Blocks=approval` and the 1:1 ID match in the verdict table's `Classification` column (`majority-disagree → C-<N>`). Do NOT create a parallel `Open Questions` block — see `prompts/profiles/implementation-planning.md` self-review step 6 for the orphan-on-either-side contract.
|
|
319
323
|
7. Conditionally render the top-of-report `- [ ] Approved` marker line: present iff gate ∈ {passed, passed-with-dissent}, absent iff gate ∈ {blocked-by-disagreement, aborted-non-result}. `validators/validate-run.py` `validate_phase_boundary` enforces this correspondence. Manually flipping a blocked gate to passing in order to render the marker is a contract violation.
|
|
320
324
|
|
|
321
325
|
If `convergence.planBodyVerification.enabled == false` (set by `--no-plan-verification` or by `okstra config set plan-verification off`), the entire sub-step is skipped and the top-of-report Approval marker is rendered unconditionally (legacy behaviour). This opt-out is intended for fast iteration only and is not recommended for handoff-ready plans.
|
|
@@ -45,7 +45,7 @@ Unlike the Codex / Gemini workers, you are an in-process Claude subagent — you
|
|
|
45
45
|
|
|
46
46
|
4. Anchor all file operations to the absolute `Project Root` from the lead prompt. Use absolute paths — do NOT rely on inherited cwd. Never use `cd` to change directory.
|
|
47
47
|
- **Executor exception (implementation phase only):** when this worker is dispatched as the `Executor` and the lead prompt provides an `EXECUTOR_WORKTREE_PATH` that differs from the session's inherited cwd, cwd-sensitive Bash commands (`cargo *`, `npm *`, `pnpm *`, `bun *`, `pytest`, `make *`, `go *`, language-toolchain test/build commands) MUST be prefixed with `cd <EXECUTOR_WORKTREE_PATH> && ` in the same Bash invocation — e.g. `cd /Users/.../worktrees/foo && cargo test -p bar`. Do NOT wrap the whole thing in `bash -lc "..."` or `bash -c "..."`; pass the chained command directly to the Bash tool so the leading `cd` token remains visible to the permission layer. The `cd` is scoped to the single Bash subshell and does not mutate the session's shell state, so this does not conflict with the "never use cd" rule above (which prevents the worker from drifting the session cwd across calls).
|
|
48
|
-
- **Executor coding-conventions preflight (BLOCKING, before your first `Edit` / `Write`):** when dispatched as the `Executor`, you MUST run the coding-conventions preflight defined in the executor sidecar (`prompts/profiles/_implementation-executor.md` → "Pre-implementation context exploration") before writing any code — detect each touched file's language and
|
|
48
|
+
- **Executor coding-conventions preflight (BLOCKING, before your first `Edit` / `Write`):** when dispatched as the `Executor`, you MUST run the coding-conventions preflight defined in the executor sidecar (`prompts/profiles/_implementation-executor.md` → "Pre-implementation context exploration") before writing any code — detect each touched file's language and read okstra's installed coding-conventions files directly — `~/.claude/skills/okstra-coding-preflight/languages/<lang>.md` + `clean-code.md` + any `architecture/hexagonal.md` overlay (placed by `okstra install`), then state in one line which conventions apply. The skill is `user-invocable: false` and subagents do NOT auto-trigger skills, so read the files via the Read tool by absolute path rather than relying on Skill invocation; if those files are not readable in your runtime, degrade per that sidecar section (agnostic principles + project lint/convention files) — never skip the gate.
|
|
49
49
|
- **Verifier QA-gate exception:** verifier roles MAY use the same `cd <WORKTREE> && <cmd>` shape when executing project-declared `qaCommands` (lint / format / typecheck / test) from `project.json`, since those commands are cwd-sensitive by nature. Outside the QA gate, verifiers still read with absolute paths only — do NOT use `cd` for file inspection.
|
|
50
50
|
- **No extra chaining beyond `cd && cmd`:** the permission matcher only allows the exact two-segment shape `cd <PATH> && <single-command>`. Do NOT append additional pipes, semicolons, redirects, or `&&` chains — e.g. `cd ... && cargo test ... 2>&1 | tail -20; echo "exit:$?"` will trigger a permission prompt every dispatch because the trailing `| tail`, `; echo`, and `2>&1` tokens disqualify the prefix match against `Bash(cargo:*)`. Let Claude Code capture the full stdout/stderr and exit code natively — do not post-process with `tail`, `head`, or `echo "exit:$?"`. If output truncation is genuinely needed, run the command first and read the result in a separate tool call.
|
|
51
51
|
|
|
@@ -60,7 +60,7 @@ Unlike the Codex / Gemini workers, you are an in-process Claude subagent — you
|
|
|
60
60
|
Before producing any output, you MUST:
|
|
61
61
|
|
|
62
62
|
1. Extract the absolute path from the lead's `**Worker Preamble Path:**` anchor header and Read that file end-to-end with a single `Read` call (no `offset`, no `limit`). This is the canonical SSOT for the Required Reading + Error Reporting + Output sections contract.
|
|
63
|
-
2. Read every input file the lead enumerated under `## Inputs` (or equivalent heading) in the dispatch prompt body, end-to-end, following the rules stated in the preamble. For analysis workers this is
|
|
63
|
+
2. Read every primary input file the lead enumerated under `## Inputs` (or equivalent heading) in the dispatch prompt body, end-to-end, following the rules stated in the preamble. For analysis workers this is normally `analysis-packet.md`; the source files named inside that packet are fallback/evidence paths to open when needed. Analysis workers do NOT read `final-report-template.md` — that file is for the report writer only.
|
|
64
64
|
|
|
65
65
|
**Heartbeat — write the audit sidecar EARLY and APPEND per stage (BLOCKING).** Because this worker runs as an in-process Agent or a fresh-session tmux pane, the lead has no `BashOutput`-style liveness signal while waiting for your return. The audit sidecar is the only signal that survives a silent hang. Write the sidecar at `runs/<task-type>/worker-results/claude-worker-audit-<task-type>-<seq>.md` immediately after extracting `Project Root` and the assigned paths — BEFORE the per-file end-to-end reads — with just the heading line (`# Claude Worker Audit — <task-key>`) and one `- PROGRESS: started <ISO-8601-UTC>` line. Then APPEND one short progress line per stage as you advance: `read-<filename>`, `analysis-start`, `findings-draft-start`, `findings-draft-complete`, `write-result-start`. The append cadence MUST NOT exceed 5 minutes — if a single analysis stage is taking longer, emit a `- PROGRESS: in-stage:<stage> <ISO-8601-UTC>` heartbeat. A 5-minute stale sidecar mtime is the canonical "this worker has hung" signal for the operator. Sidecar write/append uses `Write` (initial) and `Edit` / heredoc `>>` (per-stage append).
|
|
66
66
|
|
|
@@ -68,7 +68,7 @@ Before producing any output, you MUST:
|
|
|
68
68
|
|
|
69
69
|
When returning results, start the file with a YAML frontmatter block, then organize the body into the following sections in this exact order.
|
|
70
70
|
|
|
71
|
-
**Frontmatter (mandatory)** — set `workerId: "claude"`. Copy `id`, `aliases`, `taskType`, `task-id`, `task-group`, `project-id`, `date` verbatim from the input
|
|
71
|
+
**Frontmatter (mandatory)** — set `workerId: "claude"`. Copy `id`, `aliases`, `taskType`, `task-id`, `task-group`, `project-id`, `date` verbatim from the primary input (`analysis-packet.md`; fall back to `analysis-material.md` only if the packet is missing a field). Full schema and a concrete example live in the `okstra-team-contract` skill's "Result Frontmatter" subsection.
|
|
72
72
|
|
|
73
73
|
1. **Findings** - what you identified
|
|
74
74
|
2. **Missing Information or Assumptions** - gaps in the analysis
|
|
@@ -78,7 +78,7 @@ When returning results, start the file with a YAML frontmatter block, then organ
|
|
|
78
78
|
|
|
79
79
|
Include file paths and line numbers when discussing code evidence.
|
|
80
80
|
|
|
81
|
-
**Item IDs (mandatory).** Every row in sections 1–5 (and any optional section 6) MUST carry a worker-internal item ID unique within this file. Use the leading column for table-form items (`F-001`, `M-001`, `S-001`, `U-001`, `R-001` per section) or a `[<ID>]` prefix for bullet/numbered items. The ID shape is your choice but it MUST appear — the lead's §
|
|
81
|
+
**Item IDs (mandatory).** Every row in sections 1–5 (and any optional section 6) MUST carry a worker-internal item ID unique within this file. Use the leading column for table-form items (`F-001`, `M-001`, `S-001`, `U-001`, `R-001` per section) or a `[<ID>]` prefix for bullet/numbered items. The ID shape is your choice but it MUST appear — the lead's §6.1 / §6.2 / §2.1 synthesis preserves these IDs in its `Source items (worker:item)` column to keep cross-worker traceability intact. See `prompts/profiles/_common-contract.md` "Cross-worker traceability" SSOT.
|
|
82
82
|
|
|
83
83
|
**Ticket tagging:** For runs whose task type is `requirements-discovery`, `error-analysis`, `implementation-planning`, or `implementation`, every item in sections 1–5 MUST carry a ticket identifier. Use the `Ticket ID` column in table-form items and the `[TICKETID: <id>]` prefix in bullet/numbered items. Fill priority: `Issue / Ticket` from the input → `Task ID` (no prefix, e.g. `8852`) → `unknown`. Multiple tickets are comma-separated. Full rules live in the `okstra-team-contract` skill's Ticket Tagging section.
|
|
84
84
|
|
|
@@ -143,7 +143,7 @@ This wrapper does NOT invoke MCP tools directly. MCP availability inside the Cod
|
|
|
143
143
|
Before invoking the Codex CLI, you MUST:
|
|
144
144
|
|
|
145
145
|
1. Extract the absolute path from the lead's `**Worker Preamble Path:**` anchor header and verify the CLI run will Read that file end-to-end (canonical SSOT for the Required Reading + Error Reporting + Output sections contract). The lead's prompt body — which you persist verbatim and feed into Codex via stdin — already contains this anchor; do not strip it.
|
|
146
|
-
2. Verify the lead's prompt body lists the per-run input files under `## Inputs` (
|
|
146
|
+
2. Verify the lead's prompt body lists the per-run primary input files under `## Inputs` (normally `analysis-packet.md` for analysis workers). The source files named inside that packet are fallback/evidence paths to open when needed. Analysis workers do NOT read `final-report-template.md` — that file is for the report writer only.
|
|
147
147
|
|
|
148
148
|
The CLI writes a Reading Confirmation block to the **audit sidecar** at `runs/<task-type>/worker-results/codex-worker-audit-<task-type>-<seq>.md`. The sidecar's body begins with `# Codex Worker Audit — <task-key>` followed by one short line per input file confirming end-to-end reading. The main Codex output MUST NOT contain a `## 0. Reading Confirmation` heading — the validator fails worker-results that contain one. If any file was skipped, record a `tool-failure` in the errors sidecar instead of fabricating Findings.
|
|
149
149
|
|
|
@@ -151,7 +151,7 @@ The CLI writes a Reading Confirmation block to the **audit sidecar** at `runs/<t
|
|
|
151
151
|
|
|
152
152
|
When returning results, start the file with a YAML frontmatter block, then organize the body into the following sections in this exact order.
|
|
153
153
|
|
|
154
|
-
**Frontmatter (mandatory)** — set `workerId: "codex"`. Copy `id`, `aliases`, `taskType`, `task-id`, `task-group`, `project-id`, `date` verbatim from the input
|
|
154
|
+
**Frontmatter (mandatory)** — set `workerId: "codex"`. Copy `id`, `aliases`, `taskType`, `task-id`, `task-group`, `project-id`, `date` verbatim from the primary input (`analysis-packet.md`; fall back to `analysis-material.md` only if the packet is missing a field). Full schema and a concrete example live in the `okstra-team-contract` skill's "Result Frontmatter" subsection.
|
|
155
155
|
|
|
156
156
|
1. **Findings** - what Codex identified
|
|
157
157
|
2. **Missing Information or Assumptions** - gaps in the analysis
|
|
@@ -161,7 +161,7 @@ When returning results, start the file with a YAML frontmatter block, then organ
|
|
|
161
161
|
|
|
162
162
|
Include file paths and line numbers when discussing code evidence.
|
|
163
163
|
|
|
164
|
-
**Item IDs (mandatory).** Every row in sections 1–5 (and any optional section 6) MUST carry a worker-internal item ID unique within this file. Codex tends to use hierarchical numbering (`1.1`, `1.2`, `1.3`, ...); that shape is fine — keep what's natural. What matters is that each item is addressable. The lead's §
|
|
164
|
+
**Item IDs (mandatory).** Every row in sections 1–5 (and any optional section 6) MUST carry a worker-internal item ID unique within this file. Codex tends to use hierarchical numbering (`1.1`, `1.2`, `1.3`, ...); that shape is fine — keep what's natural. What matters is that each item is addressable. The lead's §6.1 / §6.2 / §2.1 synthesis preserves these IDs as `codex:<your-id>` entries in its `Source items (worker:item)` column. See `prompts/profiles/_common-contract.md` "Cross-worker traceability" SSOT.
|
|
165
165
|
|
|
166
166
|
**Ticket tagging:** For runs whose task type is `requirements-discovery`, `error-analysis`, `implementation-planning`, or `implementation`, every item in sections 1–5 MUST carry a ticket identifier. Use the `Ticket ID` column in table-form items and the `[TICKETID: <id>]` prefix in bullet/numbered items. Fill priority: `Issue / Ticket` from the input → `Task ID` (no prefix, e.g. `8852`) → `unknown`. Multiple tickets are comma-separated. Full rules live in the `okstra-team-contract` skill's Ticket Tagging section.
|
|
167
167
|
|
|
@@ -143,7 +143,7 @@ This wrapper does NOT invoke MCP tools directly. MCP availability inside the Gem
|
|
|
143
143
|
Before invoking the Gemini CLI, you MUST:
|
|
144
144
|
|
|
145
145
|
1. Extract the absolute path from the lead's `**Worker Preamble Path:**` anchor header and verify the CLI run will Read that file end-to-end (canonical SSOT for the Required Reading + Error Reporting + Output sections contract). The lead's prompt body — which you persist verbatim and feed into Gemini via stdin — already contains this anchor; do not strip it.
|
|
146
|
-
2. Verify the lead's prompt body lists the per-run input files under `## Inputs` (
|
|
146
|
+
2. Verify the lead's prompt body lists the per-run primary input files under `## Inputs` (normally `analysis-packet.md` for analysis workers). The source files named inside that packet are fallback/evidence paths to open when needed. Analysis workers do NOT read `final-report-template.md` — that file is for the report writer only.
|
|
147
147
|
|
|
148
148
|
The CLI writes a Reading Confirmation block to the **audit sidecar** at `runs/<task-type>/worker-results/gemini-worker-audit-<task-type>-<seq>.md`. The sidecar's body begins with `# Gemini Worker Audit — <task-key>` followed by one short line per input file confirming end-to-end reading. The main Gemini output MUST NOT contain a `## 0. Reading Confirmation` heading — the validator fails worker-results that contain one. If any file was skipped, record a `tool-failure` in the errors sidecar instead of fabricating Findings.
|
|
149
149
|
|
|
@@ -151,7 +151,7 @@ The CLI writes a Reading Confirmation block to the **audit sidecar** at `runs/<t
|
|
|
151
151
|
|
|
152
152
|
When returning results, start the file with a YAML frontmatter block, then organize the body into the following sections in this exact order.
|
|
153
153
|
|
|
154
|
-
**Frontmatter (mandatory)** — set `workerId: "gemini"`. Copy `id`, `aliases`, `taskType`, `task-id`, `task-group`, `project-id`, `date` verbatim from the input
|
|
154
|
+
**Frontmatter (mandatory)** — set `workerId: "gemini"`. Copy `id`, `aliases`, `taskType`, `task-id`, `task-group`, `project-id`, `date` verbatim from the primary input (`analysis-packet.md`; fall back to `analysis-material.md` only if the packet is missing a field). Full schema and a concrete example live in the `okstra-team-contract` skill's "Result Frontmatter" subsection.
|
|
155
155
|
|
|
156
156
|
1. **Findings** - what Gemini identified
|
|
157
157
|
2. **Missing Information or Assumptions** - gaps in the analysis
|
|
@@ -161,7 +161,7 @@ When returning results, start the file with a YAML frontmatter block, then organ
|
|
|
161
161
|
|
|
162
162
|
Include file paths and line numbers when discussing code evidence.
|
|
163
163
|
|
|
164
|
-
**Item IDs (mandatory).** Every row in sections 1–5 (and any optional section 6) MUST carry a worker-internal item ID unique within this file. Gemini may use `F-1`, `F-2`, ... or numbered hierarchical IDs — either is fine. What matters is that each item is addressable. The lead's §
|
|
164
|
+
**Item IDs (mandatory).** Every row in sections 1–5 (and any optional section 6) MUST carry a worker-internal item ID unique within this file. Gemini may use `F-1`, `F-2`, ... or numbered hierarchical IDs — either is fine. What matters is that each item is addressable. The lead's §6.1 / §6.2 / §2.1 synthesis preserves these IDs as `gemini:<your-id>` entries in its `Source items (worker:item)` column. See `prompts/profiles/_common-contract.md` "Cross-worker traceability" SSOT.
|
|
165
165
|
|
|
166
166
|
**Ticket tagging:** For runs whose task type is `requirements-discovery`, `error-analysis`, `implementation-planning`, or `implementation`, every item in sections 1–5 MUST carry a ticket identifier. Use the `Ticket ID` column in table-form items and the `[TICKETID: <id>]` prefix in bullet/numbered items. Fill priority: `Issue / Ticket` from the input → `Task ID` (no prefix, e.g. `8852`) → `unknown`. Multiple tickets are comma-separated. Full rules live in the `okstra-team-contract` skill's Ticket Tagging section.
|
|
167
167
|
|
|
@@ -71,9 +71,9 @@ For the report writer specifically, the `## Inputs` list always includes:
|
|
|
71
71
|
- `<instruction-set>/final-report-template.md` — the **phase-stripped** Jinja2 template the renderer uses (only this run's §4.x deliverable block remains). Read it to understand which data.json fields appear where in the rendered markdown; do NOT edit it, and do NOT pull the full `templates/reports/final-report.template.md` source.
|
|
72
72
|
- `templates/reports/i18n/en.json` and `templates/reports/i18n/ko.json`.
|
|
73
73
|
- Every analysis worker's result file under `worker-results/`.
|
|
74
|
-
- `state/convergence-<task-type>-<seq>.json` (if present). When present, reproduce its `roundHistory[]`, `round2SkippedReason`, and `finalClassificationCounts` verbatim into the final report's Section
|
|
74
|
+
- `state/convergence-<task-type>-<seq>.json` (if present). When present, reproduce its `roundHistory[]`, `round2SkippedReason`, and `finalClassificationCounts` verbatim into the final report's Section 6 Round History sub-table — do not recompute from worker results.
|
|
75
75
|
|
|
76
|
-
For the carry-in `clarification-response.md` (if present), walk every row of `##
|
|
76
|
+
For the carry-in `clarification-response.md` (if present), walk every row of `## 1. Clarification Items` including rows whose `User input` cell is blank — a blank cell with `Status=open` is a signal you must surface in the conditional `## 0. Clarification Response Carried In From Previous Run` section (the template's `RENDER_IF` guard activates it when the carry-in path is non-empty). When no carry-in path was provided, OMIT the `## 0.` heading entirely — do NOT write an empty-state stub.
|
|
77
77
|
|
|
78
78
|
Write a Reading Confirmation block to your **audit sidecar** at `runs/<task-type>/worker-results/report-writer-worker-audit-<task-type>-<seq>.md`. The main final-report and the main worker-results file MUST NOT contain a `## 0. Reading Confirmation` heading. If you cannot truthfully confirm a file end-to-end, record a `tool-failure` in the errors sidecar instead of fabricating the report.
|
|
79
79
|
|
|
@@ -100,7 +100,7 @@ Rules (the schema enforces most of these — they are listed here so you know *w
|
|
|
100
100
|
- If evidence is missing, write `"I don't know"` in the relevant statement field rather than fabricating confidence.
|
|
101
101
|
- Cite file paths and line numbers in every `evidence.primary[].source` / `consensus[].evidence` cell.
|
|
102
102
|
- Preserve every analysis worker's ticket tagging — every row's `ticketId` field carries the ticket key or the task-fallback. For single-ticket runs, set `ticketCoverage` to `{"singleTicket": "<ticket>"}`. For runs that do not require ticket tagging (`release-handoff`, `final-verification`), set `ticketCoverage` to `{"omit": true}`.
|
|
103
|
-
- When the `Task Type` is `improvement-discovery`, populate `##
|
|
103
|
+
- When the `Task Type` is `improvement-discovery`, populate `## 5.9 Improvement Candidates` with the 10-column schema enforced by `validators/validate-improvement-report.py`. Source the row IDs (`I-NNN`), lens whitelist, and Source workers patterns from `scripts/okstra_ctl/improvement_lenses.py` — do NOT introduce new lens names or worker prefixes.
|
|
104
104
|
|
|
105
105
|
Write the data.json with your `Write` tool against the absolute `Result Path`. Then invoke the renderer (`Bash`): `python3 scripts/okstra-render-final-report.py <data.json path>`. Confirm both files exist and respond with a short status line: `data.json written to <abs path>; markdown rendered to <abs path>. Sections populated: <count>.`
|
|
106
106
|
|
|
@@ -142,6 +142,13 @@ while [[ $# -gt 0 ]]; do
|
|
|
142
142
|
APPROVE_PLAN_ACK="true"
|
|
143
143
|
shift
|
|
144
144
|
;;
|
|
145
|
+
--implementation-option)
|
|
146
|
+
# 유저가 implementation-planning final-report 에서 고른 Option Candidate
|
|
147
|
+
# 이름. 런타임이 approved-plan frontmatter 의 implementation-option 라인을
|
|
148
|
+
# 이 값으로 채운다. 빈 값이면 implementation 이 Recommended Option 으로 폴백.
|
|
149
|
+
IMPLEMENTATION_OPTION="$(require_option_value --implementation-option "${2-}")"
|
|
150
|
+
shift 2
|
|
151
|
+
;;
|
|
145
152
|
--no-plan-verification)
|
|
146
153
|
# implementation-planning 의 Phase 6 plan-body verification 라운드를
|
|
147
154
|
# 끈다. 기본값은 활성화. 비활성 시 final-report 상단의 User Approval
|
|
@@ -178,7 +185,7 @@ while [[ $# -gt 0 ]]; do
|
|
|
178
185
|
printf ' hint: did you mean --task-id?\n' >&2
|
|
179
186
|
;;
|
|
180
187
|
esac
|
|
181
|
-
printf ' valid options: --render-only --resume-clarification --yes --workers --lead-model --claude-model --codex-model --gemini-model --report-writer-model --related-tasks --task-type --project-id --project-root --task-group --task-id --task-brief --directive --clarification-response --approved-plan --approve --no-plan-verification -h|--help\n' >&2
|
|
188
|
+
printf ' valid options: --render-only --resume-clarification --yes --workers --lead-model --claude-model --codex-model --gemini-model --report-writer-model --related-tasks --task-type --project-id --project-root --task-group --task-id --task-brief --directive --clarification-response --approved-plan --approve --implementation-option --no-plan-verification -h|--help\n' >&2
|
|
182
189
|
usage
|
|
183
190
|
exit 1
|
|
184
191
|
;;
|
|
@@ -39,6 +39,9 @@ DIRECTIVE=""
|
|
|
39
39
|
CLARIFICATION_RESPONSE_PATH=""
|
|
40
40
|
APPROVED_PLAN_PATH=""
|
|
41
41
|
APPROVE_PLAN_ACK="false"
|
|
42
|
+
# implementation 전용: 유저가 고른 Option Candidate 이름. 빈 값이면 implementation
|
|
43
|
+
# 이 plan 의 Recommended Option 으로 폴백한다. --implementation-option 으로 설정.
|
|
44
|
+
IMPLEMENTATION_OPTION=""
|
|
42
45
|
# Phase 6 plan-body verification toggle. Default "true" (round runs).
|
|
43
46
|
# Flipped to "false" by --no-plan-verification on the CLI.
|
|
44
47
|
PLAN_VERIFICATION_ENABLED="true"
|
|
@@ -59,23 +59,25 @@ resolve_task_root_for_shortcut() {
|
|
|
59
59
|
local task_id="$4"
|
|
60
60
|
|
|
61
61
|
local resolved=""
|
|
62
|
-
resolved="$(python3 - "$project_root" "$project_id" "$task_group" "$task_id" <<'PY'
|
|
63
|
-
import json, os,
|
|
62
|
+
resolved="$(python3 - "$WORKSPACE_ROOT/scripts" "$project_root" "$project_id" "$task_group" "$task_id" <<'PY'
|
|
63
|
+
import json, os, sys
|
|
64
64
|
from pathlib import Path
|
|
65
65
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
66
|
+
# task root 의 slug 경로 구성은 okstra_ctl.paths.task_dir(SSOT) 에 위임한다.
|
|
67
|
+
# 과거 이 heredoc 은 slugify 와 `.okstra/tasks/<slug>/<slug>` 구조를 자체
|
|
68
|
+
# 재구현해 규칙 변경 시 silent drift 위험이 있었다. project-resolver.sh 와
|
|
69
|
+
# 동일하게 $WORKSPACE_ROOT/scripts 를 sys.path 에 올려 패키지를 import 한다.
|
|
70
|
+
sys.path.insert(0, sys.argv[1])
|
|
71
|
+
from okstra_ctl.paths import task_dir
|
|
72
|
+
|
|
73
|
+
project_root = Path(sys.argv[2])
|
|
74
|
+
project_id = sys.argv[3]
|
|
75
|
+
task_group = sys.argv[4]
|
|
76
|
+
task_id = sys.argv[5]
|
|
70
77
|
|
|
71
78
|
requested_key = f"{project_id}:{task_group}:{task_id}"
|
|
72
79
|
requested_key_ci = requested_key.lower()
|
|
73
80
|
|
|
74
|
-
def slugify(value: str) -> str:
|
|
75
|
-
value = value.lower()
|
|
76
|
-
value = re.sub(r"[^a-z0-9]+", "-", value).strip("-")
|
|
77
|
-
return value
|
|
78
|
-
|
|
79
81
|
candidates = []
|
|
80
82
|
|
|
81
83
|
catalog_path = project_root / ".okstra" / "discovery" / "task-catalog.json"
|
|
@@ -111,7 +113,7 @@ if catalog_path.is_file():
|
|
|
111
113
|
sys.exit(0)
|
|
112
114
|
candidates.append(str(abs_path))
|
|
113
115
|
|
|
114
|
-
slug_path = project_root
|
|
116
|
+
slug_path = task_dir(project_root, task_group, task_id)
|
|
115
117
|
if slug_path.is_dir():
|
|
116
118
|
print(f"OK\t{slug_path}")
|
|
117
119
|
sys.exit(0)
|
|
@@ -46,6 +46,12 @@ optional arguments:
|
|
|
46
46
|
\`- [ ] Approved\` to \`- [x] Approved\` and appends an approval audit line
|
|
47
47
|
(timestamp + "CLI --approve"). Use this for scripted/CI flows or when you want a
|
|
48
48
|
single command to both approve and launch the next phase.
|
|
49
|
+
--implementation-option <name>
|
|
50
|
+
Name of the Option Candidate the user chose from the implementation-planning
|
|
51
|
+
final-report. Only meaningful together with --approved-plan and
|
|
52
|
+
--task-type=implementation. The runtime fills the approved-plan frontmatter
|
|
53
|
+
\`implementation-option:\` line with <name>. When omitted, the implementation run
|
|
54
|
+
falls back to the plan's \`Recommended Option\`.
|
|
49
55
|
--no-plan-verification
|
|
50
56
|
Disable the Phase 6 plan-body verification round that runs after the report-writer
|
|
51
57
|
authors the implementation-planning draft. Default: enabled. Only meaningful with
|
|
@@ -129,7 +129,7 @@ def main(argv: list[str] | None = None) -> int:
|
|
|
129
129
|
meta = RunMeta(task_key=task_key, task_type=task_type, seq=seq, source_report=source_report)
|
|
130
130
|
html_path = render_html_view(report_path, run_meta=meta, css=css, js=js)
|
|
131
131
|
if html_path is None:
|
|
132
|
-
print("html: skipped (no §
|
|
132
|
+
print("html: skipped (no §1 clarification rows — html view carries no interactive forms for this report)")
|
|
133
133
|
else:
|
|
134
134
|
print(f"html: {html_path}")
|
|
135
135
|
return 0
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
#
|
|
3
|
+
# okstra-team-reconcile.sh — flip dead-pane stale-active team members to
|
|
4
|
+
# inactive so the lead's `TeamDelete()` can disband the team in one shot.
|
|
5
|
+
#
|
|
6
|
+
# A Claude Code team member clears its own `isActive` flag in
|
|
7
|
+
# `~/.claude/teams/<team>/config.json` when its `Agent()` dispatch returns. A
|
|
8
|
+
# member whose tmux pane died WITHOUT that flip stays `isActive: true`, and
|
|
9
|
+
# `TeamDelete` then refuses the whole team ("active members remain") — an error
|
|
10
|
+
# no re-sent `shutdown_request` can clear, since the addressee is already gone.
|
|
11
|
+
# This reconciles exactly that case; it never touches a live-pane member, the
|
|
12
|
+
# lead, or a member with no recorded pane (those are left for graceful
|
|
13
|
+
# shutdown). It no-ops when tmux is unavailable or nothing is stale.
|
|
14
|
+
#
|
|
15
|
+
# Usage: okstra-team-reconcile.sh [--list] <team-name>
|
|
16
|
+
# --list report what WOULD be deactivated; do not write (alias --dry-run).
|
|
17
|
+
#
|
|
18
|
+
# Failures are non-fatal to the run — teardown must never block on this.
|
|
19
|
+
set -u
|
|
20
|
+
|
|
21
|
+
_dir="$(cd -P "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
22
|
+
# Logic lives in okstra_ctl.team_reconcile. In the repo layout the package is a
|
|
23
|
+
# bin-sibling (scripts/okstra_ctl); in the installed layout it is under
|
|
24
|
+
# $OKSTRA_HOME/lib/python. Put both on PYTHONPATH so either resolves.
|
|
25
|
+
home="${OKSTRA_HOME:-$HOME/.okstra}"
|
|
26
|
+
export PYTHONPATH="${_dir}:${home}/lib/python${PYTHONPATH:+:$PYTHONPATH}"
|
|
27
|
+
|
|
28
|
+
exec python3 -c 'import sys; from okstra_ctl.team_reconcile import main; sys.exit(main(sys.argv[1:]))' "$@"
|
package/runtime/bin/okstra.sh
CHANGED
|
@@ -80,6 +80,7 @@ okstra execution summary:
|
|
|
80
80
|
executor (implementation only): ${EXECUTOR_OVERRIDE:-default(claude)}
|
|
81
81
|
approved plan: ${APPROVED_PLAN_PATH:-None}
|
|
82
82
|
approve ack (CLI 승인 의사): ${APPROVE_PLAN_ACK}
|
|
83
|
+
implementation option (선택 옵션): ${IMPLEMENTATION_OPTION:-None(fallback to Recommended Option)}
|
|
83
84
|
related tasks: ${RELATED_TASKS_RAW:-None}
|
|
84
85
|
CONFIRM_EOF
|
|
85
86
|
printf 'Continue? [y/yes]: ' >&2
|
|
@@ -117,6 +118,7 @@ PY_ARGS=(
|
|
|
117
118
|
[[ -n "${RELATED_TASKS_RAW-}" ]] && PY_ARGS+=(--related-tasks "$RELATED_TASKS_RAW")
|
|
118
119
|
[[ -n "${APPROVED_PLAN_PATH-}" ]] && PY_ARGS+=(--approved-plan "$APPROVED_PLAN_PATH")
|
|
119
120
|
[[ "$APPROVE_PLAN_ACK" == "true" ]] && PY_ARGS+=(--approve)
|
|
121
|
+
[[ -n "${IMPLEMENTATION_OPTION-}" ]] && PY_ARGS+=(--implementation-option "$IMPLEMENTATION_OPTION")
|
|
120
122
|
[[ -n "${CLARIFICATION_RESPONSE_PATH-}" ]] && PY_ARGS+=(--clarification-response "$CLARIFICATION_RESPONSE_PATH")
|
|
121
123
|
[[ -n "${WORK_CATEGORY-}" ]] && PY_ARGS+=(--work-category "$WORK_CATEGORY")
|
|
122
124
|
[[ -n "${BASE_REF-}" ]] && PY_ARGS+=(--base-ref "$BASE_REF")
|
|
@@ -39,6 +39,8 @@ Emit one `PROGRESS: <phase-id> <verb-phrase>` line as plain user-facing text at
|
|
|
39
39
|
|
|
40
40
|
- Task manifest: `{{TASK_MANIFEST_RELATIVE_PATH}}`
|
|
41
41
|
- Run manifest: `{{RUN_MANIFEST_RELATIVE_PATH}}`
|
|
42
|
+
- Active run context: `{{ACTIVE_RUN_CONTEXT_RELATIVE_PATH}}`
|
|
43
|
+
- Analysis packet: `{{ANALYSIS_PACKET_RELATIVE_PATH}}`
|
|
42
44
|
|
|
43
45
|
## Session
|
|
44
46
|
|
|
@@ -82,7 +84,7 @@ Emit one `PROGRESS: <phase-id> <verb-phrase>` line as plain user-facing text at
|
|
|
82
84
|
## Available MCP Servers
|
|
83
85
|
|
|
84
86
|
{{AVAILABLE_MCP_SERVERS}}
|
|
85
|
-
- The full usage policy and per-phase rules live in the
|
|
87
|
+
- The full usage policy and per-phase rules live in the analysis packet's `Available MCP Servers` extract. Inject only the one-line pointer below into each analysis-worker prompt: `**MCP servers:** follow the analysis packet's "Available MCP Servers" section (already in your Required reading).`
|
|
86
88
|
- **Invocation rule (forward to every worker prompt)**: MCP tools are addressed by their tool name through the host's tool interface — **never via `Bash`**. Claude-side workers call the tool directly (e.g. `mcp__<server>__<tool>`). Codex/Gemini workers call through their CLI's own MCP transport (e.g. `codex mcp call ...`). Running the tool name as a shell command is a contract violation and will always fail regardless of permission grants.
|
|
87
89
|
- Codex worker and Gemini worker run external CLIs; they can only use these MCP servers if their own CLI configs mirror them. If not, instruct the worker to record `MCP not available in this CLI` in its `Missing Information or Assumptions` block rather than guessing or shell-falling-back.
|
|
88
90
|
- MCP queries are evidence-grade. Cite server, table, and the SELECT used in worker output. MCP must NOT be used as a write path in any phase, including `implementation`.
|
|
@@ -91,4 +93,4 @@ Emit one `PROGRESS: <phase-id> <verb-phrase>` line as plain user-facing text at
|
|
|
91
93
|
|
|
92
94
|
- Source path: `{{CLARIFICATION_RESPONSE_RELATIVE_PATH}}`
|
|
93
95
|
- If the source path above is empty, no prior clarification response was attached to this run.
|
|
94
|
-
- If the source path is set, a copy is staged at `{{INSTRUCTION_SET_RELATIVE_PATH}}/clarification-response.md`. Read it before running workers; reconcile each `C-*` row in section
|
|
96
|
+
- If the source path is set, a copy is staged at `{{INSTRUCTION_SET_RELATIVE_PATH}}/clarification-response.md`. Read it before running workers; reconcile each `C-*` row in section 1 (`## 1. Clarification Items`) of the prior report against new evidence and record the outcome in the conditional `## 0. Clarification Response Carried In From Previous Run` section of this run's final report (render that heading only when carry-in is non-empty — the validator fails empty Section 0 stubs).
|