okstra 0.1.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.
Files changed (106) hide show
  1. package/README.md +36 -0
  2. package/bin/okstra +62 -0
  3. package/package.json +30 -0
  4. package/runtime/.gitkeep +0 -0
  5. package/runtime/BUILD.json +5 -0
  6. package/runtime/agents/SKILL.md +243 -0
  7. package/runtime/agents/TODO.md +168 -0
  8. package/runtime/agents/workers/claude-worker.md +106 -0
  9. package/runtime/agents/workers/codex-worker.md +179 -0
  10. package/runtime/agents/workers/gemini-worker.md +179 -0
  11. package/runtime/agents/workers/report-writer-worker.md +116 -0
  12. package/runtime/bin/okstra-central.sh +152 -0
  13. package/runtime/bin/okstra-codex-exec.sh +53 -0
  14. package/runtime/bin/okstra-error-log.py +295 -0
  15. package/runtime/bin/okstra-gemini-exec.sh +55 -0
  16. package/runtime/bin/okstra-token-usage.py +46 -0
  17. package/runtime/bin/okstra.sh +162 -0
  18. package/runtime/prompts/launch.template.md +52 -0
  19. package/runtime/prompts/profiles/error-analysis.md +43 -0
  20. package/runtime/prompts/profiles/final-verification.md +37 -0
  21. package/runtime/prompts/profiles/implementation-planning.md +85 -0
  22. package/runtime/prompts/profiles/implementation.md +71 -0
  23. package/runtime/prompts/profiles/requirements-discovery.md +43 -0
  24. package/runtime/python/lib/okstra/cli.sh +227 -0
  25. package/runtime/python/lib/okstra/globals.sh +157 -0
  26. package/runtime/python/lib/okstra/interactive.sh +411 -0
  27. package/runtime/python/lib/okstra/project-resolver.sh +57 -0
  28. package/runtime/python/lib/okstra/usage.sh +98 -0
  29. package/runtime/python/lib/okstra-ctl/cmd-batch.sh +59 -0
  30. package/runtime/python/lib/okstra-ctl/cmd-list.sh +35 -0
  31. package/runtime/python/lib/okstra-ctl/cmd-open.sh +36 -0
  32. package/runtime/python/lib/okstra-ctl/cmd-projects.sh +26 -0
  33. package/runtime/python/lib/okstra-ctl/cmd-reconcile.sh +27 -0
  34. package/runtime/python/lib/okstra-ctl/cmd-reindex.sh +38 -0
  35. package/runtime/python/lib/okstra-ctl/cmd-rerun.sh +326 -0
  36. package/runtime/python/lib/okstra-ctl/cmd-show.sh +27 -0
  37. package/runtime/python/lib/okstra-ctl/cmd-tail.sh +76 -0
  38. package/runtime/python/lib/okstra-ctl/main.sh +41 -0
  39. package/runtime/python/lib/okstra-ctl/prepare.sh +29 -0
  40. package/runtime/python/lib/okstra-ctl/usage.sh +23 -0
  41. package/runtime/python/okstra_ctl/__init__.py +125 -0
  42. package/runtime/python/okstra_ctl/backfill.py +253 -0
  43. package/runtime/python/okstra_ctl/batch.py +62 -0
  44. package/runtime/python/okstra_ctl/ids.py +84 -0
  45. package/runtime/python/okstra_ctl/index.py +216 -0
  46. package/runtime/python/okstra_ctl/invocation.py +49 -0
  47. package/runtime/python/okstra_ctl/jsonl.py +84 -0
  48. package/runtime/python/okstra_ctl/listing.py +156 -0
  49. package/runtime/python/okstra_ctl/locks.py +42 -0
  50. package/runtime/python/okstra_ctl/material.py +62 -0
  51. package/runtime/python/okstra_ctl/models.py +63 -0
  52. package/runtime/python/okstra_ctl/path_resolve.py +40 -0
  53. package/runtime/python/okstra_ctl/paths.py +251 -0
  54. package/runtime/python/okstra_ctl/project_meta.py +51 -0
  55. package/runtime/python/okstra_ctl/reconcile.py +166 -0
  56. package/runtime/python/okstra_ctl/render.py +1065 -0
  57. package/runtime/python/okstra_ctl/resolver.py +54 -0
  58. package/runtime/python/okstra_ctl/run.py +674 -0
  59. package/runtime/python/okstra_ctl/run_context.py +166 -0
  60. package/runtime/python/okstra_ctl/seeding.py +97 -0
  61. package/runtime/python/okstra_ctl/sequence.py +53 -0
  62. package/runtime/python/okstra_ctl/session.py +33 -0
  63. package/runtime/python/okstra_ctl/tmux.py +27 -0
  64. package/runtime/python/okstra_ctl/workers.py +64 -0
  65. package/runtime/python/okstra_ctl/workflow.py +182 -0
  66. package/runtime/python/okstra_project/__init__.py +41 -0
  67. package/runtime/python/okstra_project/resolver.py +126 -0
  68. package/runtime/python/okstra_project/state.py +170 -0
  69. package/runtime/python/okstra_token_usage/__init__.py +26 -0
  70. package/runtime/python/okstra_token_usage/blocks.py +62 -0
  71. package/runtime/python/okstra_token_usage/claude.py +97 -0
  72. package/runtime/python/okstra_token_usage/cli.py +84 -0
  73. package/runtime/python/okstra_token_usage/codex.py +80 -0
  74. package/runtime/python/okstra_token_usage/collect.py +161 -0
  75. package/runtime/python/okstra_token_usage/gemini.py +77 -0
  76. package/runtime/python/okstra_token_usage/jsonl_io.py +18 -0
  77. package/runtime/python/okstra_token_usage/paths.py +22 -0
  78. package/runtime/python/okstra_token_usage/pricing.py +71 -0
  79. package/runtime/python/okstra_token_usage/report.py +64 -0
  80. package/runtime/templates/prd/brief.template.md +273 -0
  81. package/runtime/templates/project-docs/task-index.template.md +65 -0
  82. package/runtime/templates/reports/error-analysis-input.template.md +80 -0
  83. package/runtime/templates/reports/final-report.template.md +167 -0
  84. package/runtime/templates/reports/final-verification-input.template.md +67 -0
  85. package/runtime/templates/reports/implementation-input.template.md +81 -0
  86. package/runtime/templates/reports/implementation-planning-input.template.md +93 -0
  87. package/runtime/templates/reports/quick-input.template.md +64 -0
  88. package/runtime/templates/reports/schedule.template.md +168 -0
  89. package/runtime/templates/reports/settings.template.json +101 -0
  90. package/runtime/templates/reports/task-brief.template.md +165 -0
  91. package/runtime/validators/lib/common.sh +44 -0
  92. package/runtime/validators/lib/fixtures.sh +322 -0
  93. package/runtime/validators/lib/paths.sh +44 -0
  94. package/runtime/validators/lib/runners.sh +140 -0
  95. package/runtime/validators/lib/summary.sh +15 -0
  96. package/runtime/validators/lib/validate-assets.sh +44 -0
  97. package/runtime/validators/lib/validate-prompt-metadata.sh +267 -0
  98. package/runtime/validators/lib/validate-tasks.sh +335 -0
  99. package/runtime/validators/validate-run.py +568 -0
  100. package/runtime/validators/validate-schedule.py +665 -0
  101. package/runtime/validators/validate-workflow.sh +190 -0
  102. package/src/doctor.mjs +127 -0
  103. package/src/install.mjs +355 -0
  104. package/src/paths.mjs +132 -0
  105. package/src/uninstall.mjs +122 -0
  106. package/src/version.mjs +20 -0
package/README.md ADDED
@@ -0,0 +1,36 @@
1
+ # okstra
2
+
3
+ Runtime installer and path resolver for [okstra](https://github.com/Devonshin/okstra) cross-verification skills.
4
+
5
+ This package is **not** the okstra skills themselves. It carries the python and bash runtime that the skills depend on, and exposes commands that the skills invoke to discover where everything lives.
6
+
7
+ ## Companion: skills
8
+
9
+ Skills are distributed separately through the `skills` CLI:
10
+
11
+ ```bash
12
+ npx skills@latest add Devonshin/okstra
13
+ ```
14
+
15
+ ## Install runtime
16
+
17
+ ```bash
18
+ npx okstra@latest install
19
+ ```
20
+
21
+ This populates `~/.okstra/lib/python/`, `~/.okstra/bin/`, and `~/.okstra/version`. The `agents/` directory stays inside this package — skills resolve its path with `okstra paths --field agents`.
22
+
23
+ ## Commands
24
+
25
+ | Command | Description |
26
+ |---|---|
27
+ | `okstra install` | Install runtime into `~/.okstra` |
28
+ | `okstra ensure-installed` | Idempotent check + reinstall if stale; skills call this on every run |
29
+ | `okstra paths` | Print runtime paths (`agents`, `pythonpath`, `bin`, `home`, `version`) |
30
+ | `okstra doctor` | Diagnose the installed runtime |
31
+
32
+ Run `okstra --help` for full usage.
33
+
34
+ ## Status
35
+
36
+ Pre-release (`0.1.0-pre.x`). Layout and command surface may change before `0.1.0`.
package/bin/okstra ADDED
@@ -0,0 +1,62 @@
1
+ #!/usr/bin/env node
2
+ import { getPackageVersion } from "../src/version.mjs";
3
+
4
+ const COMMANDS = new Map([
5
+ ["paths", () => import("../src/paths.mjs").then((m) => m.run)],
6
+ ["install", () => import("../src/install.mjs").then((m) => m.runInstall)],
7
+ ["ensure-installed", () => import("../src/install.mjs").then((m) => m.runEnsureInstalled)],
8
+ ["uninstall", () => import("../src/uninstall.mjs").then((m) => m.runUninstall)],
9
+ ["doctor", () => import("../src/doctor.mjs").then((m) => m.run)],
10
+ ]);
11
+
12
+ const USAGE = `okstra-cli — runtime installer and path resolver for okstra skills
13
+
14
+ Usage:
15
+ okstra <command> [options]
16
+
17
+ Commands:
18
+ install Install okstra runtime into ~/.okstra
19
+ ensure-installed Verify install is fresh; reinstall if stale (idempotent)
20
+ uninstall Remove installed runtime (user data preserved by default)
21
+ paths Print runtime paths (agents/pythonpath/bin/home/version)
22
+ doctor Diagnostic check of the installed runtime
23
+
24
+ Global options:
25
+ --version Print okstra-cli version and exit
26
+ --help Print this help
27
+
28
+ Run 'okstra <command> --help' for command-specific options.
29
+ `;
30
+
31
+ async function main(argv) {
32
+ const args = argv.slice(2);
33
+
34
+ if (args.length === 0 || args[0] === "--help" || args[0] === "-h") {
35
+ process.stdout.write(USAGE);
36
+ return 0;
37
+ }
38
+
39
+ if (args[0] === "--version" || args[0] === "-v") {
40
+ process.stdout.write(`${await getPackageVersion()}\n`);
41
+ return 0;
42
+ }
43
+
44
+ const [cmd, ...rest] = args;
45
+ const loader = COMMANDS.get(cmd);
46
+ if (!loader) {
47
+ process.stderr.write(`unknown command: ${cmd}\n\n${USAGE}`);
48
+ return 2;
49
+ }
50
+
51
+ try {
52
+ const run = await loader();
53
+ const exitCode = await run(rest);
54
+ return typeof exitCode === "number" ? exitCode : 0;
55
+ } catch (err) {
56
+ process.stderr.write(`error: ${err.message}\n`);
57
+ if (process.env.OKSTRA_DEBUG) process.stderr.write(`${err.stack}\n`);
58
+ return 1;
59
+ }
60
+ }
61
+
62
+ main(process.argv).then((code) => process.exit(code));
package/package.json ADDED
@@ -0,0 +1,30 @@
1
+ {
2
+ "name": "okstra",
3
+ "version": "0.1.0",
4
+ "description": "Runtime installer and path resolver for okstra cross-verification skills",
5
+ "license": "MIT",
6
+ "author": "devonshin",
7
+ "repository": {
8
+ "type": "git",
9
+ "url": "git+https://github.com/Devonshin/okstra.git",
10
+ "directory": "packages/okstra"
11
+ },
12
+ "type": "module",
13
+ "bin": {
14
+ "okstra": "bin/okstra"
15
+ },
16
+ "files": [
17
+ "bin/",
18
+ "src/",
19
+ "runtime/",
20
+ "README.md"
21
+ ],
22
+ "engines": {
23
+ "node": ">=18"
24
+ },
25
+ "scripts": {
26
+ "build": "node scripts/build.mjs",
27
+ "prepack": "node scripts/build.mjs",
28
+ "test": "node --test test/"
29
+ }
30
+ }
File without changes
@@ -0,0 +1,5 @@
1
+ {
2
+ "package": "0.1.0",
3
+ "builtAt": "2026-05-11T08:09:27.712Z",
4
+ "repoRoot": "/Volumes/Workspaces/workspace/projects/Okstra"
5
+ }
@@ -0,0 +1,243 @@
1
+ ---
2
+ name: okstra
3
+ description: Use when the user says "okstra", "cross verify", "cross-check with other AIs", "compare Claude, Codex, and Gemini", or asks for multi-agent comparison against a prepared task bundle.
4
+ ---
5
+
6
+ # OKSTRA Skill
7
+
8
+ ## Overview
9
+
10
+ Claude lead orchestrates multiple AI workers (Claude, Codex, Gemini) against a prepared task bundle, collects their independent outputs, supervises convergence, and ensures the final report is produced. When `Report writer worker` is in the selected roster, the final report file is **authored by the Report writer worker** — Claude lead reviews and approves but does not write the file itself. Claude lead never substitutes its own reasoning for a worker result, and never bypasses a rostered Report writer worker by writing the report directly.
11
+
12
+ ## When to Use
13
+
14
+ - User explicitly says "okstra", "cross verify", or "cross-check with other AIs"
15
+ - User wants multi-agent comparison or cross-check
16
+ - A prepared task bundle exists with `task-manifest.json`
17
+
18
+ **Do NOT use** for single-agent tasks or when no task bundle is prepared.
19
+
20
+ ## Sub-skill index
21
+
22
+ This SKILL.md is the operating contract and phase index. Detailed procedures live in the sub-skills below; consult them whenever the corresponding phase is active.
23
+
24
+ | Skill | Scope |
25
+ |-------|-------|
26
+ | [okstra-context-loader](./skills/okstra-context-loader/SKILL.md) | Phase 1 task-bundle discovery, manifest fields, run-directory layout |
27
+ | [okstra-team-contract](./skills/okstra-team-contract/SKILL.md) | Phase 2–5 worker roster, model assignment rules, prompt composition (anchor headers, `[Required reading]`, `[Error reporting]`), worker output contract, terminal statuses, usage tracking |
28
+ | [okstra-convergence](./skills/okstra-convergence/SKILL.md) | Phase 5.5 convergence loop, finding categories, reverify dispatch (anchor headers, required-reading suppression), convergence state schema |
29
+ | [okstra-report-writer](./skills/okstra-report-writer/SKILL.md) | Phase 6 final-report authorship, dispatch template, resume-safe dispatch, shared-graph integrity check, Phase 7 token-usage collector |
30
+ | [okstra-status](./skills/okstra-status/SKILL.md) | Project/task status views and `workStatus` updates |
31
+ | [okstra-history](./skills/okstra-history/SKILL.md) | Past-run history, re-run command assembly, resume helper |
32
+ | [okstra-report-finder](./skills/okstra-report-finder/SKILL.md) | Locate the final report for a given task key |
33
+ | [okstra-schedule](./skills/okstra-schedule/SKILL.md) | Generate a consolidated work schedule for a task-group |
34
+ | [okstra-time-summary](./skills/okstra-time-summary/SKILL.md) | Per-task / per-worker elapsed-time breakdown |
35
+
36
+ ## Quick Reference
37
+
38
+ | Phase | Action | Key sub-skill |
39
+ |-------|--------|---------------|
40
+ | 1. Intake | Read task bundle in order | `okstra-context-loader` |
41
+ | 1.5 Graph hint | Build shared knowledge graph (optional) | this SKILL — see "Optional shared knowledge graph" below |
42
+ | 2. Prompts | Prepare shared + role-specific prompts | `okstra-team-contract` |
43
+ | 2.5 Team contract | Load operating rules for selected roster | `okstra-team-contract` |
44
+ | 3. Team creation | Create team, fallback if it fails | this SKILL — see "Phase 3" below |
45
+ | 4. Execution | Spawn analysis workers (Teams preferred) | `okstra-team-contract` |
46
+ | 5. Fallback | Sequential/background dispatch when Teams unavailable | `okstra-team-contract` |
47
+ | 5.5 Convergence | Cross-verify findings across workers | `okstra-convergence` |
48
+ | 6. Synthesis | Dispatch Report writer worker, review draft | `okstra-report-writer` |
49
+ | 7. Persist | Run token-usage collector, update manifests | `okstra-report-writer` |
50
+
51
+ ## Core operating contract
52
+
53
+ - `Claude lead` owns orchestration, convergence supervision, and final-report ownership (review/approval). It does NOT author the final-report file when `Report writer worker` is in the roster.
54
+ - Standard worker roles: `Claude worker`, `Codex worker`, `Gemini worker`, `Report writer worker`. If the current run selects a subset, use only that subset with exact role labels from the task bundle.
55
+ - `Report writer worker`, when in the roster, is the **author** of the final-report file. Lead reviews the draft and may request a revision via a follow-up dispatch, but MUST NOT write the report itself as a "shortcut". The only legal lead-authored fallback is when a Report writer worker dispatch was actually attempted and recorded a terminal status of `error`/`timeout`/`not-run` with an explicit reason in team-state — see [okstra-report-writer](./skills/okstra-report-writer/SKILL.md) "Lead-authored fallback".
56
+ - "Session resume", "team is no longer alive", and similar are NOT valid reasons to skip Report writer worker dispatch — see [okstra-report-writer](./skills/okstra-report-writer/SKILL.md) "Resume-safe dispatch".
57
+ - If the brief is incomplete, continue with explicit uncertainty markers rather than fabricating confidence.
58
+ - Required roles must not be replaced by unnamed generic parallel workers. Before the final verdict, every selected worker must have either a saved result file or an explicit terminal status with reason. Any attempted worker with status `completed`, `timeout`, or `error` must also have a saved worker prompt history file at its assigned run-level prompt path.
59
+
60
+ ## Lifecycle Phase Boundaries (BLOCKING)
61
+
62
+ A single okstra run executes **exactly one** lifecycle phase. The phase is given by `task-manifest.json.workflow.currentPhase` (or, equivalently, the run's `Task Type`). The lead and every worker MUST stay inside that phase's boundary for the duration of the run. Crossing the boundary is a contract violation, not a productivity gain.
63
+
64
+ | Lifecycle phase | Allowed outputs | Forbidden actions |
65
+ |-----------------|-----------------|-------------------|
66
+ | `requirements-discovery` | classification, routing decision, missing-input list, next-phase recommendation | code edits, plan documents, build/test execution that mutates state |
67
+ | `error-analysis` | evidence, root-cause hypotheses, reproduction gaps, validation paths | code edits, implementation design, build/migration/deploy execution |
68
+ | `implementation-planning` | option matrix, trade-offs, dependencies, recommended order, validation/rollback strategy, **explicit user-approval request** | source code edits, file writes outside the run's `reports/`, `prompts/`, `state/`, `manifests/`, `worker-results/`, `status/`, `sessions/` directories, build/migration/deploy execution |
69
+ | `implementation` | code edits authorised by an approved plan, accompanying tests | starting work without an approved `implementation-planning` final report carried in via `--clarification-response` or referenced in the brief |
70
+ | `final-verification` | acceptance verdict, residual risk, regression notes; read-only execution of existing test/validation commands is permitted | source code edits, refactors, scope expansion |
71
+
72
+ Phase-transition checklist (lead, end of run):
73
+
74
+ 1. Confirm the current phase's required outputs are complete and recorded in the final report.
75
+ 2. Set `workflow.phaseStates.<currentPhase>.state = "completed"` in `task-manifest.json` (validator does this when the run passes; verify the value).
76
+ 3. Update `workflow.lastCompletedPhase` and `workflow.nextRecommendedPhase`.
77
+ 4. **Do NOT start the next phase inside the current run.** A new okstra invocation with the new `--task-type` is the only legal way to advance.
78
+
79
+ User-utterance interpretation rule:
80
+
81
+ - "다음 단계 진행해" / "proceed to the next step" / equivalent phrases are scoped to **the current phase only**. Interpret them as "produce the remaining outputs of the current phase," never as "start the next lifecycle phase."
82
+ - If the current phase's outputs are already complete and the user clearly wants to advance, reply with the phase-transition checklist above and the exact next-run command. Wait for explicit user confirmation before any action that belongs to the next phase.
83
+ - If `nextRecommendedPhase` is `implementation-planning`, the next run produces a **plan**, not code. The next run after that is `implementation`.
84
+
85
+ ## Default model assignments
86
+
87
+ Unless the task bundle overrides:
88
+
89
+ | Role | Model | subagent_type | Notes |
90
+ |------|-------|---------------|-------|
91
+ | Claude lead | opus | -- | orchestration + synthesis |
92
+ | Report writer worker | opus | report-writer-worker | authors the final report file (`agents/report-writer-worker.md`) |
93
+ | Claude worker | sonnet | claude-worker | defined in `agents/claude-worker.md` |
94
+ | Codex worker | gpt-5.5 | codex-worker | defined in `agents/codex-worker.md` |
95
+ | Gemini worker | auto | gemini-worker | defined in `agents/gemini-worker.md` |
96
+
97
+ If the prepared task bundle contains explicit model assignments, those assignments are canonical for the run. All three analysis workers use dedicated agent definitions; Codex/Gemini wrappers handle external CLI invocation internally; Claude worker runs as an in-process subagent with explicitly registered MCP tools so it does not fall back to `claude --mcp-cli` Bash invocations.
98
+
99
+ ## Phase 1: Task-bundle intake and required reading order
100
+
101
+ **REQUIRED SUB-SKILL:** Invoke [okstra-context-loader](./skills/okstra-context-loader/SKILL.md) first to discover task bundle paths.
102
+
103
+ 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 `.project-docs/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 `.project-docs/okstra/discovery/task-catalog.json` first.
104
+
105
+ After context-loader completes, read the following files. The ordering below reflects logical priority for synthesis; for execution, lead MUST issue all Read calls **in a single message (parallel reads)** — these files are independent and serial reads waste several seconds per run with no benefit.
106
+
107
+ 1. `task-manifest.json` (found by context-loader)
108
+ 2. `task-index.md` only if a quick human summary is useful
109
+ 3. `instruction-set/analysis-profile.md`
110
+ 4. `instruction-set/analysis-material.md`
111
+ 5. `instruction-set/reference-expectations.md`
112
+ 6. `instruction-set/task-brief.md`
113
+ 7. `instruction-set/final-report-template.md`
114
+ 8. the current run manifest under `runs/<task-type>/manifests/`
115
+ 9. the current run team-state artifact
116
+
117
+ Extract: 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.
118
+
119
+ If previous run reports exist, use as historical context only. If `history/timeline.json` exists, use it to review past runs. 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, treat that as missing information and say `I don't know` rather than inventing expected states.
120
+
121
+ ## Phase 2 — Phase 5: Prompt preparation, team creation, execution, fallback
122
+
123
+ These phases are governed by [okstra-team-contract](./skills/okstra-team-contract/SKILL.md). It is the canonical source for:
124
+
125
+ - Worker prompt anchor headers and body composition rules.
126
+ - The `[Required reading]` clause (audience-scoped enumeration: analysis workers vs report-writer vs reverify dispatches).
127
+ - The `[Error reporting]` clause and the asymmetry between claude-worker and codex/gemini-worker prompts.
128
+ - Worker output contract (sections 0–5), header standard, terminal statuses, errors-sidecar schema.
129
+ - Token-usage tracking conventions.
130
+
131
+ `Report writer worker` is NOT an analysis worker. Do not dispatch it in Phase 4/5 alongside analysis workers. It is invoked only in Phase 6 — see [okstra-report-writer](./skills/okstra-report-writer/SKILL.md).
132
+
133
+ ### Phase 3 — Team creation
134
+
135
+ Always attempt team creation first. Do not check environment variables or guess availability.
136
+
137
+ 1. Call `TeamCreate(team_name: "okstra-<task-key>", description: "Lead-plus-worker okstra run for <task-key>")`.
138
+ 2. If `TeamCreate` succeeds, proceed to Phase 4.
139
+ 3. If `TeamCreate` fails (tool error, permission denied, or unavailable), proceed to Phase 5 fallback.
140
+
141
+ Use agent and subagent names that map cleanly to the selected worker roles. Do not create ambiguous role names that differ from `Claude worker`, `Codex worker`, `Gemini worker`, or `Report writer worker`.
142
+
143
+ ### Phase 4 / Phase 5 — Execution and error-log dump
144
+
145
+ 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.
146
+
147
+ After each worker terminates (any terminal status), if a worker errors sidecar exists at `runs/.../worker-results/<role-slug>-errors.json`, dump it to the run error log:
148
+
149
+ ```bash
150
+ python3 scripts/okstra-error-log.py append-from-worker \
151
+ --sidecar <sidecar> \
152
+ --out <runDir>/logs/errors-<task-type>-<seq>.jsonl \
153
+ --task-key <taskKey> --agent <agent> --agent-role <role> --model <model>
154
+ ```
155
+
156
+ For Codex/Gemini wrappers: if the CLI returns non-zero, times out, or hits a rate limit, immediately call `okstra-error-log.py append-observed --error-type cli-failure ...` with the captured exit code, duration, message, and stderr excerpt. The wrapper subagent does this from inside its own Bash tool — Lead does NOT need to re-record. Token usage is NOT available from Agent tool results in real time; it is collected post-hoc at the start of Phase 7.
157
+
158
+ ## Phase 5.5: Convergence loop
159
+
160
+ **REQUIRED SUB-SKILL:** Invoke [okstra-convergence](./skills/okstra-convergence/SKILL.md) for iterative cross-verification.
161
+
162
+ Convergence is enabled by default. Configure via task-manifest.json:
163
+
164
+ - `convergence.enabled`: true/false (default: true)
165
+ - `convergence.maxRounds`: 1–3 — **phase-aware default**: `1` for `requirements-discovery`, `2` for all other task types
166
+ - `convergence.verificationMode`: `"lightweight"` | `"full-reanalysis"` (default: `"lightweight"`)
167
+
168
+ When `task-manifest.json` does not set `convergence.maxRounds`, lead MUST resolve the effective value via the phase-aware default above before entering Phase 5.5, and record the resolved value in the convergence state artifact.
169
+
170
+ If any re-verification batch yields a `verification-error` terminal status, or a worker result fails the contract, Lead MUST record one event per violation via `python3 scripts/okstra-error-log.py append-observed --error-type contract-violation --agent <offending-agent> ...`. Use `agent: "claude-lead"` only when the violation is detected internally without a specific worker.
171
+
172
+ If convergence is disabled, proceed directly to Phase 6 with the raw worker results.
173
+
174
+ ## Phase 6: Final report assembly
175
+
176
+ **REQUIRED SUB-SKILL:** Invoke [okstra-report-writer](./skills/okstra-report-writer/SKILL.md) for report structure, dispatch template, resume-safe dispatch, shared-graph integrity check, and lead-authored fallback rules.
177
+
178
+ ### Authoring ownership (BLOCKING)
179
+
180
+ If `Report writer worker` is in the selected roster (`recommendedWorkers` / `resultContract.requiredWorkerRoles`), **Lead MUST dispatch it to write `runs/<task-type>/reports/final-report-<task-type>-<seq>.md`**. Lead does NOT write that file. Lead's role in this phase is: prepare the report-writer prompt (carrying convergence output, all worker results, and reference expectations), dispatch, then review the produced file.
181
+
182
+ Do not write the final verdict until every analysis worker role has either a saved result or a terminal status entry. The convergence output provides four finding categories:
183
+
184
+ 1. Full Consensus
185
+ 2. Partial Consensus
186
+ 3. Contested
187
+ 4. Worker-Unique
188
+
189
+ All categories must appear in the final synthesis. Do not omit contested or worker-unique findings. If the brief does not define a stricter format, follow `instruction-set/final-report-template.md`. If `reference-expectations.md` defines explicit expected states for config files or deployment manifests, include a clear match/gap assessment.
190
+
191
+ If only one worker result is usable: reduced-confidence synthesis. If evidence is missing: say `I don't know`. If no meaningful worker differences: say so explicitly.
192
+
193
+ ## Phase 7: Artifact persistence and validator handoff
194
+
195
+ The detailed persistence checklist and the BLOCKING token-usage collector invocation live in [okstra-report-writer](./skills/okstra-report-writer/SKILL.md). Persist the run yourself — do not assume okstra saves the final artifacts for you.
196
+
197
+ Order of operations:
198
+
199
+ 1. Run the token-usage collector with `--substitute-final-report`. The final-report file MUST already exist before this step runs.
200
+ 2. Verify final report exists at the expected report path. When `Report writer worker` is in the roster, that worker authored the file in Phase 6 — Lead's job here is to **verify** structure and template conformance.
201
+ 3. Update team-state artifact (preserve usage fields written by the script).
202
+ 4. Update run manifest.
203
+ 5. Update `task-manifest.json`, including lifecycle fields (work category, phase states, next recommended phase, approval markers, safe-resume checkpoint).
204
+ 6. Update `task-index.md`.
205
+ 7. Write final status file if expected.
206
+
207
+ Keep the assigned worker prompt history paths stable in `team-state`, `run-manifest`, and `task-manifest`. Do not rewrite prompt artifacts to `/tmp` or omit prompt metadata for attempted workers.
208
+
209
+ After persistence, the run-level error log lives at `<runDir>/logs/errors-<task-type>-<seq>.jsonl`. Useful jq one-liners for retrospective review:
210
+
211
+ ```bash
212
+ # Counts per agent
213
+ jq -s 'group_by(.agent) | map({agent: .[0].agent, count: length})' <runDir>/logs/errors-<task-type>-<seq>.jsonl
214
+
215
+ # Counts per errorType
216
+ jq -s 'group_by(.errorType) | map({type: .[0].errorType, count: length})' <runDir>/logs/errors-<task-type>-<seq>.jsonl
217
+ ```
218
+
219
+ The errors log is informational. Its presence/absence does not affect the final verdict. Do not block report writing on it.
220
+
221
+ After persistence, reply briefly in Korean with: completion status, final report path, team-state path, validator result, resume command path, any remaining blocker.
222
+
223
+ ## Common Mistakes
224
+
225
+ | Mistake | Fix |
226
+ |---------|-----|
227
+ | Substituting Claude lead reasoning for a worker result | Claude lead synthesizes only — spawn the worker |
228
+ | Skipping a worker silently | Always record terminal status with reason |
229
+ | Writing verdict before all workers report | Wait for all results or explicit terminal statuses |
230
+ | Ignoring task bundle model assignments | Task bundle overrides are canonical |
231
+ | Sending identical prompts to all workers | Add role-specific emphasis per [okstra-team-contract](./skills/okstra-team-contract/SKILL.md) |
232
+ | Omitting contested or worker-unique findings | All categories must appear in the report |
233
+ | Running full re-analysis when lightweight suffices | Default lightweight; full only when manifest opts in |
234
+ | Using `/tmp/*prompt*.txt` for worker prompt persistence | Persist the exact worker prompt to the assigned run-level `prompts/` path |
235
+ | Lead writes `final-report-<suffix>.md` itself when `Report writer worker` is in the roster | Dispatch the Report writer worker per [okstra-report-writer](./skills/okstra-report-writer/SKILL.md) "Phase 6 dispatch template" |
236
+ | Skipping Report writer worker dispatch citing "session resume constraint" or "team is gone" | No such constraint exists — see [okstra-report-writer](./skills/okstra-report-writer/SKILL.md) "Resume-safe dispatch" |
237
+ | Using `subagent_type: "general-purpose"` for Report writer worker | Use `subagent_type: "report-writer-worker"` |
238
+ | Including `final-report-template.md` in analysis worker `[Required reading]` | Template belongs only in the report-writer prompt — see [okstra-team-contract](./skills/okstra-team-contract/SKILL.md) audience-scoped enumeration |
239
+ | Injecting `[Required reading]` into lightweight reverify prompts | Lightweight reverify forbids re-reading source materials — see [okstra-convergence](./skills/okstra-convergence/SKILL.md) "Reverify prompt: required-reading suppression" |
240
+ | Letting `convergence.maxRounds` default to 2 for `requirements-discovery` | Resolve effective default to `1` for discovery and record in convergence state artifact |
241
+ | Issuing serial Read calls in Phase 1 | The intake files are independent — issue all Read calls in a single message (parallel) |
242
+ | Flagging the claude-worker dispatch prompt as "incomplete" because it lacks `[Required reading]` / `[Error reporting]` blocks | Intentional asymmetry — see [okstra-team-contract](./skills/okstra-team-contract/SKILL.md) "Asymmetry between claude-worker and codex/gemini-worker prompts" |
243
+ | Skipping `--substitute-final-report` in the Phase 7 collector run | Always pass the flag — see [okstra-report-writer](./skills/okstra-report-writer/SKILL.md) "Phase 7 token-usage collector" |
@@ -0,0 +1,168 @@
1
+ # okstra (okstra) — 후속 개선 TODO
2
+
3
+ 이 파일은 okstra 워크플로우의 워커 종료 / Phase 4 대기 시간 개선 작업, 그리고 워커 설정 일관성 감사(2026-05-03)에서 도출됐지만 단일 라운드에서 안전하게 처리할 수 없어 별도 라운드로 미룬 항목을 기록한다.
4
+
5
+ ---
6
+
7
+ ## 항목 C2 — Worker-results 경로 표준 결정 [해결됨, 2026-05-03]
8
+
9
+ ### 결정
10
+
11
+ 런타임이 도달한 layout을 canonical로 채택했다(`scripts/okstra.sh:1495-1523` 기준):
12
+
13
+ ```
14
+ runs/<task-type>/
15
+ ├── manifests/ (run-manifest-<task-type>-<seq>.json)
16
+ ├── state/ (team-state-<task-type>-<seq>.json, convergence-<task-type>-<seq>.json)
17
+ ├── prompts/ (claude-execution-prompt-<task-type>-<seq>.md, <role>-worker-prompt-<task-type>-<seq>.md)
18
+ ├── reports/ (final-report-<task-type>-<seq>.md)
19
+ ├── status/ (final-<task-type>-<seq>.status)
20
+ ├── sessions/ (claude-resume-<task-type>-<seq>.sh)
21
+ ├── logs/ (errors-<task-type>-<seq>.jsonl, optional)
22
+ └── worker-results/
23
+ ├── claude-worker-<task-type>-<seq>.md
24
+ ├── codex-worker-<task-type>-<seq>.md
25
+ ├── gemini-worker-<task-type>-<seq>.md
26
+ └── report-writer-worker-<task-type>-<seq>.md
27
+ ```
28
+
29
+ 규칙:
30
+ - `<seq>` = 3-digit zero-padded sequence number (`001`, `002`, …) scoped **per-category directory** (i.e., scanned independently per `manifests/`, `prompts/`, `reports/`, `status/`, `state/`, `sessions/`, `worker-results/`). 파일명 infix이며 디렉토리 세그먼트가 아님.
31
+ - 카테고리별 카운터이므로 같은 run에서도 디렉토리마다 `<seq>` 값이 다를 수 있다(이전 run이 일부 카테고리만 기록한 경우). 한 run의 cross-category 식별자는 manifest의 `runDateTimeSegment`(ISO timestamp) 필드이며, 파일명 infix가 아니다.
32
+ - `runs/<date>/...` 옛 패턴(date-first)은 폐기. `<date>` 디렉토리 세그먼트는 더 이상 사용하지 않음.
33
+ - 같은 task-type 재실행 시 같은 디렉토리를 재사용하되, 모든 run-level artifact는 `<task-type>-<seq>` infix로 분리되므로 덮어쓰지 않는다.
34
+
35
+ ### 수정 내역
36
+
37
+ - `scripts/okstra.sh` 의 `CLAUDE_WORKER_RESULT_FILE` 외 4종 파일명에 `$RUN_FILE_SUFFIX` 추가 (이전엔 suffix가 없어 재실행 시 덮어쓰기됨).
38
+ - 옛 `runs/<task-type>/<task-type>-<seq>/...` 및 `runs/<date>/<task-type>/...` 표기를 모두 정리해 reality에 맞춤. 영향 파일:
39
+ - `agents/SKILL.md`
40
+ - `agents/workers/{claude,codex,gemini,report-writer}-worker.md`
41
+ - `skills/okstra-context-loader/SKILL.md` (canonical 트리 갱신)
42
+ - `skills/okstra-team-contract/SKILL.md`
43
+ - `skills/okstra-convergence/SKILL.md`
44
+ - `skills/okstra-report-writer/SKILL.md`
45
+ - `OKSTRA_USAGE_MANUAL.md`
46
+
47
+ ---
48
+
49
+ ## 항목 F4 — `implementation.md` 프로필의 워커 이름 매핑 누락 [블로킹: 설계 결정 필요]
50
+
51
+ ### 문제
52
+
53
+ [prompts/profiles/implementation.md](../../../prompts/profiles/implementation.md) 프로필은 다른 4개 프로필과 달리 다음 워커 이름을 사용한다:
54
+
55
+ - `Claude executor` (유일하게 Edit/Write/state-mutating Bash 허용)
56
+ - `Claude verifier`
57
+ - `Codex verifier`
58
+ - `Gemini verifier`
59
+
60
+ 그런데 **이 4개 역할 이름 중 어느 것도 [agents/workers/](agents/) 의 `*.md` 파일로 등록돼 있지 않음**. 등록된 워커 정의는 `claude-worker.md`, `codex-worker.md`, `gemini-worker.md`, `report-writer-worker.md` 4종.
61
+
62
+ ### 결과로 발생 가능한 모호성
63
+
64
+ Lead가 implementation.md 프로필을 따라 Phase 4 dispatch를 시도할 때:
65
+
66
+ - `subagent_type: "claude-executor"` 같은 값이 실제로는 등록 안 돼 있어 dispatch 실패.
67
+ - 또는 Lead가 임의로 `subagent_type: "claude-worker"` 로 매핑해 dispatch — 그러면 implementation 프로필의 핵심 안전장치(`Claude executor`만 Edit/Write 허용) 가 작동하지 않음. `claude-worker.md` 정의는 read-only를 강제하지 않음.
68
+
69
+ ### 결정해야 할 것
70
+
71
+ 1. **별도 워커 정의 파일 신설**: `agents/claude-executor.md`, `agents/claude-verifier.md`, `agents/codex-verifier.md`, `agents/gemini-verifier.md` 4종을 만들어 등록 — 각 정의에 read-only / write-allowed 제약을 직접 인코딩.
72
+ 2. **기존 워커 재사용 + 프롬프트 레벨 제약**: `claude-worker` 등을 그대로 쓰되 lead의 dispatch 프롬프트에서 "이번 dispatch에서는 Edit/Write 금지" 같은 룰을 주입. 단점: 프롬프트만으로 강제되며 도구 레벨 차단이 아님.
73
+ 3. **implementation.md 프로필 자체 폐기/리네임**: 다른 프로필이 `claude-worker` 등 표준 이름을 쓰므로 implementation도 같은 이름 체계로 재작성.
74
+
75
+ ### 권장
76
+
77
+ 옵션 1이 가장 안전(`tools` 화이트리스트로 도구 레벨 차단 가능). 다만 신규 워커 정의 4개 작성은 작업량이 있어 별도 라운드에서 다룬다.
78
+
79
+ ### 추가로 점검할 것
80
+
81
+ - okstra-team-contract / SKILL.md 에 implementation 워크플로우의 워커 명단이 따로 등재돼 있는지(현재 Role Definitions 표는 4종만 등재).
82
+ - okstra runtime이 `subagent_type` 미등록 시 어떻게 동작하는지(silent fallback vs 명시적 에러).
83
+
84
+ ---
85
+
86
+ ## 수정 B — Leader-side 워커 soft timeout 도입
87
+
88
+ ### 배경
89
+
90
+ okstra는 Phase 4에서 Claude / Codex / Gemini 워커 3종을 동시에 spawn한다. 현재 leader는:
91
+
92
+ - Agent 호출을 foreground(blocking)로 발사하므로 가장 느린 워커가 phase 전체를 잡아둔다.
93
+ - `terminal status: timeout` 카테고리는 [`okstra-team-contract` SKILL.md](skills/okstra-team-contract/SKILL.md) 에 정의돼 있지만, **누가 어떤 조건으로 timeout을 트리거하는지에 대한 룰이 없다**.
94
+ - 결과적으로 Claude worker의 ack가 늦으면 leader는 무한정 기다리고, convergence(Phase 5.5)가 지연된다.
95
+
96
+ 수정 A(Claude worker Stop Condition)는 워커 측 자율 종료를 강제하지만, 워커가 규칙을 따르지 않거나 in-process subagent runtime이 멈춘 경우의 안전장치는 여전히 없다. 수정 B는 그 안전장치를 leader 쪽에 추가한다.
97
+
98
+ ### 변경 대상 파일
99
+
100
+ - [SKILL.md](SKILL.md) Phase 4 섹션 (대략 380~410 라인 부근, "Phase 4: Preferred Agent Teams execution")
101
+ - [skills/okstra-team-contract/SKILL.md](skills/okstra-team-contract/SKILL.md) — terminal status 표 보강 (필요 시)
102
+
103
+ ### 추가할 룰 초안
104
+
105
+ Phase 4 실행 섹션에 아래 블록을 추가한다.
106
+
107
+ ```markdown
108
+ ### Per-worker soft timeout
109
+
110
+ Lead must establish an internal expected-duration window per worker based on
111
+ task type:
112
+
113
+ | Task type | Expected per-worker duration |
114
+ | ------------------------ | ----------------------------- |
115
+ | requirements-discovery | 10 minutes |
116
+ | error-analysis | 15 minutes |
117
+ | implementation-planning | 20 minutes |
118
+ | final-verification | 10 minutes |
119
+
120
+ If a worker has not returned within **2× the expected duration** AND the
121
+ worker-results file already exists on disk with a valid standardized header,
122
+ Lead MUST:
123
+
124
+ 1. Record terminal status `timeout` in team-state for that worker, with
125
+ `reason: "worker-overran-after-write"` and the wall-clock duration.
126
+ 2. Append a `cli-failure` (Codex/Gemini) or `tool-failure` (Claude worker)
127
+ event via `okstra-error-log.py append-observed`.
128
+ 3. Proceed with Phase 5.5 using the on-disk worker-results file as the
129
+ canonical worker output. Do NOT invent results — if the file does not exist
130
+ or fails header validation, record `not-run` instead of `timeout` and skip
131
+ that worker's contribution to convergence.
132
+
133
+ Lead does NOT have a runtime-level "cancel Agent call" capability. The Agent
134
+ call may continue to run in the background and eventually return; Lead simply
135
+ ignores the late return if a `timeout` status was already recorded.
136
+
137
+ If the worker-results file does NOT exist when the soft timeout fires, Lead
138
+ must wait for either the file to appear or the Agent call to return — do not
139
+ fabricate a `timeout` status against a missing artifact.
140
+ ```
141
+
142
+ ### 검증 체크리스트
143
+
144
+ 수정 B를 머지하기 전에 다음을 확인한다.
145
+
146
+ - [ ] `okstra-team-contract` 의 terminal status 표(`completed | timeout | error | not-run`)와 새 룰의 의미가 정확히 일치하는가
147
+ - [ ] `okstra-error-log.py append-observed` 의 `--error-type cli-failure` / `tool-failure` 파라미터가 새 룰에서 요구하는 형태와 일치하는가 (`scripts/okstra-error-log.py` 시그니처 점검)
148
+ - [ ] team-state JSON 스키마에 `reason`, `durationSeconds` 필드가 이미 존재하는가, 없다면 스키마 마이그레이션 필요
149
+ - [ ] Phase 5.5 (`okstra-convergence`) 가 일부 워커 결과 누락 상태에서도 정상 동작하는가 — 적어도 1개 워커 결과만으로는 convergence 진행을 거부해야 하는가, 아니면 partial 모드를 허용하는가 정책 결정
150
+ - [ ] 이 룰을 Phase 5 (sequential/background fallback)에도 동일하게 적용할지 결정
151
+
152
+ ### 의존 / 선행 작업
153
+
154
+ - 수정 A (Claude worker Stop Condition) 가 먼저 머지되어 일정 기간 사용 데이터를 수집해야, 위 표의 expected duration 값을 실측 기반으로 조정할 수 있다. 초안 값은 보수적으로 잡았으므로 1~2주 사용 후 조정 권장.
155
+
156
+ ### 참고 — 적용 범위 밖 (수정 C 후보)
157
+
158
+ 다음은 수정 B와 별개의 더 큰 설계 변경이며, 별도 브랜치에서 다룬다.
159
+
160
+ - Phase 4를 foreground multi-Agent에서 `run_in_background: true` + leader polling 방식으로 전환
161
+ - Lead 가 worker-results 파일 존재 + 헤더 검증으로 완료를 판단하는 폴링 루프 추가
162
+ - 진짜 cancellation (Agent 강제 종료) 가 가능해지면 그 시점에 통합
163
+
164
+ ---
165
+
166
+ ## 변경 이력
167
+
168
+ - 2026-05-03 — 작성. 수정 A(Claude worker Stop Condition) 동시 머지에 따른 후속 항목 기록.