Initial Commit
This commit is contained in:
36
openspec/archive/2026-04-19-enterprise-dedup/proposal.md
Normal file
36
openspec/archive/2026-04-19-enterprise-dedup/proposal.md
Normal file
@@ -0,0 +1,36 @@
|
||||
# OpenSpec Change: enterprise-dedup
|
||||
|
||||
- **Change ID**: enterprise-dedup
|
||||
- **Package**: `@suaveplan/dedup`
|
||||
- **Category**: universal
|
||||
- **Target path**: `universal/data/dedup`
|
||||
- **Status**: PROPOSED
|
||||
- **Date**: 2026-04-19
|
||||
- **Reference spec**: `/mnt/s/web/suaveplan/enterprise/dedup.md`
|
||||
|
||||
## Summary
|
||||
Greenfield rebuild of `@suaveplan/dedup` — an entity deduplication engine with pluggable match keys, scoring rules, and merge strategies (latest-wins, manual, scored-merge). Computes similarity via Jaro-Winkler and Levenshtein.
|
||||
|
||||
## Current-state audit (genesis)
|
||||
Package does not exist yet — fresh build.
|
||||
|
||||
## Dependencies
|
||||
- Workspace: none (leaf)
|
||||
- External (via catalog): `zod`, `tslib`, `@opentelemetry/api`
|
||||
- Dev (via catalog): `vitest`, `@vitest/coverage-istanbul`, `fast-check`, `mitata`
|
||||
|
||||
## Preserved public surface
|
||||
- `DedupEngine` — `detect(entities, config)`, `merge(group, strategy)`.
|
||||
- Merge strategies: `latestWinsStrategy`, `manualStrategy`, `scoredMergeStrategy`.
|
||||
- Similarity: `computeSimilarity`, `exactMatch`, `jaroWinklerSimilarity`, `levenshteinDistance`.
|
||||
- Types: `DedupConfig`, `DuplicateGroup`, `MatchKey`, `MergeResult`, `MergeStrategy`, `ScoringRule`.
|
||||
|
||||
## New genesis additions
|
||||
- Codes: `DEDUP.INVALID_CONFIG`, `DEDUP.STRATEGY_ERROR`.
|
||||
- Zod schemas for `DedupConfig`, `ScoringRule`, `MatchKey`.
|
||||
- OTel counter `dedup.groups.total`, histogram `dedup.detect.duration_ms`.
|
||||
- Property tests: grouping is reflexive (`detect([x]).length === 0 duplicates`), symmetric, and scoring-rule weights in `[0, 1]`.
|
||||
|
||||
## Impact
|
||||
- Adds one new package: `universal/data/dedup`
|
||||
- Adds one new spec capability: `dedup`
|
||||
@@ -0,0 +1,27 @@
|
||||
# Capability Spec: dedup
|
||||
|
||||
**Package**: `@suaveplan/dedup`
|
||||
**Version**: 0.0.0 (genesis)
|
||||
**Status**: ADDED
|
||||
|
||||
---
|
||||
|
||||
## ADDED Requirements
|
||||
|
||||
### DD-01 — Match keys
|
||||
`MatchKey` MUST be `{ field, extract?, normaliser?, weight }`. The engine MUST support multiple match keys per config and combine their contributions by weighted sum, normalised to `[0, 1]`.
|
||||
|
||||
### DD-02 — Similarity primitives
|
||||
`exactMatch(a, b)` MUST be `a === b`. `levenshteinDistance` MUST compute edit distance in O(|a|·|b|). `jaroWinklerSimilarity` MUST return a value in `[0, 1]`. `computeSimilarity(a, b, rules)` MUST apply the configured `ScoringRule[]` and return a composite score in `[0, 1]`.
|
||||
|
||||
### DD-03 — Detect contract
|
||||
`DedupEngine.detect(entities, config)` MUST return `DuplicateGroup[]` where each group has `{ representative, members, scores }`. Every entity MUST belong to at most one group. Entities below `config.threshold` MUST NOT be grouped.
|
||||
|
||||
### DD-04 — Merge strategies
|
||||
`latestWinsStrategy` MUST pick the entity with the most recent `updatedAt`. `manualStrategy` MUST defer to the caller via a resolver callback. `scoredMergeStrategy` MUST merge fields per-field using the highest-scored source. All strategies MUST return `MergeResult { merged, sources }`.
|
||||
|
||||
### DD-05 — Observability
|
||||
Every `detect` call MUST record `dedup.detect.duration_ms` histogram and `dedup.groups.total` counter. Every merge MUST record `dedup.merge.total{strategy}`.
|
||||
|
||||
### DD-06 — Configuration validation
|
||||
`DedupConfig` MUST be validated via Zod. Invalid configs MUST surface as `DEDUP.INVALID_CONFIG`.
|
||||
27
openspec/archive/2026-04-19-enterprise-dedup/tasks.md
Normal file
27
openspec/archive/2026-04-19-enterprise-dedup/tasks.md
Normal file
@@ -0,0 +1,27 @@
|
||||
# Tasks: enterprise-dedup
|
||||
|
||||
## 1. Scaffold
|
||||
- [x] 1.1 `universal/data/dedup/`; 100/100/100/100; guard tests; CLAUDE/README/FOLDERS.
|
||||
|
||||
## 2. Errors + schemas
|
||||
- [x] 2.1 `src/errors/dedup-error.ts` — codes.
|
||||
- [x] 2.2 Zod schemas.
|
||||
|
||||
## 3. Scoring
|
||||
- [x] 3.1 `src/core/scoring/similarity.ts` — `exactMatch`, `computeSimilarity`, `jaroWinklerSimilarity`, `levenshteinDistance`.
|
||||
- [x] 3.2 Property tests.
|
||||
|
||||
## 4. Engine
|
||||
- [x] 4.1 `src/core/engine/dedup-engine.ts` — `DedupEngine` (detect + merge dispatch).
|
||||
- [x] 4.2 OTel counter + histogram.
|
||||
|
||||
## 5. Merge strategies
|
||||
- [x] 5.1 `src/core/merge/merge-strategy.ts` — `latestWinsStrategy`, `manualStrategy`, `scoredMergeStrategy`.
|
||||
|
||||
## 6. Docs / barrel / exports / README
|
||||
|
||||
## 7. Benchmarks
|
||||
- [x] 7.1 `detect.bench.ts` on 10 k / 100 k entities.
|
||||
|
||||
## 8. Ship gate
|
||||
- [x] 8.1 Verification sequence; fold + archive.
|
||||
Reference in New Issue
Block a user