okstra 0.102.1 → 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.
- package/README.kr.md +5 -6
- package/README.md +5 -6
- package/docs/kr/architecture/storage-model.md +1 -1
- package/docs/kr/architecture.md +8 -12
- package/docs/kr/cli.md +6 -6
- package/docs/kr/container.md +1 -1
- package/docs/kr/performance-improvement-plan-v2.md +2 -2
- package/docs/project-structure-overview.md +2 -2
- package/package.json +7 -2
- package/runtime/BUILD.json +2 -2
- package/runtime/bin/okstra-antigravity-exec.sh +1 -2
- package/runtime/bin/okstra-codex-exec.sh +1 -2
- package/runtime/bin/okstra-render-final-report.py +2 -9
- package/runtime/bin/okstra-spawn-followups.py +4 -6
- package/runtime/bin/okstra-trace-cleanup.sh +24 -4
- package/runtime/prompts/lead/okstra-lead-contract.md +2 -2
- package/runtime/prompts/lead/report-writer.md +1 -1
- package/runtime/prompts/profiles/_common-contract.md +9 -11
- package/runtime/python/okstra_ctl/codex_dispatch.py +4 -12
- package/runtime/python/okstra_ctl/consumers.py +35 -0
- package/runtime/python/okstra_ctl/container.py +4 -6
- package/runtime/python/okstra_ctl/dispatch_core.py +4 -12
- package/runtime/python/okstra_ctl/final_report_paths.py +24 -0
- package/runtime/python/okstra_ctl/handoff.py +2 -1
- package/runtime/python/okstra_ctl/implementation_stage.py +7 -11
- package/runtime/python/okstra_ctl/report_view_artifacts.py +14 -0
- package/runtime/python/okstra_ctl/report_views.py +7 -4
- package/runtime/python/okstra_ctl/run.py +3 -10
- package/runtime/python/okstra_ctl/stage_targets.py +18 -0
- package/runtime/python/okstra_ctl/wizard.py +24 -25
- package/runtime/python/okstra_ctl/wizard_stage_intent.py +54 -0
- package/runtime/python/okstra_token_usage/report.py +2 -5
- package/runtime/validators/validate-report-views.py +2 -1
- package/runtime/validators/validate-run.py +1 -11
- package/src/cli-registry.mjs +1 -1
- package/src/commands/lifecycle/install.mjs +10 -20
- package/src/commands/lifecycle/uninstall.mjs +7 -10
- package/docs/superpowers/plans/2026-05-12-ticket-id-in-reports.md +0 -638
- package/docs/superpowers/plans/2026-05-14-convergence-queue-pruning.md +0 -1568
- package/docs/superpowers/plans/2026-05-17-dual-format-final-report.md +0 -167
- package/docs/superpowers/plans/2026-05-20-final-report-language.md +0 -1501
- package/docs/superpowers/plans/2026-05-20-implementation-planning-multi-stage.md +0 -1267
- package/docs/superpowers/plans/2026-05-20-okstra-run-prompt-sot-b1.md +0 -1007
- package/docs/superpowers/plans/2026-05-20-wizard-messages-json-sot.md +0 -720
- package/docs/superpowers/plans/2026-05-20-wizard-prompt-json-sot-a1.md +0 -681
- package/docs/superpowers/plans/2026-05-21-improvement-discovery-task-type.md +0 -1691
- package/docs/superpowers/plans/2026-05-24-implementation-lead-context-slimming.md +0 -1700
- package/docs/superpowers/plans/2026-05-25-okstra-project-root-rename.md +0 -158
- package/docs/superpowers/plans/2026-05-26-wizard-3-option-picker.md +0 -860
- package/docs/superpowers/plans/2026-06-02-final-verification-protocol-hardening.md +0 -326
- package/docs/superpowers/plans/2026-06-02-okstra-run-branch-confirm-step.md +0 -337
- package/docs/superpowers/plans/2026-06-02-okstra-run-phase-pane-cleanup.md +0 -410
- package/docs/superpowers/plans/2026-06-02-requirements-discovery-fanout.md +0 -728
- package/docs/superpowers/plans/2026-06-04-adversarial-implementation-planning.md +0 -294
- package/docs/superpowers/plans/2026-06-04-adversarial-verification.md +0 -570
- package/docs/superpowers/plans/2026-06-04-coverage-critic.md +0 -516
- package/docs/superpowers/plans/2026-06-04-stage-cohesion-planner.md +0 -351
- package/docs/superpowers/plans/2026-06-04-stage-run-batching.md +0 -457
- package/docs/superpowers/plans/2026-06-05-acceptance-critic.md +0 -251
- package/docs/superpowers/plans/2026-06-05-compact-markdown-report-tables.md +0 -323
- package/docs/superpowers/plans/2026-06-05-wizard-batch-prompts.md +0 -559
- package/docs/superpowers/plans/2026-06-06-final-verification-whole-task-gate.md +0 -993
- package/docs/superpowers/plans/2026-06-06-stage-parallel-and-pending-fixes.md +0 -93
- package/docs/superpowers/plans/2026-06-06-stage-worktree-isolation-p1.md +0 -447
- package/docs/superpowers/plans/2026-06-06-stage-worktree-isolation-p2.md +0 -289
- package/docs/superpowers/plans/2026-06-06-stage-worktree-isolation-p3.md +0 -774
- package/docs/superpowers/plans/2026-06-06-stage-worktree-isolation-p4.md +0 -303
- package/docs/superpowers/plans/2026-06-06-stage-worktree-isolation-p5-multidep-base.md +0 -387
- package/docs/superpowers/plans/2026-06-07-stage-conformance-qa-phase2.md +0 -275
- package/docs/superpowers/plans/2026-06-07-stage-conformance-qa-phase3.md +0 -282
- package/docs/superpowers/plans/2026-06-07-stage-conformance-qa-phase4a.md +0 -147
- package/docs/superpowers/plans/2026-06-07-stage-conformance-qa-phase4b.md +0 -262
- package/docs/superpowers/plans/2026-06-07-stage-conformance-qa-phase4c.md +0 -184
- package/docs/superpowers/plans/2026-06-07-stage-conformance-qa-phase4d.md +0 -88
- package/docs/superpowers/plans/2026-06-07-stage-conformance-qa-phase4e.md +0 -250
- package/docs/superpowers/plans/2026-06-07-stage-conformance-qa.md +0 -409
- package/docs/superpowers/plans/2026-06-09-implementation-run-artifact-stage-isolation.md +0 -320
- package/docs/superpowers/plans/2026-06-10-concurrent-run-team-guard.md +0 -456
- package/docs/superpowers/plans/2026-06-10-git-reconcile-stale-sha-recovery.md +0 -1408
- package/docs/superpowers/plans/2026-06-10-lead-worker-completion-polling-PROBE.md +0 -42
- package/docs/superpowers/plans/2026-06-10-lead-worker-completion-polling.md +0 -337
- package/docs/superpowers/plans/2026-06-10-p6-token-usage-incremental.md +0 -1029
- package/docs/superpowers/plans/2026-06-10-stage-group-handoff.md +0 -1572
- package/docs/superpowers/plans/2026-06-11-fix-cycle.md +0 -1290
- package/docs/superpowers/plans/2026-06-11-wizard-whole-task-final-verification.md +0 -526
- package/docs/superpowers/plans/2026-06-12-html-plan-approval.md +0 -1000
- package/docs/superpowers/plans/2026-06-13-repo-risk-hardening.md +0 -493
- package/docs/superpowers/plans/2026-06-14-host-runtime-auto-execution.md +0 -1775
- package/docs/superpowers/plans/2026-06-15-coding-preflight-pack-dispatch-path.md +0 -504
- package/docs/superpowers/plans/2026-06-15-internal-skill-migration-final-fixups.md +0 -342
- package/docs/superpowers/plans/2026-06-15-internal-skill-migration-fixups.md +0 -258
- package/docs/superpowers/plans/2026-06-15-internal-skill-migration-remaining-fixups.md +0 -387
- package/docs/superpowers/plans/2026-06-15-internal-skill-resource-migration.md +0 -749
- package/docs/superpowers/plans/2026-06-15-worker-prompt-anchor-final-fixups.md +0 -828
- package/docs/superpowers/plans/2026-06-15-worker-prompt-header-error-contract.md +0 -490
- package/docs/superpowers/plans/2026-06-17-okstra-error-report.md +0 -724
- package/docs/superpowers/plans/2026-06-18-subagent-pane-reclaim.md +0 -483
- package/docs/superpowers/plans/2026-06-19-agent-operating-standard.md +0 -476
- package/docs/superpowers/plans/2026-06-19-okstra-inspect-recap-facet.md +0 -647
- package/docs/superpowers/plans/2026-06-20-error-feedback-loop.md +0 -1019
- package/docs/superpowers/plans/2026-06-20-run-index-row-normalization.md +0 -583
- package/docs/superpowers/plans/2026-06-20-stage-auto-integrate-teardown.md +0 -819
- package/docs/superpowers/plans/2026-06-21-okstra-container-local-user-test.md +0 -714
- package/docs/superpowers/plans/2026-06-21-release-handoff-local-checkout.md +0 -348
- package/docs/superpowers/plans/2026-06-23-implementation-stage-multiselect-chain.md +0 -630
- package/docs/superpowers/plans/2026-06-23-implementation-step-commit-granularity.md +0 -274
- package/docs/superpowers/plans/2026-06-23-phase-batch-cleanup-enforcement.md +0 -409
- package/docs/superpowers/plans/2026-06-24-cross-project-precondition.md +0 -542
- package/docs/superpowers/plans/2026-06-24-decision-drafts-render-gap.md +0 -568
- package/docs/superpowers/plans/2026-06-24-manual-user-test-section.md +0 -203
- package/docs/superpowers/plans/2026-06-24-okstra-container-build-rename.md +0 -525
- package/docs/superpowers/specs/2026-05-12-ticket-id-in-reports-design.md +0 -131
- package/docs/superpowers/specs/2026-05-15-implementation-plan-verification-design.md +0 -254
- package/docs/superpowers/specs/2026-05-20-final-report-language-design.md +0 -383
- package/docs/superpowers/specs/2026-05-20-implementation-planning-multi-stage-design.md +0 -322
- package/docs/superpowers/specs/2026-05-20-okstra-run-prompt-sot-design.md +0 -299
- package/docs/superpowers/specs/2026-05-21-improvement-discovery-task-type-design.md +0 -335
- package/docs/superpowers/specs/2026-06-02-okstra-run-branch-confirm-step-design.md +0 -113
- package/docs/superpowers/specs/2026-06-02-okstra-run-phase-pane-cleanup-design.md +0 -173
- package/docs/superpowers/specs/2026-06-02-requirements-discovery-fanout-design.md +0 -154
- package/docs/superpowers/specs/2026-06-04-adversarial-implementation-planning-design.md +0 -90
- package/docs/superpowers/specs/2026-06-04-adversarial-verification-design.md +0 -176
- package/docs/superpowers/specs/2026-06-04-coverage-critic-design.md +0 -99
- package/docs/superpowers/specs/2026-06-04-stage-splitting-cost-aware-design.md +0 -98
- package/docs/superpowers/specs/2026-06-05-acceptance-critic-design.md +0 -90
- package/docs/superpowers/specs/2026-06-05-compact-markdown-report-tables-design.md +0 -87
- package/docs/superpowers/specs/2026-06-05-wizard-batch-prompts-design.md +0 -121
- package/docs/superpowers/specs/2026-06-06-final-verification-whole-task-gate-design.md +0 -126
- package/docs/superpowers/specs/2026-06-06-stage-worktree-isolation-design.md +0 -180
- package/docs/superpowers/specs/2026-06-06-vertical-slice-tdd-planning-design.md +0 -179
- package/docs/superpowers/specs/2026-06-07-stage-conformance-qa-design.md +0 -169
- package/docs/superpowers/specs/2026-06-09-executor-model-custom-id-cascade-design.md +0 -66
- package/docs/superpowers/specs/2026-06-09-implementation-run-artifact-stage-isolation-design.md +0 -87
- package/docs/superpowers/specs/2026-06-10-blocking-contract-posthoc-conformance-design.md +0 -168
- package/docs/superpowers/specs/2026-06-10-concurrent-run-team-guard-design.md +0 -107
- package/docs/superpowers/specs/2026-06-10-git-reconcile-stale-sha-recovery-design.md +0 -105
- package/docs/superpowers/specs/2026-06-10-lead-worker-completion-polling-design.md +0 -113
- package/docs/superpowers/specs/2026-06-10-stage-group-handoff-design.md +0 -156
- package/docs/superpowers/specs/2026-06-11-brief-entry-only-handoff-stage-entry-design.md +0 -158
- package/docs/superpowers/specs/2026-06-11-fix-cycle-design.md +0 -94
- package/docs/superpowers/specs/2026-06-11-wizard-whole-task-final-verification-design.md +0 -89
- package/docs/superpowers/specs/2026-06-12-codex-lead-adapter-design.md +0 -358
- package/docs/superpowers/specs/2026-06-12-html-plan-approval-design.md +0 -85
- package/docs/superpowers/specs/2026-06-12-stage-discipline-rule-design.md +0 -108
- package/docs/superpowers/specs/2026-06-13-forbidden-actions-ssot-design.md +0 -134
- package/docs/superpowers/specs/2026-06-13-neutral-tmux-lead-adapter-design.md +0 -284
- package/docs/superpowers/specs/2026-06-14-host-runtime-auto-execution-design.md +0 -404
- package/docs/superpowers/specs/2026-06-17-okstra-error-report-design.md +0 -123
- package/docs/superpowers/specs/2026-06-18-subagent-pane-reclaim-design.md +0 -150
- package/docs/superpowers/specs/2026-06-19-agent-operating-standard-design.md +0 -120
- package/docs/superpowers/specs/2026-06-19-okstra-inspect-recap-facet-design.md +0 -96
- package/docs/superpowers/specs/2026-06-20-error-feedback-loop-design.md +0 -171
- package/docs/superpowers/specs/2026-06-20-run-index-row-normalization-design.md +0 -112
- package/docs/superpowers/specs/2026-06-20-stage-auto-integrate-teardown-design.md +0 -145
- package/docs/superpowers/specs/2026-06-21-okstra-container-local-user-test-design.md +0 -125
- package/docs/superpowers/specs/2026-06-21-release-handoff-local-checkout-design.md +0 -113
- package/docs/superpowers/specs/2026-06-23-implementation-stage-multiselect-chain-design.md +0 -138
- package/docs/superpowers/specs/2026-06-23-implementation-step-commit-granularity-design.md +0 -120
- package/docs/superpowers/specs/2026-06-24-cross-project-precondition-design.md +0 -129
- package/docs/superpowers/specs/2026-06-24-decision-drafts-render-gap-design.md +0 -185
- package/docs/superpowers/specs/2026-06-24-manual-user-test-section-design.md +0 -121
- 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: Update OMP fallback test**
|
|
297
|
-
|
|
298
|
-
Change the OMP test to assert `okstra-run` exists and `okstra-team-contract` does not exist.
|
|
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`.
|