okstra 0.102.2 → 0.102.3

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 (161) hide show
  1. package/README.kr.md +5 -5
  2. package/README.md +5 -5
  3. package/docs/kr/architecture/storage-model.md +1 -1
  4. package/docs/kr/architecture.md +7 -11
  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/okstra-antigravity-exec.sh +1 -2
  12. package/runtime/bin/okstra-codex-exec.sh +1 -2
  13. package/runtime/bin/okstra-render-final-report.py +2 -9
  14. package/runtime/bin/okstra-spawn-followups.py +4 -6
  15. package/runtime/bin/okstra-trace-cleanup.sh +24 -4
  16. package/runtime/prompts/lead/okstra-lead-contract.md +2 -2
  17. package/runtime/prompts/lead/report-writer.md +1 -1
  18. package/runtime/prompts/profiles/_common-contract.md +9 -11
  19. package/runtime/python/okstra_ctl/codex_dispatch.py +4 -12
  20. package/runtime/python/okstra_ctl/consumers.py +35 -0
  21. package/runtime/python/okstra_ctl/container.py +4 -6
  22. package/runtime/python/okstra_ctl/dispatch_core.py +4 -12
  23. package/runtime/python/okstra_ctl/final_report_paths.py +24 -0
  24. package/runtime/python/okstra_ctl/handoff.py +2 -1
  25. package/runtime/python/okstra_ctl/implementation_stage.py +7 -11
  26. package/runtime/python/okstra_ctl/report_view_artifacts.py +14 -0
  27. package/runtime/python/okstra_ctl/report_views.py +7 -4
  28. package/runtime/python/okstra_ctl/run.py +3 -10
  29. package/runtime/python/okstra_ctl/stage_targets.py +18 -0
  30. package/runtime/python/okstra_ctl/wizard.py +24 -25
  31. package/runtime/python/okstra_ctl/wizard_stage_intent.py +54 -0
  32. package/runtime/python/okstra_token_usage/report.py +2 -5
  33. package/runtime/validators/validate-report-views.py +2 -1
  34. package/runtime/validators/validate-run.py +1 -11
  35. package/src/commands/lifecycle/install.mjs +5 -5
  36. package/src/commands/lifecycle/uninstall.mjs +4 -4
  37. package/docs/superpowers/plans/2026-05-12-ticket-id-in-reports.md +0 -638
  38. package/docs/superpowers/plans/2026-05-14-convergence-queue-pruning.md +0 -1568
  39. package/docs/superpowers/plans/2026-05-17-dual-format-final-report.md +0 -167
  40. package/docs/superpowers/plans/2026-05-20-final-report-language.md +0 -1501
  41. package/docs/superpowers/plans/2026-05-20-implementation-planning-multi-stage.md +0 -1267
  42. package/docs/superpowers/plans/2026-05-20-okstra-run-prompt-sot-b1.md +0 -1007
  43. package/docs/superpowers/plans/2026-05-20-wizard-messages-json-sot.md +0 -720
  44. package/docs/superpowers/plans/2026-05-20-wizard-prompt-json-sot-a1.md +0 -681
  45. package/docs/superpowers/plans/2026-05-21-improvement-discovery-task-type.md +0 -1691
  46. package/docs/superpowers/plans/2026-05-24-implementation-lead-context-slimming.md +0 -1700
  47. package/docs/superpowers/plans/2026-05-25-okstra-project-root-rename.md +0 -158
  48. package/docs/superpowers/plans/2026-05-26-wizard-3-option-picker.md +0 -860
  49. package/docs/superpowers/plans/2026-06-02-final-verification-protocol-hardening.md +0 -326
  50. package/docs/superpowers/plans/2026-06-02-okstra-run-branch-confirm-step.md +0 -337
  51. package/docs/superpowers/plans/2026-06-02-okstra-run-phase-pane-cleanup.md +0 -410
  52. package/docs/superpowers/plans/2026-06-02-requirements-discovery-fanout.md +0 -728
  53. package/docs/superpowers/plans/2026-06-04-adversarial-implementation-planning.md +0 -294
  54. package/docs/superpowers/plans/2026-06-04-adversarial-verification.md +0 -570
  55. package/docs/superpowers/plans/2026-06-04-coverage-critic.md +0 -516
  56. package/docs/superpowers/plans/2026-06-04-stage-cohesion-planner.md +0 -351
  57. package/docs/superpowers/plans/2026-06-04-stage-run-batching.md +0 -457
  58. package/docs/superpowers/plans/2026-06-05-acceptance-critic.md +0 -251
  59. package/docs/superpowers/plans/2026-06-05-compact-markdown-report-tables.md +0 -323
  60. package/docs/superpowers/plans/2026-06-05-wizard-batch-prompts.md +0 -559
  61. package/docs/superpowers/plans/2026-06-06-final-verification-whole-task-gate.md +0 -993
  62. package/docs/superpowers/plans/2026-06-06-stage-parallel-and-pending-fixes.md +0 -93
  63. package/docs/superpowers/plans/2026-06-06-stage-worktree-isolation-p1.md +0 -447
  64. package/docs/superpowers/plans/2026-06-06-stage-worktree-isolation-p2.md +0 -289
  65. package/docs/superpowers/plans/2026-06-06-stage-worktree-isolation-p3.md +0 -774
  66. package/docs/superpowers/plans/2026-06-06-stage-worktree-isolation-p4.md +0 -303
  67. package/docs/superpowers/plans/2026-06-06-stage-worktree-isolation-p5-multidep-base.md +0 -387
  68. package/docs/superpowers/plans/2026-06-07-stage-conformance-qa-phase2.md +0 -275
  69. package/docs/superpowers/plans/2026-06-07-stage-conformance-qa-phase3.md +0 -282
  70. package/docs/superpowers/plans/2026-06-07-stage-conformance-qa-phase4a.md +0 -147
  71. package/docs/superpowers/plans/2026-06-07-stage-conformance-qa-phase4b.md +0 -262
  72. package/docs/superpowers/plans/2026-06-07-stage-conformance-qa-phase4c.md +0 -184
  73. package/docs/superpowers/plans/2026-06-07-stage-conformance-qa-phase4d.md +0 -88
  74. package/docs/superpowers/plans/2026-06-07-stage-conformance-qa-phase4e.md +0 -250
  75. package/docs/superpowers/plans/2026-06-07-stage-conformance-qa.md +0 -409
  76. package/docs/superpowers/plans/2026-06-09-implementation-run-artifact-stage-isolation.md +0 -320
  77. package/docs/superpowers/plans/2026-06-10-concurrent-run-team-guard.md +0 -456
  78. package/docs/superpowers/plans/2026-06-10-git-reconcile-stale-sha-recovery.md +0 -1408
  79. package/docs/superpowers/plans/2026-06-10-lead-worker-completion-polling-PROBE.md +0 -42
  80. package/docs/superpowers/plans/2026-06-10-lead-worker-completion-polling.md +0 -337
  81. package/docs/superpowers/plans/2026-06-10-p6-token-usage-incremental.md +0 -1029
  82. package/docs/superpowers/plans/2026-06-10-stage-group-handoff.md +0 -1572
  83. package/docs/superpowers/plans/2026-06-11-fix-cycle.md +0 -1290
  84. package/docs/superpowers/plans/2026-06-11-wizard-whole-task-final-verification.md +0 -526
  85. package/docs/superpowers/plans/2026-06-12-html-plan-approval.md +0 -1000
  86. package/docs/superpowers/plans/2026-06-13-repo-risk-hardening.md +0 -493
  87. package/docs/superpowers/plans/2026-06-14-host-runtime-auto-execution.md +0 -1775
  88. package/docs/superpowers/plans/2026-06-15-coding-preflight-pack-dispatch-path.md +0 -504
  89. package/docs/superpowers/plans/2026-06-15-internal-skill-migration-final-fixups.md +0 -342
  90. package/docs/superpowers/plans/2026-06-15-internal-skill-migration-fixups.md +0 -258
  91. package/docs/superpowers/plans/2026-06-15-internal-skill-migration-remaining-fixups.md +0 -387
  92. package/docs/superpowers/plans/2026-06-15-internal-skill-resource-migration.md +0 -749
  93. package/docs/superpowers/plans/2026-06-15-worker-prompt-anchor-final-fixups.md +0 -828
  94. package/docs/superpowers/plans/2026-06-15-worker-prompt-header-error-contract.md +0 -490
  95. package/docs/superpowers/plans/2026-06-17-okstra-error-report.md +0 -724
  96. package/docs/superpowers/plans/2026-06-18-subagent-pane-reclaim.md +0 -483
  97. package/docs/superpowers/plans/2026-06-19-agent-operating-standard.md +0 -476
  98. package/docs/superpowers/plans/2026-06-19-okstra-inspect-recap-facet.md +0 -647
  99. package/docs/superpowers/plans/2026-06-20-error-feedback-loop.md +0 -1019
  100. package/docs/superpowers/plans/2026-06-20-run-index-row-normalization.md +0 -583
  101. package/docs/superpowers/plans/2026-06-20-stage-auto-integrate-teardown.md +0 -819
  102. package/docs/superpowers/plans/2026-06-21-okstra-container-local-user-test.md +0 -714
  103. package/docs/superpowers/plans/2026-06-21-release-handoff-local-checkout.md +0 -348
  104. package/docs/superpowers/plans/2026-06-23-implementation-stage-multiselect-chain.md +0 -630
  105. package/docs/superpowers/plans/2026-06-23-implementation-step-commit-granularity.md +0 -274
  106. package/docs/superpowers/plans/2026-06-23-phase-batch-cleanup-enforcement.md +0 -409
  107. package/docs/superpowers/plans/2026-06-24-cross-project-precondition.md +0 -542
  108. package/docs/superpowers/plans/2026-06-24-decision-drafts-render-gap.md +0 -568
  109. package/docs/superpowers/plans/2026-06-24-manual-user-test-section.md +0 -203
  110. package/docs/superpowers/plans/2026-06-24-okstra-container-build-rename.md +0 -525
  111. package/docs/superpowers/specs/2026-05-12-ticket-id-in-reports-design.md +0 -131
  112. package/docs/superpowers/specs/2026-05-15-implementation-plan-verification-design.md +0 -254
  113. package/docs/superpowers/specs/2026-05-20-final-report-language-design.md +0 -383
  114. package/docs/superpowers/specs/2026-05-20-implementation-planning-multi-stage-design.md +0 -322
  115. package/docs/superpowers/specs/2026-05-20-okstra-run-prompt-sot-design.md +0 -299
  116. package/docs/superpowers/specs/2026-05-21-improvement-discovery-task-type-design.md +0 -335
  117. package/docs/superpowers/specs/2026-06-02-okstra-run-branch-confirm-step-design.md +0 -113
  118. package/docs/superpowers/specs/2026-06-02-okstra-run-phase-pane-cleanup-design.md +0 -173
  119. package/docs/superpowers/specs/2026-06-02-requirements-discovery-fanout-design.md +0 -154
  120. package/docs/superpowers/specs/2026-06-04-adversarial-implementation-planning-design.md +0 -90
  121. package/docs/superpowers/specs/2026-06-04-adversarial-verification-design.md +0 -176
  122. package/docs/superpowers/specs/2026-06-04-coverage-critic-design.md +0 -99
  123. package/docs/superpowers/specs/2026-06-04-stage-splitting-cost-aware-design.md +0 -98
  124. package/docs/superpowers/specs/2026-06-05-acceptance-critic-design.md +0 -90
  125. package/docs/superpowers/specs/2026-06-05-compact-markdown-report-tables-design.md +0 -87
  126. package/docs/superpowers/specs/2026-06-05-wizard-batch-prompts-design.md +0 -121
  127. package/docs/superpowers/specs/2026-06-06-final-verification-whole-task-gate-design.md +0 -126
  128. package/docs/superpowers/specs/2026-06-06-stage-worktree-isolation-design.md +0 -180
  129. package/docs/superpowers/specs/2026-06-06-vertical-slice-tdd-planning-design.md +0 -179
  130. package/docs/superpowers/specs/2026-06-07-stage-conformance-qa-design.md +0 -169
  131. package/docs/superpowers/specs/2026-06-09-executor-model-custom-id-cascade-design.md +0 -66
  132. package/docs/superpowers/specs/2026-06-09-implementation-run-artifact-stage-isolation-design.md +0 -87
  133. package/docs/superpowers/specs/2026-06-10-blocking-contract-posthoc-conformance-design.md +0 -168
  134. package/docs/superpowers/specs/2026-06-10-concurrent-run-team-guard-design.md +0 -107
  135. package/docs/superpowers/specs/2026-06-10-git-reconcile-stale-sha-recovery-design.md +0 -105
  136. package/docs/superpowers/specs/2026-06-10-lead-worker-completion-polling-design.md +0 -113
  137. package/docs/superpowers/specs/2026-06-10-stage-group-handoff-design.md +0 -156
  138. package/docs/superpowers/specs/2026-06-11-brief-entry-only-handoff-stage-entry-design.md +0 -158
  139. package/docs/superpowers/specs/2026-06-11-fix-cycle-design.md +0 -94
  140. package/docs/superpowers/specs/2026-06-11-wizard-whole-task-final-verification-design.md +0 -89
  141. package/docs/superpowers/specs/2026-06-12-codex-lead-adapter-design.md +0 -358
  142. package/docs/superpowers/specs/2026-06-12-html-plan-approval-design.md +0 -85
  143. package/docs/superpowers/specs/2026-06-12-stage-discipline-rule-design.md +0 -108
  144. package/docs/superpowers/specs/2026-06-13-forbidden-actions-ssot-design.md +0 -134
  145. package/docs/superpowers/specs/2026-06-13-neutral-tmux-lead-adapter-design.md +0 -284
  146. package/docs/superpowers/specs/2026-06-14-host-runtime-auto-execution-design.md +0 -404
  147. package/docs/superpowers/specs/2026-06-17-okstra-error-report-design.md +0 -123
  148. package/docs/superpowers/specs/2026-06-18-subagent-pane-reclaim-design.md +0 -150
  149. package/docs/superpowers/specs/2026-06-19-agent-operating-standard-design.md +0 -120
  150. package/docs/superpowers/specs/2026-06-19-okstra-inspect-recap-facet-design.md +0 -96
  151. package/docs/superpowers/specs/2026-06-20-error-feedback-loop-design.md +0 -171
  152. package/docs/superpowers/specs/2026-06-20-run-index-row-normalization-design.md +0 -112
  153. package/docs/superpowers/specs/2026-06-20-stage-auto-integrate-teardown-design.md +0 -145
  154. package/docs/superpowers/specs/2026-06-21-okstra-container-local-user-test-design.md +0 -125
  155. package/docs/superpowers/specs/2026-06-21-release-handoff-local-checkout-design.md +0 -113
  156. package/docs/superpowers/specs/2026-06-23-implementation-stage-multiselect-chain-design.md +0 -138
  157. package/docs/superpowers/specs/2026-06-23-implementation-step-commit-granularity-design.md +0 -120
  158. package/docs/superpowers/specs/2026-06-24-cross-project-precondition-design.md +0 -129
  159. package/docs/superpowers/specs/2026-06-24-decision-drafts-render-gap-design.md +0 -185
  160. package/docs/superpowers/specs/2026-06-24-manual-user-test-section-design.md +0 -121
  161. 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`.