Initial Commit
This commit is contained in:
158
.claude/skills/enterprise-package-migration/SKILL.md
Normal file
158
.claude/skills/enterprise-package-migration/SKILL.md
Normal file
@@ -0,0 +1,158 @@
|
||||
---
|
||||
name: enterprise-package-migration
|
||||
description: Use when migrating a package from `../suaveplan/` into the genesis monorepo, or when adding a new genesis-original package. Mandates reading `../suaveplan/enterprise/<pkg>.md` first, authoring `**Verified by:**` lines at draft time, completing the 4-gate triple before declaring done. Triggers on path patterns like `packages/<plugin>/<pkg>` for new packages, or when the user mentions migration from main, bringing across, or porting from `suaveplan`.
|
||||
---
|
||||
|
||||
# Enterprise Package Migration
|
||||
|
||||
This skill enforces the workflow that prevents the 17 retroactive-ticking incidents that occurred during the first migration wave. Read it end-to-end before doing anything.
|
||||
|
||||
## When this applies
|
||||
|
||||
You are in this skill if:
|
||||
|
||||
1. The user is creating a new package under `packages/<plugin>/<pkg>/` in `/mnt/s/web/genesis`.
|
||||
2. The user mentions migrating, porting, or bringing across a package from `../suaveplan/`.
|
||||
3. You are authoring an `openspec/changes/<id>/` for a package that has an `enterprise/<pkg>.md` source.
|
||||
|
||||
If none of those apply, this skill does not apply — exit.
|
||||
|
||||
## The non-negotiable workflow
|
||||
|
||||
### Step 0 — Read the source
|
||||
|
||||
If `../suaveplan/enterprise/<pkg>.md` exists, **read it end-to-end before opening any other file**. It is the canonical requirements source. Do not author a genesis spec from memory of what the package does — you will lose requirements that way. The 17 retroactive-ticking incidents all traced to specs written from memory rather than from a side-by-side mapping with this file.
|
||||
|
||||
### Step 1 — Read the workflow rules
|
||||
|
||||
In this order:
|
||||
|
||||
1. `/mnt/s/web/genesis/CLAUDE.md` — full read.
|
||||
2. `/mnt/s/web/genesis/openspec/AGENTS.md` — every section, especially 13 (spec-conformance audit) and 14 (source mapping for migrations).
|
||||
3. `/mnt/s/web/genesis/openspec/templates/README.md` — when and how to use the templates.
|
||||
|
||||
### Step 2 — Author the change folder from templates
|
||||
|
||||
```bash
|
||||
cp -r /mnt/s/web/genesis/openspec/templates/proposal.md /mnt/s/web/genesis/openspec/changes/<change-id>/proposal.md
|
||||
cp -r /mnt/s/web/genesis/openspec/templates/tasks.md /mnt/s/web/genesis/openspec/changes/<change-id>/tasks.md
|
||||
mkdir -p /mnt/s/web/genesis/openspec/changes/<change-id>/specs/<cap>/
|
||||
cp -r /mnt/s/web/genesis/openspec/templates/spec-delta.md /mnt/s/web/genesis/openspec/changes/<change-id>/specs/<cap>/spec.md
|
||||
```
|
||||
|
||||
Do not author from scratch. Every template field exists to prevent a specific failure mode.
|
||||
|
||||
### Step 3 — Fill `## Source mapping` in proposal.md
|
||||
|
||||
Every requirement in the spec delta MUST cite a line range in `../suaveplan/enterprise/<pkg>.md`. Format:
|
||||
|
||||
```markdown
|
||||
| Requirement | Source lines | Notes |
|
||||
|---|---|---|
|
||||
| Zero workspace deps | L12-L34 | verbatim |
|
||||
| OTel adapter | L140-L155 | verbatim |
|
||||
```
|
||||
|
||||
Requirements with no source line go in the second table with a justification:
|
||||
|
||||
```markdown
|
||||
| Requirement | Justification |
|
||||
|---|---|
|
||||
| 100% coverage threshold | Genesis-wide policy, not package-specific |
|
||||
```
|
||||
|
||||
"Forgot to map" is not a justification.
|
||||
|
||||
### Step 4 — Fill `**Verified by:**` lines in spec-delta.md
|
||||
|
||||
Every requirement gets a line listing the concrete `it(...)` titles that pin every scenario:
|
||||
|
||||
```markdown
|
||||
**Verified by:** `src/feature/feature.test.ts::"<exact title>"` AND `src/feature/feature.spec-conformance.test.ts::"<exact title>"`
|
||||
```
|
||||
|
||||
This is mandatory at authoring time, not after the gates pass. If you don't know what to put, write the test name first, then write the test. Don't ship the spec without the line filled in.
|
||||
|
||||
### Step 5 — Implement, test, document
|
||||
|
||||
Standard CLAUDE.md rules apply:
|
||||
|
||||
- Five files per feature module (`feature.ts`, `feature.test.ts`, `feature.types.ts`, `feature.md`, `index.ts`).
|
||||
- 100% test coverage from day one (`provider: 'istanbul'`, never v8).
|
||||
- Sibling `.md` for every implementation file (≥200 words, basic + advanced examples, full API reference).
|
||||
- `{ timeout: 5000 }` on every `it()`/`test()`.
|
||||
- NEVER use mocks — use injectable `Clock`/`Rng`/`Logger`/etc from `@suaveplan/types`.
|
||||
- Check the `@suaveplan/error` consumers rule: every package extends `SuaveplanError` EXCEPT the three testing packages.
|
||||
|
||||
### Step 6 — Pass all 5 gates
|
||||
|
||||
Run in order. Stop on the first red:
|
||||
|
||||
```bash
|
||||
cd /mnt/s/web/genesis
|
||||
bun run check # gate 1 — Biome 0/0/0 across monorepo
|
||||
bunx turbo lint typecheck test --filter=@suaveplan/<pkg> # gate 2
|
||||
bunx turbo test:coverage --filter=@suaveplan/<pkg> # gate 3 — 100/100/100/100
|
||||
bun scripts/openspec-conformance.ts @suaveplan/<pkg> # gate 4 — 0 errors
|
||||
bunx turbo build --filter=@suaveplan/<pkg> # gate 5
|
||||
```
|
||||
|
||||
Never add a `biome-ignore` directive on faith. Workflow:
|
||||
|
||||
1. Run `bun run check` to see what Biome actually flags.
|
||||
2. Copy the exact rule path from Biome's output (e.g. `lint/suspicious/noExplicitAny`). Guessing produces parse errors — `lint/suspicious/noThrowLiterals` does not exist in Biome 2.x.
|
||||
3. Add the suppression, re-run `bun run check`, confirm it's now used.
|
||||
4. If you remove the underlying flag later, also remove the suppression — unused suppressions are errors.
|
||||
|
||||
If gate 3 reports drift, FIX IT INLINE. Do not punt to a follow-up change. The acceptable patterns:
|
||||
|
||||
- Implementation drifts from spec → align impl to spec, OR align spec to impl if the impl is the intended design.
|
||||
- Error code registered but unused → wire it into a real production code path.
|
||||
- OTel instrument declared but not emitted → wire it into the production hot path; assert with a real in-memory `MeterProvider`, not `vi.mock`.
|
||||
- Public type returns `: unknown` instead of a generic → thread `<T = unknown>` through the public surface.
|
||||
|
||||
### Step 7 — Pre-archive 8-row checklist
|
||||
|
||||
Before folding the spec delta:
|
||||
|
||||
| # | Check |
|
||||
|---|---|
|
||||
| 1 | Generics threaded; `expectTypeOf` assertions on every literal-type claim |
|
||||
| 2 | Zod schemas wired at every declared boundary |
|
||||
| 3 | Every error code in `error-codes.ts` thrown by ≥1 production code path |
|
||||
| 4 | Strict-mode behaviors tested both on and off |
|
||||
| 5 | OTel instruments emitted from production paths and asserted with real `MeterProvider` |
|
||||
| 6 | Lifecycle dedup tested where claimed (in-flight Promise, idempotent set/load) |
|
||||
| 7 | No retroactive tick — every `tasks.md` checkbox reflects work actually done in this change |
|
||||
| 8 | **No `export *` in any feature-module barrel** (§6a). Run `grep -rn "^\s*export\s\+\(type\s\+\)\?\*\s\+from" packages/<plugin>/<pkg>/src/ --include="index.ts" \| grep -v "/src/index\.ts:" \| grep -v "\.select/" \| grep -v "\.native/index\.ts:" \| grep -v "\.noble/index\.ts:" \| grep -v "export \* as"`. Zero output expected. If the upstream library used `export *` barrels, **convert them in this migration** — every `<feature>/index.ts` must list its symbols by name. |
|
||||
| 9 | **No direct `vitest` / `bun:test` imports in test files** (CLAUDE.md rule 11 / §7 / §13 step 4b). Run `grep -rnE "from ['\"](vitest\|bun:test)['\"]" packages/<plugin>/<pkg>/src/ --include="*.ts" --include="*.tsx"`. Zero output expected for any non-exempt package. The exempt allowlist is exactly five testing-infra packages (`@suaveplan/testing`, `testing-dom`, `testing-e2e`, `testing-integration`, `testing-integration-step-ca`). If the upstream library imported runner primitives directly from `vitest`, **rewrite every line to `from "@suaveplan/testing/runner"` in this migration** — not as a follow-up. The repo-wide CI gate `bun scripts/lint/check-test-runner-imports.ts` catches regressions but the migration commit must already be clean. |
|
||||
|
||||
### Step 8 — Archive
|
||||
|
||||
```bash
|
||||
# fold the delta
|
||||
# (manual: copy ADDED/MODIFIED/REMOVED requirement bodies into openspec/specs/<cap>/spec.md)
|
||||
mv /mnt/s/web/genesis/openspec/changes/<change-id> /mnt/s/web/genesis/openspec/archive/$(date +%Y-%m-%d)-<change-id>
|
||||
```
|
||||
|
||||
Refresh `MANIFEST.md` if package set or deps changed:
|
||||
|
||||
```bash
|
||||
cd /mnt/s/web/genesis && bun scripts/folder-reorg/generate-manifest.ts
|
||||
```
|
||||
|
||||
Update the package listing in `CLAUDE.md`.
|
||||
|
||||
## Red flags — stop and ask
|
||||
|
||||
- The user says "just stub it" / "we'll wire it later" / "ship it 95% done" — refuse. Genesis ships at 100% or not at all.
|
||||
- You discover the source `enterprise/<pkg>.md` references functionality not in scope (e.g., the file lists 5 things but the user only wants 3) — ask before scoping down. The default is "match the source"; partial migration is a judgment call.
|
||||
- A required dependency package isn't migrated yet → check `MANIFEST.md` for dep order. Migrate the dep first, or stop and ask.
|
||||
- The conformance script reports drift you can't fix without a breaking change to public surface → stop and ask. Breaking changes need explicit user approval.
|
||||
- The user pushes back on writing `**Verified by:**` lines at draft time — show them this skill and `openspec/AGENTS.md` Section 13. Do not skip the lines.
|
||||
|
||||
## Reference materials
|
||||
|
||||
- Canonical example: `openspec/changes/error-spec-conformance/` and `packages/core/error/src/base/suaveplan-error.spec-conformance.test.ts`
|
||||
- The 17 retroactive-ticking failure modes: `openspec/AGENTS.md` Section 12 (banned archival practices) and Section 13 (audit checklist)
|
||||
- Source mapping example: any `proposal.md` in `openspec/changes/*-spec-conformance/` after the conformance sweep
|
||||
Reference in New Issue
Block a user