146 lines
9.2 KiB
Markdown
146 lines
9.2 KiB
Markdown
# Tasks — enterprise-rules-migration
|
|
|
|
> Every checkbox MUST reflect work actually done in this change. Retroactive ticking is the failure mode this template guards against.
|
|
|
|
## 1. Spec authoring
|
|
|
|
- [x] 1.1 Read `../suaveplan/enterprise/rules.md` end-to-end
|
|
- [x] 1.2 No prior `openspec/specs/rules/spec.md` exists — new capability
|
|
- [x] 1.3 Read `openspec/AGENTS.md` Sections 13 and 14
|
|
- [x] 1.4 Draft `proposal.md` from templates/proposal.md
|
|
- [x] 1.5 Source mapping table cites enterprise/rules.md lines for every requirement
|
|
- [x] 1.6 Draft `specs/rules/spec.md` and `specs/rules-hono/spec.md`
|
|
- [x] 1.7 Every requirement carries a `**Verified by:**` line
|
|
|
|
## 2. Implementation — @suaveplan/rules
|
|
|
|
### 2.1 Package scaffold — ✅ landed 2026-05-11
|
|
|
|
- [x] 2.1.1 `packages/workflow/rules/package.json` (catalog deps + workspace `@suaveplan/error`, `events`, `types`)
|
|
- [x] 2.1.2 `tsconfig.json` + `tsconfig.lib.json` extend `tsconfig.base.json`
|
|
- [x] 2.1.3 `vite.config.ts` (preserveModules, dts)
|
|
- [x] 2.1.4 `vitest.config.ts` (istanbul, 100/100/100/100 thresholds)
|
|
- [x] 2.1.5 Subpath exports declared for every feature module (engine, builder, context, actions, events, operators, validators/{schema,field,custom}, serializer, optimizer, types, errors)
|
|
|
|
### 2.2 Types + errors + constants — ✅ landed 2026-05-11
|
|
|
|
- [x] 2.2.1 `src/types/` — rule.types, context.types, operator.types, action.types, event.types, validator.types, result.types, guards.ts, index.ts
|
|
- [x] 2.2.2 `src/errors/rules-error.ts` — `defineCodes("RULES", [24 codes])` + `RulesError extends SuaveplanError<RulesErrorCode>` + `isRulesError` guard + sibling `.test.ts` + sibling `.md`
|
|
- [x] 2.2.3 `src/constants.ts` — PACKAGE_NAME, VERSION, DEFAULT_MAX_DEPTH, DEFAULT_EVENT_HISTORY, DEFAULT_ACTION_TIMEOUT_MS, DEFAULT_ACTION_PARALLELISM + sibling `.md`
|
|
|
|
### 2.3 Engine + builder + context — ✅ landed 2026-05-11
|
|
|
|
- [x] 2.3.1 `src/engine/engine.ts` — `RuleEngine` with evaluate/evaluateAll/evaluateRuleset/check, depth limit (`RULES.ENGINE_DEPTH_EXCEEDED`), plugin registration (idempotent), AbortSignal (`RULES.ENGINE_ABORTED`), OTel histogram + counters + span; internal `compareValues` dispatcher over 33 operators + sibling .md + sibling test
|
|
- [x] 2.3.2 `src/builder/builder.ts` — `RuleBuilder` (fluent + pending-operator combine), `FieldBuilder` (30 operator methods), `rule`/`condition`/`and`/`or`/`not`/`group` factories + sibling .md + sibling test
|
|
- [x] 2.3.3 `src/context/context.ts` — `ContextBuilder` (immutable per call), `DefaultContextProvider` (injectable `Clock`, enhancer pipeline), `DefaultFieldResolver` (dot-path + `prop[N]`, strict mode → `RULES.FIELD_RESOLUTION_FAILED`), `createRequestContext`/`createScopedContext`, `getField`/`hasField`, Zod-validated options + sibling .md + sibling test
|
|
- [x] 2.3.4 `src/otel/otel.ts` — lazy OTel instruments (`getInstruments` / `resetInstruments`) + sibling .md
|
|
|
|
### 2.4 Actions + events
|
|
|
|
- [ ] 2.4.1 `src/actions/actions.ts` — `Action`, `ActionRegistry`, `ActionExecutor`, `createAction`/`createActionRegistry`/`createActionExecutor`, `validateActionConfig`, `builtInHandlers` (log/set/delay/noop with `LoggerLike`)
|
|
- [ ] 2.4.2 `src/events/event-bus.ts` — `EventBus`, `HookManager`, bounded history, priority hooks, `waitFor` with timeout + AbortSignal
|
|
|
|
### 2.5 Operators
|
|
|
|
- [ ] 2.5.1 `src/operators/registry.ts` — `OperatorRegistry`
|
|
- [ ] 2.5.2 `src/operators/defaults.ts` — 30 built-in operators + `defaultOperatorRegistry` registration
|
|
|
|
### 2.6 Validators
|
|
|
|
- [ ] 2.6.1 `src/validators/schema/schema.ts` — `SchemaValidator` with formats, transforms, recursion, AbortSignal
|
|
- [ ] 2.6.2 `src/validators/field/field.ts` — `FieldValidator`, `field()`, 12 preset chains
|
|
- [ ] 2.6.3 `src/validators/custom/custom.ts` — `CustomValidator`, `ValidatorRegistry`, 17 built-ins + `composeValidators` + `defaultValidatorRegistry`
|
|
|
|
### 2.7 Serializer + optimizer
|
|
|
|
- [ ] 2.7.1 `src/serializer/serializer.ts` — full serialize/deserialize surface with function-placeholder strategy + Zod boundary
|
|
- [ ] 2.7.2 `src/optimizer/optimizer.ts` — `optimizeRule`/`analyzeRule`/`estimateCost`/`findFields`/`hasAsyncComponents`/`countRules`
|
|
|
|
### 2.8 Barrel + benchmarks
|
|
|
|
- [ ] 2.8.1 `src/index.ts` — explicit named re-exports for every public symbol (no `export *`)
|
|
- [ ] 2.8.2 `src/__benchmarks__/` — mitata benchmarks for engine.evaluate + serializer round-trip + optimizer
|
|
|
|
## 3. Implementation — @suaveplan/rules-hono
|
|
|
|
- [ ] 3.1 `packages/workflow/rules-hono/package.json` (peer `hono`, dep `@suaveplan/rules`)
|
|
- [ ] 3.2 tsconfig + vite + vitest configs
|
|
- [ ] 3.3 `src/middleware/rule.ts`, `validation.ts`, `access-control.ts`, `response-validation.ts`, `rate-limit-rule.ts`, `combine.ts`
|
|
- [ ] 3.4 `src/engine/default.ts` — lazy `getDefaultEngine` + `resetDefaultEngine` under `./testing` subpath
|
|
- [ ] 3.5 OTel surface for every middleware
|
|
- [ ] 3.6 Barrel + subpath exports
|
|
|
|
## 4. Tests
|
|
|
|
- [ ] 4.1 Unit tests per feature module covering every scenario (every `it()` has `{ timeout: 5000 }`)
|
|
- [ ] 4.2 Spec-conformance tests (`*.spec-conformance.test.ts`) pinning type-level / OTel / RulesError-code-thrown / strict-mode scenarios
|
|
- [ ] 4.3 Property-based tests on operators (commutative/associative) + optimizer + serializer round-trips (`fast-check`)
|
|
- [ ] 4.4 Hono middleware tests via in-process `app.request(...)` (no mocks)
|
|
|
|
## 5. Documentation
|
|
|
|
- [ ] 5.1 Sibling `.md` ≥200 words for every implementation `.ts` (Purpose / Features / Basic / Advanced / API Reference / Implementation Notes)
|
|
- [ ] 5.2 Root `README.md` per package with Modules section linking every co-located `.md`
|
|
- [ ] 5.3 Update root `CLAUDE.md` package listing
|
|
- [ ] 5.4 Update `STATUS.md` (rules row + new rules-hono row)
|
|
- [ ] 5.5 Update `SUMMARY.md` workflow section
|
|
|
|
## 6. 5-gate verification
|
|
|
|
- [ ] 6.1 `bun run check` — 0/0/0
|
|
- [ ] 6.2 `bunx turbo lint typecheck test --filter=@suaveplan/rules` — green
|
|
- [ ] 6.3 `bunx turbo lint typecheck test --filter=@suaveplan/rules-hono` — green
|
|
- [ ] 6.4 `bunx turbo test:coverage --filter=@suaveplan/rules` — 100/100/100/100
|
|
- [ ] 6.5 `bunx turbo test:coverage --filter=@suaveplan/rules-hono` — 100/100/100/100
|
|
- [ ] 6.6 `bun scripts/openspec-conformance.ts @suaveplan/rules` — exit 0
|
|
- [ ] 6.7 `bun scripts/openspec-conformance.ts @suaveplan/rules-hono` — exit 0
|
|
- [ ] 6.8 `bunx turbo build --filter=@suaveplan/{rules,rules-hono}` — green
|
|
|
|
## 7. Pre-archive 9-row checklist
|
|
|
|
- [ ] 7.1 Generics threaded; `expectTypeOf` assertions on every literal-type claim (type guards)
|
|
- [ ] 7.2 Zod schemas wired at every declared boundary (RuleSchema, RulesetSchema, SerializedRuleSchema, SchemaSchema, ContextSchema, MiddlewareOptionsSchemas)
|
|
- [ ] 7.3 Every code in `defineCodes("RULES", [...])` thrown by ≥1 production path
|
|
- [ ] 7.4 Strict-mode behaviors tested both on and off (FieldResolver strict, abortEarly)
|
|
- [ ] 7.5 OTel instruments emitted from production paths, asserted with in-memory `MeterProvider`
|
|
- [ ] 7.6 Lifecycle dedup tested (`engine.use(plugin)` idempotent, `getDefaultEngine` returns identical reference)
|
|
- [ ] 7.7 No retroactive tick — every box reflects work done in this change
|
|
- [ ] 7.8 No `export *` in feature-module barrels (§6a) — `grep` clean
|
|
- [ ] 7.9 No direct `vitest` / `bun:test` imports — `grep` clean
|
|
|
|
## Continuation pickup point (next session)
|
|
|
|
**State as of 2026-05-11 ~15:55:**
|
|
|
|
Sections 1, 2.1, 2.2 are complete. Section 2.3 (engine + builder + context) is the next atomic unit — start there.
|
|
|
|
**Recommended order:**
|
|
|
|
1. **2.3 engine + builder + context** — the engine consumes context + operators; builder produces rules. Implement context first (`FieldResolver` with dot-path/array-index, `ContextBuilder`, `DefaultContextProvider`, `createRequestContext` with injectable `Clock`), then builder, then engine (depth limit, AbortSignal, OTel histograms, plugin registration).
|
|
2. **2.5 operators** — 30 built-ins are independent of engine internals beyond the `OperatorDefinition` shape (already in types). Can be implemented in parallel with 2.3 via subagent.
|
|
3. **2.4 actions + events** — depend on context + operators. EventBus consumes injectable `Clock`.
|
|
4. **2.6 validators** — three modules (schema/field/custom), each independent.
|
|
5. **2.7 serializer + optimizer** — depend on the full `Rule` surface being stable.
|
|
6. **2.8 barrel + benchmarks** — finalise `src/index.ts` to re-export every public symbol (no `export *`).
|
|
7. **3.x rules-hono** — only after the rules core is green at 100% coverage.
|
|
8. **5.x docs + 6.x gates + 7.x checklist + 8.x archive** — final sequence.
|
|
|
|
**Verification stub to land mid-stream once 2.3 is in:**
|
|
|
|
```bash
|
|
cd /home/paul/web/genesis && bun install
|
|
bunx turbo lint typecheck test --filter=@suaveplan/rules
|
|
bunx turbo test:coverage --filter=@suaveplan/rules
|
|
```
|
|
|
|
Coverage must already be 100/100/100/100 on the foundation (types + errors + constants) before adding 2.3 on top.
|
|
|
|
## 8. Archive
|
|
|
|
- [ ] 8.1 Fold `specs/rules/spec.md` into `openspec/specs/rules/spec.md`
|
|
- [ ] 8.2 Fold `specs/rules-hono/spec.md` into `openspec/specs/rules-hono/spec.md`
|
|
- [ ] 8.3 Move `openspec/changes/enterprise-rules-migration/` → `openspec/archive/<yyyy-mm-dd>-enterprise-rules-migration/`
|
|
- [ ] 8.4 `bun scripts/folder-reorg/generate-manifest.ts`
|
|
- [ ] 8.5 `bun scripts/generate-missing.ts`
|
|
- [ ] 8.6 `bunx markdownlint-cli2 --fix`
|