Initial Commit

This commit is contained in:
2026-05-27 23:29:53 +01:00
commit fbc70f96e6
10000 changed files with 1102152 additions and 0 deletions

View File

@@ -0,0 +1,166 @@
# OpenSpec Change: enterprise-wip
- **Change ID**: enterprise-wip
- **Package**: `@suaveplan/wip`
- **Category**: universal/dev
- **Target path**: `universal/dev/wip`
- **Status**: PROPOSED
- **Date**: 2026-04-24
- **Reference spec**: `/mnt/s/web/suaveplan/enterprise/wip.md`
---
## Summary
Deliver `@suaveplan/wip` on the genesis branch from scratch at enterprise quality. The package provides a work-in-progress experiments sandbox: a structured home for exploratory code, feature-flag-gated experiments, and proof-of-concept implementations that are not yet ready for a dedicated package. Genesis adds structured errors via `@suaveplan/error`, Zod schemas for experiment metadata, OTel instrumentation, `AbortSignal` on async experiments, and an `ExperimentRegistry` for tracking active experiments with lifecycle management (draft, active, graduated, abandoned).
---
## Current-state audit (genesis)
The package does not exist on genesis yet — this is a fresh build.
---
## Available workspace deps on genesis
| Package | Role |
|---|---|
| `@suaveplan/error` (`workspace:^`) | Base class for `WipError`; stable error codes |
| `@suaveplan/types` (`workspace:^`) | `LoggerLike`, `Clock`, `EventBusLike` |
| `@suaveplan/events` (`workspace:^`) | Event bus for experiment lifecycle events |
| `@suaveplan/feature-flags` (`workspace:^`) | Feature-flag gating for experiments |
| `@suaveplan/logger` (`workspace:^`) | Structured logging |
| `zod` (`catalog:forms`) | Zod schemas for experiment metadata |
| `@opentelemetry/api` (`catalog:observability`) | Spans on experiment execution |
| `tslib` (`catalog:build`) | Runtime helpers |
Dev deps: `vitest`, `@vitest/coverage-istanbul` (all `catalog:testing`).
---
## Public API surface
### Core
```ts
function createExperimentRegistry(options?: ExperimentRegistryOptions): ExperimentRegistry
interface ExperimentRegistry {
register(experiment: ExperimentDefinition): void
get(id: string): ExperimentDefinition | null
list(status?: ExperimentStatus): ReadonlyArray<ExperimentDefinition>
run<T>(id: string, fn: ExperimentFn<T>, signal?: AbortSignal): Promise<ExperimentRun<T>>
graduate(id: string, targetPackage: string): void
abandon(id: string, reason: string): void
}
```
### Experiment definition
```ts
interface ExperimentDefinition {
id: string
name: string
description: string
author?: string
createdAt?: number
status: ExperimentStatus
targetPackage?: string // where this will graduate to
flagId?: string // optional feature flag gate
tags?: string[]
}
type ExperimentStatus = 'draft' | 'active' | 'graduated' | 'abandoned'
type ExperimentFn<T> = (signal?: AbortSignal) => Promise<T>
interface ExperimentRun<T> {
readonly experimentId: string
readonly result: T
readonly durationMs: number
readonly timestamp: number
}
interface ExperimentRegistryOptions {
logger?: LoggerLike
clock?: Clock
eventBus?: EventBusLike
flagManager?: unknown // FlagManager from @suaveplan/feature-flags
}
```
### Utilities
```ts
function wip<T>(description: string, fn: () => T): T
function wipAsync<T>(description: string, fn: (signal?: AbortSignal) => Promise<T>, signal?: AbortSignal): Promise<T>
function todo(message?: string): never
function notImplemented(feature: string): never
```
### Error codes
```ts
type WipErrorCode =
| 'WIP_EXPERIMENT_NOT_FOUND'
| 'WIP_EXPERIMENT_NOT_ACTIVE'
| 'WIP_FLAG_DISABLED'
| 'WIP_NOT_IMPLEMENTED'
| 'WIP_ABORT'
function registerWipErrorCodes(): void
```
---
## Genesis additions
1. **Structured `WipError`** extending `SuaveplanError` with stable `WIP.*` codes
2. **`ExperimentRegistry`** — lifecycle management for WIP experiments
3. **`wip()` / `wipAsync()` wrappers** — log a structured trace entry when entering WIP code; throw in production builds when `NODE_ENV === 'production'`
4. **`todo()` / `notImplemented()` helpers** — throw `WipError(WIP_NOT_IMPLEMENTED)` with descriptive message, never silent
5. **Feature-flag gating** — experiments can require a flag to be enabled before running
6. **Injectable `Clock`** for experiment timestamps
7. **OTel instrumentation** — span `wip.experiment.run`, counter `wip.experiments_run_total`
8. **Zod schemas** for `ExperimentDefinition`, `ExperimentRegistryOptions`
---
## File layout
```text
universal/dev/wip/
package.json
tsconfig.json
vitest.config.ts
src/
index.ts
error-codes.ts
constants/
index.ts
types/
common.ts
common.md
core/
registry/
registry.ts
registry.md
registry.types.ts
registry.test.ts
index.ts
utils/
helpers.ts
helpers.md
helpers.test.ts
tests/
integration.test.ts
```
---
## Impact
**Downstream packages**: Developer tooling only. Should never be imported from production packages — the `wip()` helper throws in production builds as a safety guard.
**Workspace dep prerequisites**: `@suaveplan/error`, `@suaveplan/types`, `@suaveplan/events`, `@suaveplan/feature-flags`, `@suaveplan/logger` must be published.

View File

@@ -0,0 +1,101 @@
# Tasks: enterprise-wip
**Change ID**: enterprise-wip
**Package**: `@suaveplan/wip`
**Target path**: `universal/dev/wip`
**Prerequisite packages on Verdaccio**: `@suaveplan/error`, `@suaveplan/types`, `@suaveplan/events`, `@suaveplan/feature-flags`, `@suaveplan/logger`
---
## 0. Pre-flight (non-negotiable)
- [ ] 0.1 Confirm clean working tree (`git status` reports nothing) and no in-flight worktrees with uncommitted work (`git worktree list` then `git status` in each)
- [ ] 0.2 If any worktrees exist under `.claude/worktrees/`, account for each one: still-active agent, work-pending-merge, or stale-and-prune. Stale worktrees MUST be removed (`git worktree remove`) before opening a new one — code that has been lost twice on main is the failure mode this guards against.
- [ ] 0.3 Confirm the package set in `MANIFEST.md` matches `find packages -maxdepth 3 -name package.json` count. Drift here means a prior change archived without regenerating the manifest.
## 1. Scaffold
- [ ] Create `universal/dev/wip/` with `src/`, `tests/`, and feature subdirectories per the layout in `proposal.md`.
- [ ] Write `package.json` at version `0.1.0`:
- `"type": "module"`, `"sideEffects": false`
- `exports` map: `"."` barrel + `"./core/registry/registry"`, `"./utils/helpers"`
- `dependencies`: `@suaveplan/error workspace:^`, `@suaveplan/types workspace:^`, `@suaveplan/events workspace:^`, `@suaveplan/feature-flags workspace:^`, `@suaveplan/logger workspace:^`, `zod catalog:forms`, `@opentelemetry/api catalog:observability`, `tslib catalog:build`
- `devDependencies`: `vitest catalog:testing`, `@vitest/coverage-istanbul catalog:testing`, `@suaveplan/testing workspace:^`
- [ ] Write `tsconfig.json` extending `@suaveplan/typescript-config/library.json`.
- [ ] Write `vitest.config.ts` using `createTestConfig()`.
- [ ] Add `lint`, `typecheck`, `test`, `test:coverage`, `build`, `docs:check` scripts.
---
## 2. Types and error codes
- [ ] Define all public types in `src/types/common.ts`: `ExperimentDefinition`, `ExperimentStatus`, `ExperimentFn`, `ExperimentRun`, `ExperimentRegistryOptions`, `ExperimentRegistry`.
- [ ] Write `src/types/common.md` (≥200 words, simple + advanced examples).
- [ ] Define error codes in `src/error-codes.ts`: `WipErrorCode` union, metadata, `registerWipErrorCodes()`.
- [ ] Write Zod schemas in `src/types/schemas.ts` + `src/types/schemas.md`.
---
## 3. Helper utilities (`src/utils/helpers.ts`)
- [ ] Implement `wip<T>(description, fn)`:
- In production (`process.env.NODE_ENV === 'production'`): throw `WipError(WIP_NOT_IMPLEMENTED)` immediately — WIP code must never reach production.
- In development: log a `logger.warn` or `console.warn` with the description, then call `fn()`.
- Return result of `fn()`.
- [ ] Implement `wipAsync<T>(description, fn, signal?)`: async version; same production guard.
- [ ] Implement `todo(message?)`: always throws `WipError(WIP_NOT_IMPLEMENTED)` with optional message. Return type is `never`.
- [ ] Implement `notImplemented(feature)`: throws `WipError(WIP_NOT_IMPLEMENTED)` with feature name. Return type is `never`.
- [ ] Write `helpers.test.ts` (≤500 lines): `wip` in dev executes fn, `wip` in prod throws, `wipAsync` in dev resolves, `todo` throws, `notImplemented` throws.
- [ ] Write `helpers.md` (≥200 words).
---
## 4. Experiment registry (`src/core/registry/`)
- [ ] Implement `createExperimentRegistry(options?)`:
- Stores experiments in `Map<string, ExperimentDefinition>`.
- Validates options with Zod.
- [ ] Implement `registry.register(experiment)`:
- Validates with `ExperimentDefinitionSchema`.
- Throws `WipError(WIP_EXPERIMENT_NOT_FOUND)` if ID already registered (idempotency: re-registering with same ID is a no-op).
- [ ] Implement `registry.get(id)` — returns experiment or `null`.
- [ ] Implement `registry.list(status?)` — returns experiments, optionally filtered by status.
- [ ] Implement `registry.run<T>(id, fn, signal?)`:
- Throws `WipError(WIP_EXPERIMENT_NOT_FOUND)` if experiment not registered.
- Throws `WipError(WIP_EXPERIMENT_NOT_ACTIVE)` if experiment status is not `active`.
- If `experiment.flagId` is set, check via `options.flagManager`; throw `WipError(WIP_FLAG_DISABLED)` if flag is off.
- Calls `fn(signal)`, measures duration, returns `ExperimentRun<T>`.
- OTel span `wip.experiment.run`, attribute `experiment.id`; counter `wip.experiments_run_total`.
- [ ] Implement `registry.graduate(id, targetPackage)` — updates status to `graduated`, sets `targetPackage`.
- [ ] Implement `registry.abandon(id, reason)` — updates status to `abandoned`.
- [ ] Write `registry.test.ts` (≤500 lines): register, run, flag-gated run, graduate, abandon, status filtering.
- [ ] Write `registry.md` (≥200 words).
---
## 5. Integration tests (`tests/integration.test.ts`)
- [ ] Register 3 experiments, run active one, verify result returned.
- [ ] Graduate experiment, confirm it can no longer run (not active).
- [ ] Abandon experiment, confirm it can no longer run.
- [ ] Feature-flag-gated experiment: disabled flag → `WIP_FLAG_DISABLED`.
---
## 6. Docs
- [ ] All per-file `.md` files: `common.md`, `schemas.md`, `helpers.md`, `registry.md`.
- [ ] `universal/dev/wip/README.md`: purpose (development-only sandbox), installation, usage, WARNING about production guard, API section.
---
## 7. Verify and publish
- [ ] `bunx turbo lint --filter=@suaveplan/wip` — zero errors.
- [ ] `bunx turbo typecheck --filter=@suaveplan/wip` — zero errors.
- [ ] `bunx turbo test --filter=@suaveplan/wip` — all tests pass.
- [ ] `bunx turbo test:coverage --filter=@suaveplan/wip` — 100% on all touched modules.
- [ ] `bun run docs:check --filter=@suaveplan/wip` — zero errors.
- [ ] `bun scripts/publish.ts --package @suaveplan/wip`.
- [ ] Update `CLAUDE.md` package listing.
- [ ] Archive: move `openspec/changes/enterprise-wip/` to `openspec/archive/2026-04-24-enterprise-wip/`.