okstra 0.102.2 → 0.102.4

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 (167) hide show
  1. package/README.kr.md +5 -5
  2. package/README.md +5 -5
  3. package/docs/kr/architecture/storage-model.md +8 -3
  4. package/docs/kr/architecture.md +12 -13
  5. package/docs/kr/cli.md +4 -4
  6. package/docs/kr/container.md +1 -1
  7. package/docs/kr/performance-improvement-plan-v2.md +2 -2
  8. package/docs/project-structure-overview.md +2 -2
  9. package/package.json +7 -2
  10. package/runtime/BUILD.json +2 -2
  11. package/runtime/bin/lib/okstra/interactive.sh +12 -0
  12. package/runtime/bin/okstra-antigravity-exec.sh +1 -2
  13. package/runtime/bin/okstra-codex-exec.sh +1 -2
  14. package/runtime/bin/okstra-render-final-report.py +2 -9
  15. package/runtime/bin/okstra-spawn-followups.py +4 -6
  16. package/runtime/bin/okstra-trace-cleanup.sh +24 -4
  17. package/runtime/prompts/lead/okstra-lead-contract.md +2 -2
  18. package/runtime/prompts/lead/report-writer.md +1 -1
  19. package/runtime/prompts/profiles/_common-contract.md +9 -11
  20. package/runtime/python/okstra_ctl/codex_dispatch.py +6 -13
  21. package/runtime/python/okstra_ctl/consumers.py +35 -0
  22. package/runtime/python/okstra_ctl/container.py +4 -6
  23. package/runtime/python/okstra_ctl/dispatch_core.py +8 -13
  24. package/runtime/python/okstra_ctl/final_report_paths.py +24 -0
  25. package/runtime/python/okstra_ctl/handoff.py +2 -1
  26. package/runtime/python/okstra_ctl/implementation_outcome.py +271 -0
  27. package/runtime/python/okstra_ctl/implementation_stage.py +7 -11
  28. package/runtime/python/okstra_ctl/path_hints.py +665 -0
  29. package/runtime/python/okstra_ctl/render.py +4 -3
  30. package/runtime/python/okstra_ctl/report_view_artifacts.py +14 -0
  31. package/runtime/python/okstra_ctl/report_views.py +7 -4
  32. package/runtime/python/okstra_ctl/run.py +3 -10
  33. package/runtime/python/okstra_ctl/run_context.py +4 -2
  34. package/runtime/python/okstra_ctl/stage_targets.py +18 -0
  35. package/runtime/python/okstra_ctl/wizard.py +37 -26
  36. package/runtime/python/okstra_ctl/wizard_stage_intent.py +54 -0
  37. package/runtime/python/okstra_project/state.py +40 -2
  38. package/runtime/python/okstra_token_usage/report.py +2 -5
  39. package/runtime/validators/validate-report-views.py +2 -1
  40. package/runtime/validators/validate-run.py +1 -11
  41. package/src/commands/lifecycle/install.mjs +5 -5
  42. package/src/commands/lifecycle/uninstall.mjs +4 -4
  43. package/docs/superpowers/plans/2026-05-12-ticket-id-in-reports.md +0 -638
  44. package/docs/superpowers/plans/2026-05-14-convergence-queue-pruning.md +0 -1568
  45. package/docs/superpowers/plans/2026-05-17-dual-format-final-report.md +0 -167
  46. package/docs/superpowers/plans/2026-05-20-final-report-language.md +0 -1501
  47. package/docs/superpowers/plans/2026-05-20-implementation-planning-multi-stage.md +0 -1267
  48. package/docs/superpowers/plans/2026-05-20-okstra-run-prompt-sot-b1.md +0 -1007
  49. package/docs/superpowers/plans/2026-05-20-wizard-messages-json-sot.md +0 -720
  50. package/docs/superpowers/plans/2026-05-20-wizard-prompt-json-sot-a1.md +0 -681
  51. package/docs/superpowers/plans/2026-05-21-improvement-discovery-task-type.md +0 -1691
  52. package/docs/superpowers/plans/2026-05-24-implementation-lead-context-slimming.md +0 -1700
  53. package/docs/superpowers/plans/2026-05-25-okstra-project-root-rename.md +0 -158
  54. package/docs/superpowers/plans/2026-05-26-wizard-3-option-picker.md +0 -860
  55. package/docs/superpowers/plans/2026-06-02-final-verification-protocol-hardening.md +0 -326
  56. package/docs/superpowers/plans/2026-06-02-okstra-run-branch-confirm-step.md +0 -337
  57. package/docs/superpowers/plans/2026-06-02-okstra-run-phase-pane-cleanup.md +0 -410
  58. package/docs/superpowers/plans/2026-06-02-requirements-discovery-fanout.md +0 -728
  59. package/docs/superpowers/plans/2026-06-04-adversarial-implementation-planning.md +0 -294
  60. package/docs/superpowers/plans/2026-06-04-adversarial-verification.md +0 -570
  61. package/docs/superpowers/plans/2026-06-04-coverage-critic.md +0 -516
  62. package/docs/superpowers/plans/2026-06-04-stage-cohesion-planner.md +0 -351
  63. package/docs/superpowers/plans/2026-06-04-stage-run-batching.md +0 -457
  64. package/docs/superpowers/plans/2026-06-05-acceptance-critic.md +0 -251
  65. package/docs/superpowers/plans/2026-06-05-compact-markdown-report-tables.md +0 -323
  66. package/docs/superpowers/plans/2026-06-05-wizard-batch-prompts.md +0 -559
  67. package/docs/superpowers/plans/2026-06-06-final-verification-whole-task-gate.md +0 -993
  68. package/docs/superpowers/plans/2026-06-06-stage-parallel-and-pending-fixes.md +0 -93
  69. package/docs/superpowers/plans/2026-06-06-stage-worktree-isolation-p1.md +0 -447
  70. package/docs/superpowers/plans/2026-06-06-stage-worktree-isolation-p2.md +0 -289
  71. package/docs/superpowers/plans/2026-06-06-stage-worktree-isolation-p3.md +0 -774
  72. package/docs/superpowers/plans/2026-06-06-stage-worktree-isolation-p4.md +0 -303
  73. package/docs/superpowers/plans/2026-06-06-stage-worktree-isolation-p5-multidep-base.md +0 -387
  74. package/docs/superpowers/plans/2026-06-07-stage-conformance-qa-phase2.md +0 -275
  75. package/docs/superpowers/plans/2026-06-07-stage-conformance-qa-phase3.md +0 -282
  76. package/docs/superpowers/plans/2026-06-07-stage-conformance-qa-phase4a.md +0 -147
  77. package/docs/superpowers/plans/2026-06-07-stage-conformance-qa-phase4b.md +0 -262
  78. package/docs/superpowers/plans/2026-06-07-stage-conformance-qa-phase4c.md +0 -184
  79. package/docs/superpowers/plans/2026-06-07-stage-conformance-qa-phase4d.md +0 -88
  80. package/docs/superpowers/plans/2026-06-07-stage-conformance-qa-phase4e.md +0 -250
  81. package/docs/superpowers/plans/2026-06-07-stage-conformance-qa.md +0 -409
  82. package/docs/superpowers/plans/2026-06-09-implementation-run-artifact-stage-isolation.md +0 -320
  83. package/docs/superpowers/plans/2026-06-10-concurrent-run-team-guard.md +0 -456
  84. package/docs/superpowers/plans/2026-06-10-git-reconcile-stale-sha-recovery.md +0 -1408
  85. package/docs/superpowers/plans/2026-06-10-lead-worker-completion-polling-PROBE.md +0 -42
  86. package/docs/superpowers/plans/2026-06-10-lead-worker-completion-polling.md +0 -337
  87. package/docs/superpowers/plans/2026-06-10-p6-token-usage-incremental.md +0 -1029
  88. package/docs/superpowers/plans/2026-06-10-stage-group-handoff.md +0 -1572
  89. package/docs/superpowers/plans/2026-06-11-fix-cycle.md +0 -1290
  90. package/docs/superpowers/plans/2026-06-11-wizard-whole-task-final-verification.md +0 -526
  91. package/docs/superpowers/plans/2026-06-12-html-plan-approval.md +0 -1000
  92. package/docs/superpowers/plans/2026-06-13-repo-risk-hardening.md +0 -493
  93. package/docs/superpowers/plans/2026-06-14-host-runtime-auto-execution.md +0 -1775
  94. package/docs/superpowers/plans/2026-06-15-coding-preflight-pack-dispatch-path.md +0 -504
  95. package/docs/superpowers/plans/2026-06-15-internal-skill-migration-final-fixups.md +0 -342
  96. package/docs/superpowers/plans/2026-06-15-internal-skill-migration-fixups.md +0 -258
  97. package/docs/superpowers/plans/2026-06-15-internal-skill-migration-remaining-fixups.md +0 -387
  98. package/docs/superpowers/plans/2026-06-15-internal-skill-resource-migration.md +0 -749
  99. package/docs/superpowers/plans/2026-06-15-worker-prompt-anchor-final-fixups.md +0 -828
  100. package/docs/superpowers/plans/2026-06-15-worker-prompt-header-error-contract.md +0 -490
  101. package/docs/superpowers/plans/2026-06-17-okstra-error-report.md +0 -724
  102. package/docs/superpowers/plans/2026-06-18-subagent-pane-reclaim.md +0 -483
  103. package/docs/superpowers/plans/2026-06-19-agent-operating-standard.md +0 -476
  104. package/docs/superpowers/plans/2026-06-19-okstra-inspect-recap-facet.md +0 -647
  105. package/docs/superpowers/plans/2026-06-20-error-feedback-loop.md +0 -1019
  106. package/docs/superpowers/plans/2026-06-20-run-index-row-normalization.md +0 -583
  107. package/docs/superpowers/plans/2026-06-20-stage-auto-integrate-teardown.md +0 -819
  108. package/docs/superpowers/plans/2026-06-21-okstra-container-local-user-test.md +0 -714
  109. package/docs/superpowers/plans/2026-06-21-release-handoff-local-checkout.md +0 -348
  110. package/docs/superpowers/plans/2026-06-23-implementation-stage-multiselect-chain.md +0 -630
  111. package/docs/superpowers/plans/2026-06-23-implementation-step-commit-granularity.md +0 -274
  112. package/docs/superpowers/plans/2026-06-23-phase-batch-cleanup-enforcement.md +0 -409
  113. package/docs/superpowers/plans/2026-06-24-cross-project-precondition.md +0 -542
  114. package/docs/superpowers/plans/2026-06-24-decision-drafts-render-gap.md +0 -568
  115. package/docs/superpowers/plans/2026-06-24-manual-user-test-section.md +0 -203
  116. package/docs/superpowers/plans/2026-06-24-okstra-container-build-rename.md +0 -525
  117. package/docs/superpowers/specs/2026-05-12-ticket-id-in-reports-design.md +0 -131
  118. package/docs/superpowers/specs/2026-05-15-implementation-plan-verification-design.md +0 -254
  119. package/docs/superpowers/specs/2026-05-20-final-report-language-design.md +0 -383
  120. package/docs/superpowers/specs/2026-05-20-implementation-planning-multi-stage-design.md +0 -322
  121. package/docs/superpowers/specs/2026-05-20-okstra-run-prompt-sot-design.md +0 -299
  122. package/docs/superpowers/specs/2026-05-21-improvement-discovery-task-type-design.md +0 -335
  123. package/docs/superpowers/specs/2026-06-02-okstra-run-branch-confirm-step-design.md +0 -113
  124. package/docs/superpowers/specs/2026-06-02-okstra-run-phase-pane-cleanup-design.md +0 -173
  125. package/docs/superpowers/specs/2026-06-02-requirements-discovery-fanout-design.md +0 -154
  126. package/docs/superpowers/specs/2026-06-04-adversarial-implementation-planning-design.md +0 -90
  127. package/docs/superpowers/specs/2026-06-04-adversarial-verification-design.md +0 -176
  128. package/docs/superpowers/specs/2026-06-04-coverage-critic-design.md +0 -99
  129. package/docs/superpowers/specs/2026-06-04-stage-splitting-cost-aware-design.md +0 -98
  130. package/docs/superpowers/specs/2026-06-05-acceptance-critic-design.md +0 -90
  131. package/docs/superpowers/specs/2026-06-05-compact-markdown-report-tables-design.md +0 -87
  132. package/docs/superpowers/specs/2026-06-05-wizard-batch-prompts-design.md +0 -121
  133. package/docs/superpowers/specs/2026-06-06-final-verification-whole-task-gate-design.md +0 -126
  134. package/docs/superpowers/specs/2026-06-06-stage-worktree-isolation-design.md +0 -180
  135. package/docs/superpowers/specs/2026-06-06-vertical-slice-tdd-planning-design.md +0 -179
  136. package/docs/superpowers/specs/2026-06-07-stage-conformance-qa-design.md +0 -169
  137. package/docs/superpowers/specs/2026-06-09-executor-model-custom-id-cascade-design.md +0 -66
  138. package/docs/superpowers/specs/2026-06-09-implementation-run-artifact-stage-isolation-design.md +0 -87
  139. package/docs/superpowers/specs/2026-06-10-blocking-contract-posthoc-conformance-design.md +0 -168
  140. package/docs/superpowers/specs/2026-06-10-concurrent-run-team-guard-design.md +0 -107
  141. package/docs/superpowers/specs/2026-06-10-git-reconcile-stale-sha-recovery-design.md +0 -105
  142. package/docs/superpowers/specs/2026-06-10-lead-worker-completion-polling-design.md +0 -113
  143. package/docs/superpowers/specs/2026-06-10-stage-group-handoff-design.md +0 -156
  144. package/docs/superpowers/specs/2026-06-11-brief-entry-only-handoff-stage-entry-design.md +0 -158
  145. package/docs/superpowers/specs/2026-06-11-fix-cycle-design.md +0 -94
  146. package/docs/superpowers/specs/2026-06-11-wizard-whole-task-final-verification-design.md +0 -89
  147. package/docs/superpowers/specs/2026-06-12-codex-lead-adapter-design.md +0 -358
  148. package/docs/superpowers/specs/2026-06-12-html-plan-approval-design.md +0 -85
  149. package/docs/superpowers/specs/2026-06-12-stage-discipline-rule-design.md +0 -108
  150. package/docs/superpowers/specs/2026-06-13-forbidden-actions-ssot-design.md +0 -134
  151. package/docs/superpowers/specs/2026-06-13-neutral-tmux-lead-adapter-design.md +0 -284
  152. package/docs/superpowers/specs/2026-06-14-host-runtime-auto-execution-design.md +0 -404
  153. package/docs/superpowers/specs/2026-06-17-okstra-error-report-design.md +0 -123
  154. package/docs/superpowers/specs/2026-06-18-subagent-pane-reclaim-design.md +0 -150
  155. package/docs/superpowers/specs/2026-06-19-agent-operating-standard-design.md +0 -120
  156. package/docs/superpowers/specs/2026-06-19-okstra-inspect-recap-facet-design.md +0 -96
  157. package/docs/superpowers/specs/2026-06-20-error-feedback-loop-design.md +0 -171
  158. package/docs/superpowers/specs/2026-06-20-run-index-row-normalization-design.md +0 -112
  159. package/docs/superpowers/specs/2026-06-20-stage-auto-integrate-teardown-design.md +0 -145
  160. package/docs/superpowers/specs/2026-06-21-okstra-container-local-user-test-design.md +0 -125
  161. package/docs/superpowers/specs/2026-06-21-release-handoff-local-checkout-design.md +0 -113
  162. package/docs/superpowers/specs/2026-06-23-implementation-stage-multiselect-chain-design.md +0 -138
  163. package/docs/superpowers/specs/2026-06-23-implementation-step-commit-granularity-design.md +0 -120
  164. package/docs/superpowers/specs/2026-06-24-cross-project-precondition-design.md +0 -129
  165. package/docs/superpowers/specs/2026-06-24-decision-drafts-render-gap-design.md +0 -185
  166. package/docs/superpowers/specs/2026-06-24-manual-user-test-section-design.md +0 -121
  167. package/docs/superpowers/specs/2026-06-24-okstra-container-build-rename-design.md +0 -110
@@ -1,749 +0,0 @@
1
- # Internal Skill Resource Migration Implementation Plan
2
-
3
- > **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
4
-
5
- **Goal:** Only user-facing Okstra skills are installed into agent skill homes; former internal skills become Okstra runtime resources under the project/runtime tree.
6
-
7
- **Architecture:** `skills/` becomes the public skill surface and contains only the six user-facing skill directories already listed by `.claude-plugin/plugin.json`. Lead-only operating contracts move to shipped runtime prompt resources (`prompts/lead/`), and generated launch prompts load them by explicit file paths. Coding preflight moves as a routed resource pack (`prompts/coding-preflight/`): the router checks language, framework, then architecture stages; each stage iterates a list of rules and selects every matching resource. The installer copies only public skills and prunes package-owned internal skill directories from prior installs.
8
-
9
- **Tech Stack:** Node.js ES modules for install/uninstall/runtime tests, Python `okstra_ctl` renderer and pytest contract tests, markdown prompt resources, existing `npm run build` runtime sync.
10
-
11
- ---
12
-
13
- ## Grounding
14
-
15
- Current facts to preserve or change:
16
-
17
- - Public plugin skill list is six skills: `okstra-setup`, `okstra-brief`, `okstra-run`, `okstra-memory`, `okstra-inspect`, `okstra-schedule` (`.claude-plugin/plugin.json`).
18
- - Current installer copies every directory under `runtime/skills` and then copies `runtime/agents/SKILL.md` as the extra `okstra` skill.
19
- - Current lead contract (`agents/SKILL.md`) references internal skill files by skill paths and tells the lead to invoke them.
20
- - Current Claude launch prompt says `Invoke the okstra skill now`; Codex launch prompt explicitly says not to invoke Claude Code skills.
21
- - `tools/build.mjs` already ships `prompts/`, `agents/`, `templates/`, and `skills/` into `runtime/`, so prompt resources under `prompts/` are installable without adding a new build channel.
22
-
23
- ## Target File Structure
24
-
25
- ### Public user skills retained under `skills/`
26
-
27
- - `skills/okstra-setup/`
28
- - `skills/okstra-brief/`
29
- - `skills/okstra-run/`
30
- - `skills/okstra-memory/`
31
- - `skills/okstra-inspect/`
32
- - `skills/okstra-schedule/`
33
-
34
- ### Internal resources moved out of `skills/`
35
-
36
- - `agents/SKILL.md` -> `prompts/lead/okstra-lead-contract.md`
37
- - `skills/okstra-context-loader/SKILL.md` -> `prompts/lead/context-loader.md`
38
- - `skills/okstra-team-contract/SKILL.md` -> `prompts/lead/team-contract.md`
39
- - `skills/okstra-convergence/SKILL.md` -> `prompts/lead/convergence.md`
40
- - `skills/okstra-report-writer/SKILL.md` -> `prompts/lead/report-writer.md`
41
- - `skills/okstra-coding-preflight/SKILL.md` -> `prompts/coding-preflight/overview.md`
42
- - `skills/okstra-coding-preflight/clean-code.md` -> `prompts/coding-preflight/clean-code.md`
43
- - `skills/okstra-coding-preflight/languages/*` -> `prompts/coding-preflight/languages/*`
44
- - `skills/okstra-coding-preflight/languages/nodejs.md` -> `prompts/coding-preflight/frameworks/node-server.md`
45
- - `skills/okstra-coding-preflight/architecture/*` -> `prompts/coding-preflight/architectures/*`
46
-
47
- Delete the old internal directories after references are migrated:
48
-
49
- - `agents/SKILL.md`
50
- - `skills/okstra-context-loader/`
51
- - `skills/okstra-team-contract/`
52
- - `skills/okstra-convergence/`
53
- - `skills/okstra-report-writer/`
54
- - `skills/okstra-coding-preflight/`
55
-
56
-
57
- `prompts/coding-preflight/` is a routed resource pack, not a single always-read contract. Default selection is `overview.md` + `clean-code.md`, then three ordered stages. Each stage is a list of rules; a rule has one or more conditions; if any condition matches, include that rule's resource. The router never stops at the first match inside a stage because one diff can touch multiple languages/frameworks/architectures.
58
-
59
- 1. **Language stage** — iterate all language rules:
60
- - `languages/javascript-typescript.md` when any touched file is `.js`, `.jsx`, `.ts`, `.tsx`, `.mjs`, `.cjs`, or a JS package manifest implies JS/TS work.
61
- - `languages/python.md` when any touched file is `.py` or manifests include `pyproject.toml`, `requirements.txt`, `setup.py`, or `setup.cfg`.
62
- - `languages/rust.md` when any touched file is `.rs` or `Cargo.toml` exists in scope.
63
- - `languages/java.md` when any touched file is `.java` or manifests include `pom.xml` / `build.gradle`.
64
- - `languages/kotlin.md` when any touched file is `.kt` / `.kts` or manifests include `build.gradle.kts`.
65
- - `languages/sql.md` when any touched file is `.sql`, migration paths are touched, `prisma/schema.prisma` is touched, or embedded query strings / ORM query builders are changed.
66
- 2. **Framework stage** — iterate all framework/runtime rules:
67
- - `frameworks/node-server.md` when `package.json` or dependencies/scripts show server-side Node work (`express`, `fastify`, `nestjs`, server entrypoints, API routes, CLI services), or when touched files are Node runtime modules.
68
- 3. **Architecture stage** — iterate all architecture rules:
69
- - `architectures/hexagonal.md` when the project has ports-and-adapters / hexagonal signals (`domain/` + `ports/` + `adapters/`, `core/` + `infrastructure/` + `application/`, `*.port.*`, NestJS hex split, domain-boundary abstract classes).
70
-
71
- Unknown or unlisted language with no matching reference: stop before editing and ask the user for the canonical style guide; do not invent a default. No launch prompt should inline or require reading every preflight file.
72
-
73
- ## Task 1: Add a Public Skill Catalog
74
-
75
- **Files:**
76
- - Create: `src/skill-catalog.mjs`
77
- - Modify: `src/install.mjs`
78
- - Test: `tests-js/skill-catalog.test.mjs`
79
-
80
- - [ ] **Step 1: Add the catalog module**
81
-
82
- Create `src/skill-catalog.mjs`:
83
-
84
- ```js
85
- export const USER_SKILL_NAMES = Object.freeze([
86
- "okstra-setup",
87
- "okstra-brief",
88
- "okstra-run",
89
- "okstra-memory",
90
- "okstra-inspect",
91
- "okstra-schedule",
92
- ]);
93
-
94
- export const OBSOLETE_INTERNAL_SKILL_NAMES = Object.freeze([
95
- "okstra",
96
- "okstra-context-loader",
97
- "okstra-team-contract",
98
- "okstra-convergence",
99
- "okstra-report-writer",
100
- "okstra-coding-preflight",
101
- ]);
102
-
103
- export function userSkillNames() {
104
- return [...USER_SKILL_NAMES];
105
- }
106
-
107
- export function obsoleteInternalSkillNames() {
108
- return [...OBSOLETE_INTERNAL_SKILL_NAMES];
109
- }
110
- ```
111
-
112
- - [ ] **Step 2: Write catalog/plugin sync test**
113
-
114
- Create `tests-js/skill-catalog.test.mjs`:
115
-
116
- ```js
117
- import assert from "node:assert/strict";
118
- import { readFileSync } from "node:fs";
119
- import test from "node:test";
120
- import { USER_SKILL_NAMES, OBSOLETE_INTERNAL_SKILL_NAMES } from "../src/skill-catalog.mjs";
121
-
122
- function readJson(path) {
123
- return JSON.parse(readFileSync(path, "utf8"));
124
- }
125
-
126
- test("public skill catalog matches Claude plugin manifest", () => {
127
- const plugin = readJson(".claude-plugin/plugin.json");
128
- const pluginNames = plugin.skills.map((entry) => entry.replace("./skills/", ""));
129
- assert.deepEqual(pluginNames, USER_SKILL_NAMES);
130
- });
131
-
132
- test("obsolete internal skill names do not overlap public skills", () => {
133
- for (const name of OBSOLETE_INTERNAL_SKILL_NAMES) {
134
- assert.equal(USER_SKILL_NAMES.includes(name), false, name);
135
- }
136
- });
137
- ```
138
-
139
- - [ ] **Step 3: Run the new test and verify it passes before install changes**
140
-
141
- Run:
142
-
143
- ```bash
144
- node --test tests-js/skill-catalog.test.mjs
145
- ```
146
-
147
- Expected: both subtests pass.
148
-
149
- - [ ] **Step 4: Import the catalog in `src/install.mjs`**
150
-
151
- At the top of `src/install.mjs`, import the catalog:
152
-
153
- ```js
154
- import { OBSOLETE_INTERNAL_SKILL_NAMES, USER_SKILL_NAMES } from "./skill-catalog.mjs";
155
- ```
156
-
157
- Keep the existing import ordering style: built-in imports first, local imports after them.
158
-
159
- ## Task 2: Install Only Public Skills and Prune Old Internal Skill Installs
160
-
161
- **Files:**
162
- - Modify: `src/install.mjs`
163
- - Modify: `tests-js/install-runtime.test.mjs`
164
- - Modify: `tests-js/uninstall-runtime.test.mjs`
165
-
166
- - [ ] **Step 1: Replace `listSkillDirs()` usage for install with the catalog**
167
-
168
- In `installSkillsCopy(runtimeRoot, target, opts)`, stop using every directory under `runtime/skills`. Use `USER_SKILL_NAMES` as the exact install list.
169
-
170
- Implementation shape:
171
-
172
- ```js
173
- async function installSkillsCopy(runtimeRoot, target, opts) {
174
- const { refresh, dryRun, quiet } = opts;
175
- const srcRoot = join(runtimeRoot, "skills");
176
- const names = USER_SKILL_NAMES;
177
- let copied = 0;
178
- let skipped = 0;
179
- for (const name of names) {
180
- const r = await copyTreeIfChanged(join(srcRoot, name), join(target.skillsDir, name), {
181
- refresh,
182
- dryRun,
183
- mode: 0o644,
184
- });
185
- copied += r.copied;
186
- skipped += r.skipped;
187
- }
188
- const pruned = await pruneObsoleteInternalSkills(target, opts);
189
- if (!quiet) {
190
- process.stdout.write(
191
- ` ${target.provider} skills: copied=${copied} skipped=${skipped} pruned=${pruned} -> ${target.skillsDir}/ (${names.length} skills)\n`,
192
- );
193
- }
194
- return { ...target, installed: [...names] };
195
- }
196
- ```
197
-
198
- - [ ] **Step 2: Apply the same public-list behavior to link mode**
199
-
200
- In `installSkillsLink(repoAbs, target, opts)`, use `USER_SKILL_NAMES`, remove the lead-skill link call, and call the same prune helper.
201
-
202
- Implementation shape:
203
-
204
- ```js
205
- async function installSkillsLink(repoAbs, target, opts) {
206
- const { dryRun, quiet } = opts;
207
- const srcRoot = join(repoAbs, "skills");
208
- const names = USER_SKILL_NAMES;
209
- if (!dryRun) await fs.mkdir(target.skillsDir, { recursive: true });
210
- for (const name of names) {
211
- const src = join(srcRoot, name);
212
- const dst = join(target.skillsDir, name);
213
- const action = await ensureSymlink(src, dst, { dryRun });
214
- if (!quiet) process.stdout.write(` ${target.provider} skills/${name}: ${action}\n`);
215
- }
216
- const pruned = await pruneObsoleteInternalSkills(target, opts);
217
- if (!quiet && pruned > 0) {
218
- process.stdout.write(` ${target.provider} obsolete internal skills: pruned=${pruned}\n`);
219
- }
220
- return { ...target, installed: [...names] };
221
- }
222
- ```
223
-
224
- - [ ] **Step 3: Add the prune helper**
225
-
226
- Add near the skill install helpers:
227
-
228
- ```js
229
- async function pruneObsoleteInternalSkills(target, opts) {
230
- let pruned = 0;
231
- for (const name of OBSOLETE_INTERNAL_SKILL_NAMES) {
232
- const path = join(target.skillsDir, name);
233
- if (!(await pathExists(path))) continue;
234
- pruned += 1;
235
- if (!opts.dryRun) {
236
- await fs.rm(path, { recursive: true, force: true });
237
- }
238
- }
239
- return pruned;
240
- }
241
- ```
242
-
243
- This deliberately prunes only Okstra-owned exact names; no wildcard deletion.
244
-
245
- - [ ] **Step 4: Delete the lead skill install functions**
246
-
247
- Remove these obsolete pieces from `src/install.mjs`:
248
-
249
- ```js
250
- const LEAD_SKILL_NAME = "okstra";
251
- async function installLeadSkillCopy(...) { ... }
252
- async function installLeadSkillLink(...) { ... }
253
- ```
254
-
255
- No compatibility shim. The generated launch prompt will load the lead contract from `prompts/lead/` instead.
256
-
257
- - [ ] **Step 5: Update install tests to assert only public skills are installed**
258
-
259
- In `tests-js/install-runtime.test.mjs`, replace assertions that expect `okstra-team-contract` and `okstra` under provider skill homes.
260
-
261
- Expected assertion shape:
262
-
263
- ```js
264
- for (const providerRoot of [join(root, ".claude", "skills"), join(root, ".agent", "skills")]) {
265
- assert.equal(existsSync(join(providerRoot, "okstra-run", "SKILL.md")), true);
266
- assert.equal(existsSync(join(providerRoot, "okstra-setup", "SKILL.md")), true);
267
- assert.equal(existsSync(join(providerRoot, "okstra-team-contract", "SKILL.md")), false);
268
- assert.equal(existsSync(join(providerRoot, "okstra", "SKILL.md")), false);
269
- }
270
- ```
271
-
272
- Manifest assertions must compare against `USER_SKILL_NAMES`, not internal names.
273
-
274
- - [ ] **Step 6: Add stale-install prune coverage**
275
-
276
- Add a test to `tests-js/install-runtime.test.mjs`:
277
-
278
- ```js
279
- test("install prunes obsolete internal skill directories from prior installs", () => {
280
- const { root, env } = makeInstallEnv();
281
- const claudeSkills = join(root, ".claude", "skills");
282
- mkdirSync(join(claudeSkills, "okstra-team-contract"), { recursive: true });
283
- writeFileSync(join(claudeSkills, "okstra-team-contract", "SKILL.md"), "old\n");
284
- mkdirSync(join(claudeSkills, "okstra"), { recursive: true });
285
- writeFileSync(join(claudeSkills, "okstra", "SKILL.md"), "old\n");
286
-
287
- const install = runCli(["install"], { ...env, OKSTRA_RUNTIME_HOST: "external" });
288
- assert.equal(install.code, 0, install.stderr);
289
-
290
- assert.equal(existsSync(join(claudeSkills, "okstra-run", "SKILL.md")), true);
291
- assert.equal(existsSync(join(claudeSkills, "okstra-team-contract")), false);
292
- assert.equal(existsSync(join(claudeSkills, "okstra")), false);
293
- });
294
- ```
295
-
296
- - [ ] **Step 7: Remove legacy fallback skill target test**
297
-
298
- Remove the obsolete fallback-target test; supported skill homes are Claude and Agent only.
299
-
300
- - [ ] **Step 8: Run targeted install/uninstall tests**
301
-
302
- Run:
303
-
304
- ```bash
305
- node --test tests-js/skill-catalog.test.mjs tests-js/install-runtime.test.mjs tests-js/uninstall-runtime.test.mjs
306
- ```
307
-
308
- Expected: all listed JS tests pass.
309
-
310
- ## Task 3: Move Internal Markdown Contracts to Runtime Prompt Resources
311
-
312
- **Files:**
313
- - Create: `prompts/lead/okstra-lead-contract.md`
314
- - Create: `prompts/lead/context-loader.md`
315
- - Create: `prompts/lead/team-contract.md`
316
- - Create: `prompts/lead/convergence.md`
317
- - Create: `prompts/lead/report-writer.md`
318
- - Create: `prompts/coding-preflight/overview.md`
319
- - Move: `skills/okstra-coding-preflight/clean-code.md` -> `prompts/coding-preflight/clean-code.md`
320
- - Move: `skills/okstra-coding-preflight/languages/*` -> `prompts/coding-preflight/languages/*`
321
- - Move: `skills/okstra-coding-preflight/languages/nodejs.md` -> `prompts/coding-preflight/frameworks/node-server.md`
322
- - Move: `skills/okstra-coding-preflight/architecture/*` -> `prompts/coding-preflight/architectures/*`
323
- - Delete: `agents/SKILL.md`
324
- - Delete: old internal skill directories under `skills/`
325
-
326
- - [ ] **Step 1: Move lead contract content**
327
-
328
- Copy the body of `agents/SKILL.md` into `prompts/lead/okstra-lead-contract.md`, removing only skill frontmatter:
329
-
330
- ```markdown
331
- # Okstra Lead Contract
332
-
333
- ## Overview
334
- ...
335
- ```
336
-
337
- Replace wording that says `SKILL.md`, `sub-skill`, or `Invoke skill` with file-resource language:
338
-
339
- ```markdown
340
- ## Support contract index
341
-
342
- | Contract | Scope |
343
- |---|---|
344
- | [context-loader](./context-loader.md) | Phase 1 task-bundle discovery, manifest fields, run-directory layout |
345
- | [team-contract](./team-contract.md) | Phase 2–5 worker roster, model assignment rules, prompt composition, worker output contract, terminal statuses, usage tracking |
346
- | [convergence](./convergence.md) | Phase 5.5 finding convergence loop and implementation-planning plan-body verification mode |
347
- | [report-writer](./report-writer.md) | Phase 6 final-report authorship, dispatch template, resume-safe dispatch, shared-graph integrity check, Phase 7 token-usage collector |
348
- ```
349
-
350
- - [ ] **Step 2: Move internal skill bodies into lead contracts**
351
-
352
- For each source `SKILL.md`, remove the frontmatter block and write the remaining body to the matching target:
353
-
354
- ```text
355
- skills/okstra-context-loader/SKILL.md -> prompts/lead/context-loader.md
356
- skills/okstra-team-contract/SKILL.md -> prompts/lead/team-contract.md
357
- skills/okstra-convergence/SKILL.md -> prompts/lead/convergence.md
358
- skills/okstra-report-writer/SKILL.md -> prompts/lead/report-writer.md
359
- skills/okstra-coding-preflight/SKILL.md -> prompts/coding-preflight/overview.md
360
- ```
361
-
362
- Use title names that are resources, not skills:
363
-
364
- ```markdown
365
- # Okstra Context Loader Contract
366
- # Okstra Team Contract
367
- # Okstra Convergence Contract
368
- # Okstra Report Writer Contract
369
- # Okstra Coding Preflight
370
- ```
371
-
372
- - [ ] **Step 3: Move coding preflight resource files**
373
-
374
- Preserve the router semantics from `skills/okstra-coding-preflight/SKILL.md`: moving the files changes their namespace only, not when they are read. `overview.md` must define three ordered stages — language, framework, architecture. Each stage contains a list of rules; each rule can have multiple conditions; matching is list-iteration with accumulation, not first-match branching. Executors read only resources selected by touched files, project manifests, dependencies/scripts, and detected architecture.
375
-
376
- Move these files without content changes first:
377
-
378
- ```text
379
- skills/okstra-coding-preflight/clean-code.md -> prompts/coding-preflight/clean-code.md
380
- skills/okstra-coding-preflight/languages/python.md -> prompts/coding-preflight/languages/python.md
381
- skills/okstra-coding-preflight/languages/rust.md -> prompts/coding-preflight/languages/rust.md
382
- skills/okstra-coding-preflight/languages/sql.md -> prompts/coding-preflight/languages/sql.md
383
- skills/okstra-coding-preflight/languages/java.md -> prompts/coding-preflight/languages/java.md
384
- skills/okstra-coding-preflight/languages/javascript-typescript.md -> prompts/coding-preflight/languages/javascript-typescript.md
385
- skills/okstra-coding-preflight/languages/kotlin.md -> prompts/coding-preflight/languages/kotlin.md
386
- skills/okstra-coding-preflight/languages/nodejs.md -> prompts/coding-preflight/frameworks/node-server.md
387
- skills/okstra-coding-preflight/architecture/hexagonal.md -> prompts/coding-preflight/architectures/hexagonal.md
388
- ```
389
-
390
- - [ ] **Step 4: Rewrite internal links inside moved files**
391
-
392
- Replace old skill-relative links:
393
-
394
- ```text
395
- ../okstra-team-contract/SKILL.md -> ./team-contract.md
396
- ../okstra-convergence/SKILL.md -> ./convergence.md
397
- ../okstra-report-writer/SKILL.md -> ./report-writer.md
398
- ../okstra-context-loader/SKILL.md -> ./context-loader.md
399
- ```
400
-
401
- Replace prose references like `okstra-team-contract skill` with `team-contract resource` or `prompts/lead/team-contract.md`, whichever is clearer in context.
402
-
403
- - [ ] **Step 5: Delete old internal skill sources**
404
-
405
- Delete only these exact paths:
406
-
407
- ```text
408
- agents/SKILL.md
409
- skills/okstra-context-loader/
410
- skills/okstra-team-contract/
411
- skills/okstra-convergence/
412
- skills/okstra-report-writer/
413
- skills/okstra-coding-preflight/
414
- ```
415
-
416
- Do not delete the six public skill directories.
417
-
418
- ## Task 4: Make Generated Lead Prompts Load Internal Resources by Path
419
-
420
- **Files:**
421
- - Modify: `scripts/okstra_ctl/render.py`
422
- - Modify: `prompts/launch.template.md`
423
- - Modify: `prompts/profiles/_coding-conventions-preflight.md`
424
- - Modify: `agents/workers/claude-worker.md`
425
- - Modify: `agents/workers/_cli-wrapper-template.md`
426
- - Modify: `agents/workers/report-writer-worker.md`
427
- - Modify: `scripts/lib/okstra/globals.sh`
428
- - Modify: `scripts/okstra_ctl/context_cost.py`
429
- - Modify: `scripts/okstra_token_usage/claude.py`
430
- - Modify: `scripts/okstra_token_usage/collect.py`
431
-
432
- - [ ] **Step 1: Add runtime resource path helpers in `render.py`**
433
-
434
- Add helper functions near the existing lead-runtime helpers:
435
-
436
- ```python
437
- def _runtime_resource_root() -> Path:
438
- okstra_home = os.environ.get("OKSTRA_HOME", "").strip()
439
- if okstra_home:
440
- return Path(okstra_home)
441
- return Path.home() / ".okstra"
442
-
443
-
444
- def _runtime_resource_path(*parts: str) -> str:
445
- return str(_runtime_resource_root().joinpath(*parts))
446
- ```
447
-
448
- - [ ] **Step 2: Generate explicit lead resource paths**
449
-
450
- Inside the launch prompt rendering context, compute these paths:
451
-
452
- ```python
453
- lead_contract_path = _runtime_resource_path("prompts", "lead", "okstra-lead-contract.md")
454
- context_loader_path = _runtime_resource_path("prompts", "lead", "context-loader.md")
455
- team_contract_path = _runtime_resource_path("prompts", "lead", "team-contract.md")
456
- convergence_path = _runtime_resource_path("prompts", "lead", "convergence.md")
457
- report_writer_path = _runtime_resource_path("prompts", "lead", "report-writer.md")
458
- coding_preflight_root = _runtime_resource_path("prompts", "coding-preflight")
459
- ```
460
-
461
- - [ ] **Step 3: Replace Claude skill bootstrap**
462
-
463
- Replace the Claude branch text currently shaped like `Invoke the okstra skill now` with file loading:
464
-
465
- ```python
466
- lead_bootstrap_instruction = (
467
- f"Read the Okstra lead contract at `{lead_contract_path}` now. "
468
- "Then read the manifests below for all task metadata, paths, model "
469
- "assignments, and worker roster. Follow the contract's lazy-read rules "
470
- "for support resources; do not invoke hidden/internal skills."
471
- )
472
- ```
473
-
474
- For Codex and external runtime branches, add the same path as a resource, without mentioning Claude skills.
475
-
476
- - [ ] **Step 4: Add a compact resource block to the generated prompt**
477
-
478
- Add a block after the session block:
479
-
480
- ```markdown
481
- ## Okstra Runtime Resources
482
-
483
- - Lead contract: `<lead_contract_path>`
484
- - Context loader: `<context_loader_path>`
485
- - Team contract: `<team_contract_path>`
486
- - Convergence contract: `<convergence_path>`
487
- - Report writer contract: `<report_writer_path>`
488
- - Coding preflight root: `<coding_preflight_root>`
489
- ```
490
-
491
- This gives every lead runtime the same path-based contract surface.
492
-
493
- - [ ] **Step 5: Update `prompts/launch.template.md` references**
494
-
495
- Replace `agents/SKILL.md` and `okstra skill` references with the new contract names.
496
-
497
- Expected wording:
498
-
499
- ```markdown
500
- Emit one `PROGRESS: <phase-id> <verb-phrase>` line as plain user-facing text at every checkpoint enumerated in the lead contract (`prompts/lead/okstra-lead-contract.md` → "Progress reporting (BLOCKING)").
501
- ```
502
-
503
- ```markdown
504
- See `Lifecycle Phase Boundaries` in the lead contract (`prompts/lead/okstra-lead-contract.md`) for the canonical rules and the phase-transition checklist.
505
- ```
506
-
507
- - [ ] **Step 6: Update coding preflight path references**
508
-
509
- In `prompts/profiles/_coding-conventions-preflight.md`, replace the old Claude skill path with installed runtime resource paths:
510
-
511
- ```markdown
512
- Detect applicable coding-conventions resources with three ordered stages: language, framework, architecture. Always read `overview.md` and `clean-code.md` first. For each stage, iterate every rule in the stage's list; each rule may have multiple conditions, and a rule matches when any condition is true. Accumulate every matched resource; do not stop at the first match. Language examples: JS/TS files or JS package manifests -> `languages/javascript-typescript.md`; Python files/manifests -> `languages/python.md`; Rust files/manifests -> `languages/rust.md`; Java/Kotlin/SQL triggers -> matching language files. Framework examples: server-side Node evidence (`express`, `fastify`, `nestjs`, API routes, CLI services, Node runtime modules) -> `frameworks/node-server.md`. Architecture examples: ports-and-adapters / NestJS-hex signals -> `architectures/hexagonal.md`. If no listed language matches, stop before editing and ask for the canonical style guide.
513
- ```
514
-
515
- Also update the graceful-degradation line to say `resource-unavailable`, not `skill-unavailable`.
516
-
517
- - [ ] **Step 7: Update worker docs and scripts that cite old skill paths**
518
-
519
- Use exact replacements:
520
-
521
- ```text
522
- skills/okstra-team-contract/SKILL.md -> prompts/lead/team-contract.md
523
- okstra-team-contract skill -> team-contract resource
524
- okstra-convergence skill -> convergence resource
525
- okstra-report-writer skill -> report-writer resource
526
- agents/SKILL.md -> prompts/lead/okstra-lead-contract.md
527
- ```
528
-
529
- Apply these in worker agent files, wrapper templates, token usage comments, and context-cost hot path names.
530
-
531
- - [ ] **Step 8: Remove obsolete globals entry**
532
-
533
- In `scripts/lib/okstra/globals.sh`, remove or rename `SOURCE_CLAUDE_OKSTRA_SKILL`. If no runtime code reads it, delete it. If a shell path still needs the lead contract, replace it with:
534
-
535
- ```bash
536
- SOURCE_OKSTRA_LEAD_CONTRACT="$WORKSPACE_ROOT/prompts/lead/okstra-lead-contract.md"
537
- ```
538
-
539
- ## Task 5: Update Contract Tests and Docs
540
-
541
- **Files:**
542
- - Modify: `tests/test_docs_runtime_contract.py`
543
- - Modify: `tests/test_lead_runtime_marker.py`
544
- - Modify: `tests-js/doctor-runtime.test.mjs` if expected install assets mention hidden skills
545
- - Modify: `docs/kr/architecture.md`
546
- - Modify: `docs/kr/cli.md`
547
- - Modify: `docs/project-structure-overview.md`
548
- - Modify: `README.md`
549
- - Modify: `README.kr.md`
550
- - Modify: `CHANGES.md`
551
-
552
- - [ ] **Step 1: Replace internal-skill frontmatter test**
553
-
554
- In `tests/test_docs_runtime_contract.py`, remove assertions that internal resources contain `user-invocable: false`. Replace them with a resource-location assertion:
555
-
556
- ```python
557
- def test_internal_okstra_contracts_are_runtime_resources_not_skills():
558
- for relative_path in [
559
- "prompts/lead/okstra-lead-contract.md",
560
- "prompts/lead/context-loader.md",
561
- "prompts/lead/team-contract.md",
562
- "prompts/lead/convergence.md",
563
- "prompts/lead/report-writer.md",
564
- "prompts/coding-preflight/overview.md",
565
- ]:
566
- text = _read_doc(relative_path)
567
- assert "user-invocable:" not in text, relative_path
568
- assert "hide:" not in text, relative_path
569
-
570
- for relative_path in [
571
- "skills/okstra-context-loader/SKILL.md",
572
- "skills/okstra-team-contract/SKILL.md",
573
- "skills/okstra-convergence/SKILL.md",
574
- "skills/okstra-report-writer/SKILL.md",
575
- "skills/okstra-coding-preflight/SKILL.md",
576
- "agents/SKILL.md",
577
- ]:
578
- assert not (ROOT / relative_path).exists(), relative_path
579
- ```
580
-
581
- - [ ] **Step 2: Add generated-prompt guard test**
582
-
583
- Update the lead runtime marker tests so generated Claude prompts contain the lead contract path and do not contain `Invoke the okstra skill now`.
584
-
585
- Expected assertions:
586
-
587
- ```python
588
- assert "prompts/lead/okstra-lead-contract.md" in prompt_text
589
- assert "Invoke the `okstra` skill now" not in prompt_text
590
- assert "do not invoke hidden/internal skills" in prompt_text
591
- ```
592
-
593
- - [ ] **Step 3: Update JS install expectations**
594
-
595
- Where JS tests inspect runtime manifests, assert:
596
-
597
- ```js
598
- assert.deepEqual(target.skills, USER_SKILL_NAMES);
599
- assert.equal(manifest.installedAssets.claudeSkills, true);
600
- assert.equal(manifest.installedAssets.claudeAgents, true);
601
- ```
602
-
603
- `claudeSkills` remains true when public skills install; it no longer implies internal lead resources were installed as skills.
604
-
605
- - [ ] **Step 4: Update architecture docs**
606
-
607
- In `docs/kr/architecture.md`, document the new boundary:
608
-
609
- ```markdown
610
- - 사용자 호출 가능 스킬: `skills/okstra-{setup,brief,run,memory,inspect,schedule}` 만 agent skill home 으로 복사된다.
611
- - Lead/internal 운영 계약: `prompts/lead/*.md` 와 `prompts/coding-preflight/*` 로 설치되며, generated launch prompt 가 절대 경로를 제공한다. 이 파일들은 skill discovery 대상이 아니다.
612
- - 과거 `okstra-context-loader`, `okstra-team-contract`, `okstra-convergence`, `okstra-report-writer`, `okstra-coding-preflight`, `okstra` skill 디렉터리는 install 시 exact-name prune 대상이다.
613
- ```
614
-
615
- - [ ] **Step 5: Update CLI docs and READMEs**
616
-
617
- Change install behavior docs:
618
-
619
- ```markdown
620
- `okstra install` copies only user-facing Okstra skills to detected agent homes. Internal lead contracts are installed under `~/.okstra/prompts/` and loaded by generated prompts; they do not appear in the agent skill list.
621
- ```
622
-
623
- - [ ] **Step 6: Add `CHANGES.md` entry**
624
-
625
- Add a new dated entry:
626
-
627
- ```markdown
628
- ## 2026-06-15
629
-
630
- - `okstra install` now exposes only user-facing Okstra skills in agent skill lists. Lead-only contracts moved into the Okstra runtime resource tree and old internal skill directories are pruned on reinstall.
631
- - 사용자 영향: `/skills` / skill discovery views no longer show `okstra-team-contract`, `okstra-convergence`, `okstra-report-writer`, `okstra-context-loader`, `okstra-coding-preflight`, or hidden `okstra`; existing Okstra runs still load the same contracts through generated prompt paths.
632
- ```
633
-
634
- ## Task 6: Consistency Search and Runtime Build Verification
635
-
636
- **Files:**
637
- - Generated: `runtime/` via `npm run build`
638
-
639
- - [ ] **Step 1: Search for old internal skill paths**
640
-
641
- Run repository searches for these strings and update every live reference outside historical changelog entries and this plan:
642
-
643
- ```text
644
- skills/okstra-context-loader
645
- skills/okstra-team-contract
646
- skills/okstra-convergence
647
- skills/okstra-report-writer
648
- skills/okstra-coding-preflight
649
- agents/SKILL.md
650
- Invoke the `okstra` skill now
651
- okstra-team-contract skill
652
- okstra-convergence skill
653
- okstra-report-writer skill
654
- ```
655
-
656
- Expected: no live runtime, prompt, test, or docs reference requires the old skill namespace.
657
-
658
- - [ ] **Step 2: Build runtime**
659
-
660
- Run:
661
-
662
- ```bash
663
- npm run build
664
- ```
665
-
666
- Expected: `runtime/prompts/lead/*.md`, `runtime/prompts/coding-preflight/*`, and only the six public `runtime/skills/okstra-*` skill directories are present.
667
-
668
- - [ ] **Step 3: Verify no internal skills in runtime skills tree**
669
-
670
- Use a Node assertion script instead of shell globbing:
671
-
672
- ```bash
673
- node - <<'NODE'
674
- import assert from 'node:assert/strict';
675
- import { readdirSync, existsSync } from 'node:fs';
676
- import { join } from 'node:path';
677
- import { USER_SKILL_NAMES, OBSOLETE_INTERNAL_SKILL_NAMES } from './src/skill-catalog.mjs';
678
- const names = readdirSync('runtime/skills', { withFileTypes: true })
679
- .filter((entry) => entry.isDirectory())
680
- .map((entry) => entry.name)
681
- .sort();
682
- assert.deepEqual(names, [...USER_SKILL_NAMES].sort());
683
- for (const name of OBSOLETE_INTERNAL_SKILL_NAMES) {
684
- assert.equal(existsSync(join('runtime/skills', name)), false, name);
685
- }
686
- assert.equal(existsSync('runtime/prompts/lead/okstra-lead-contract.md'), true);
687
- assert.equal(existsSync('runtime/prompts/coding-preflight/clean-code.md'), true);
688
- NODE
689
- ```
690
-
691
- Expected: exit code 0.
692
-
693
- ## Task 7: End-to-End Install Smoke Tests
694
-
695
- **Files:**
696
- - No source changes expected after Task 6.
697
-
698
- - [ ] **Step 1: Run targeted automated suites**
699
-
700
- Run:
701
-
702
- ```bash
703
- node --test tests-js/skill-catalog.test.mjs tests-js/install-runtime.test.mjs tests-js/uninstall-runtime.test.mjs tests-js/doctor-runtime.test.mjs
704
- python3 -m pytest tests/test_docs_runtime_contract.py tests/test_lead_runtime_marker.py
705
- bash validators/validate-workflow.sh
706
- ```
707
-
708
- Expected: all commands pass.
709
-
710
- - [ ] **Step 2: Smoke-test install into a fake Claude home**
711
-
712
- Run:
713
-
714
- ```bash
715
- TMP_HOME=$(mktemp -d)
716
- mkdir -p "$TMP_HOME/.claude"
717
- HOME="$TMP_HOME" OKSTRA_HOME="$TMP_HOME/.okstra" OKSTRA_RUNTIME_HOST=external node bin/okstra install
718
- node - <<'NODE' "$TMP_HOME"
719
- import assert from 'node:assert/strict';
720
- import { existsSync } from 'node:fs';
721
- import { join } from 'node:path';
722
- import { USER_SKILL_NAMES, OBSOLETE_INTERNAL_SKILL_NAMES } from './src/skill-catalog.mjs';
723
- const home = process.argv[2];
724
- for (const name of USER_SKILL_NAMES) {
725
- assert.equal(existsSync(join(home, '.claude', 'skills', name, 'SKILL.md')), true, name);
726
- }
727
- for (const name of OBSOLETE_INTERNAL_SKILL_NAMES) {
728
- assert.equal(existsSync(join(home, '.claude', 'skills', name)), false, name);
729
- }
730
- assert.equal(existsSync(join(home, '.okstra', 'prompts', 'lead', 'okstra-lead-contract.md')), true);
731
- assert.equal(existsSync(join(home, '.okstra', 'prompts', 'coding-preflight', 'clean-code.md')), true);
732
- NODE
733
- ```
734
-
735
- Expected: install exits 0; Node assertions exit 0.
736
-
737
- - [ ] **Step 3: Run full check**
738
-
739
- Run:
740
-
741
- ```bash
742
- npm run check
743
- ```
744
-
745
- Expected: build, JS tests, Python tests, and workflow validator pass.
746
-
747
- ## Rollback Plan
748
-
749
- If generated lead prompts cannot reliably read `~/.okstra/prompts/lead/okstra-lead-contract.md`, revert only the render/bootstrap change and keep the moved resources staged. Do not reintroduce hidden skills as the default install surface. The fallback must be explicit prompt inlining from `prompts/lead/okstra-lead-contract.md`, not copying internal files back to `~/.claude/skills`.