| name | data-quality-guard |
| description | TRIGGER when: analyzing team data before sigma feedback application; validating
data completeness, type correctness, or outlier detection for any sigma team.
SKIP: non-sigma teams, raw data ingestion pipelines, schema migration tasks.
|
| version | 0.2.0 |
| license | MIT |
data_quality_guard
Elixir ๋ชจ๋: Sigma.V2.Skill.DataQualityGuard
MCP ์ด๋ฆ: data_quality_guard
๋ฒ์ : v2 (Phase 5)
Before You Start
- ๋น ๋ฐฐ์ด(
rows: [])๋ก ํธ์ถํ๋ฉด ์ฆ์ passed: false, quality_score: 0 ๋ฐํ. ๋ฐ์ดํฐ ์์ด ํธ์ถ ๊ธ์ง.
required_fields๋ฅผ ์ง์ ํ์ง ์์ผ๋ฉด ํ์ ํ๋ ๋๋ฝ ๊ฒ์ฌ๊ฐ ์ํ๋์ง ์์.
freshness_field๋ ISO 8601 datetime ๋ฌธ์์ด ๋๋ Unix ms timestamp ๊ฐ์ด์ด์ผ ํจ. ๋ค๋ฅธ ํฌ๋งท์ stale๋ก ๊ฐ์ฃผ.
numeric_fields ์์ด ์ด์๊ฐ ๊ฐ์ง๋ฅผ ๊ธฐ๋ํ์ง ๋ง ๊ฒ.
- ์ด ์คํฌ์ ์ฝ๊ธฐ ์ ์ฉ. ๋ฐ์ดํฐ๋ฅผ ์์ ํ์ง ์๊ณ ํ์ง ์ ์์ ์ด์ ๋ชฉ๋ก๋ง ๋ฐํ.
Input Schema
{
"type": "object",
"required": ["rows"],
"properties": {
"rows": {
"type": "array",
"description": "๊ฒ์ฌํ ๋ฐ์ดํฐ ๋ก์ฐ ๋ชฉ๋ก (JSON ์ค๋ธ์ ํธ ๋ฐฐ์ด)"
},
"required_fields": {
"type": "array",
"items": { "type": "string" },
"default": [],
"description": "๋ฐ๋์ ์กด์ฌํด์ผ ํ๋ ํ๋๋ช
๋ชฉ๋ก"
},
"freshness_field": {
"type": "string",
"description": "์ ์ ๋ ์ฒดํฌ์ ์ฌ์ฉํ ํ์์คํฌํ ํ๋๋ช
(์ ํ)"
},
"freshness_threshold_days": {
"type": "integer",
"default": 7,
"description": "N์ผ ์ด์ ์ค๋๋ ๋ฐ์ดํฐ๋ฅผ stale๋ก ํ์ "
},
"numeric_fields": {
"type": "array",
"items": { "type": "string" },
"default": [],
"description": "์ด์๊ฐ(outlier) ๊ฐ์ง๋ฅผ ์ ์ฉํ ์์น ํ๋๋ช
๋ชฉ๋ก"
}
}
}
Process
- ์ค๋ณต ๊ฒ์ฌ: ๊ฐ ๋ก์ฐ๋ฅผ JSON ์ง๋ ฌํ โ ํด์ ๋น๊ต. ๋์ผ ํด์ ๋ก์ฐ ์๋ฅผ
duplicate_rows๋ก ์ง๊ณ.
- ๋๋ฝ ๊ฒ์ฌ:
required_fields ๊ฐ ํญ๋ชฉ์ ๋ํด null | "" ๋ก์ฐ ์ ์ง๊ณ. ํ๋๋ณ ๊ฐ์๋ก ์ด์ ๋ถ๋ฆฌ.
- ์ ์ ๋ ๊ฒ์ฌ:
freshness_field ์ง์ ์, ํ์ฌ ์๊ฐ ๊ธฐ์ค freshness_threshold_days ์ด๊ณผ ๋ก์ฐ๋ฅผ stale_rows๋ก ์ง๊ณ.
- ์ด์๊ฐ ๊ฐ์ง:
numeric_fields ๊ฐ ํ๋์ ๋ํด median ๊ณ์ฐ โ |value - median| > max(10, |median| * 5) ์กฐ๊ฑด์ผ๋ก outlier ํ์ .
- ํ์ง ์ ์ ์ฐ์ถ:
10 - (dup*0.6) - (missing*0.8) - (stale*0.7) - (outlier*0.4) ๊ณต์. ์ต์๊ฐ 0.
- ๊ฒฐ๊ณผ ๋ฐํ:
passed (issues ์์ผ๋ฉด true), quality_score, issues ๋ชฉ๋ก, stats ์ง๊ณ.
Defaults
| ํ๋ผ๋ฏธํฐ | ๊ธฐ๋ณธ๊ฐ | ์กฐ์ ๊ธฐ์ค |
|---|
required_fields | [] | ๋น์ฆ๋์ค ๋ก์ง์ ํ์ ์ปฌ๋ผ๋ง ํฌํจ |
freshness_threshold_days | 7 | ์ผ์ผ ์
๋ฐ์ดํธ ๋ฐ์ดํฐ๋ 12์ผ, ์ฃผ๊ฐ์ 714์ผ |
numeric_fields | [] | ์์นํ KPI ์ปฌ๋ผ๋ง ํฌํจ (๋ฒ์ฃผํ ์ ์ธ) |
Integration
์๊ทธ๋ง ๋ด ํธ์ถ ์ง์ :
Sigma.V2.Commander.analyze_formation/2 โ ํ ๋ฉํธ๋ฆญ ๋ฐ์ดํฐ ์์ง ํ ํ์ง ๊ฒ์ฆ ์ 1์์ ํธ์ถ
- MCP ์๋ํฌ์ธํธ:
POST /mcp/sigma/tools/data_quality_guard/call (Bearer ์ธ์ฆ ํ์)
- Claude Code์์ ์ง์ ํธ์ถ:
data_quality_guard skill๋ก ์ด ๋ฐ์ดํฐ ๊ฒ์ฆํด์ค
Examples
Good โ ์ ์ ๋ฐ์ดํฐ์
:
{
"rows": [
{"id": 1, "name": "Alice", "score": 85, "updated_at": "2026-04-17T00:00:00Z"},
{"id": 2, "name": "Bob", "score": 90, "updated_at": "2026-04-16T00:00:00Z"}
],
"required_fields": ["id", "name"],
"freshness_field": "updated_at",
"freshness_threshold_days": 7,
"numeric_fields": ["score"]
}
Bad โ ์ค๋ณต + ๋๋ฝ ํผ์ฌ:
{
"rows": [
{"id": 1, "name": "Alice"},
{"id": 1, "name": "Alice"},
{"id": 3, "name": null}
],
"required_fields": ["id", "name"]
}
Edge โ ๋น ๋ฐฐ์ด:
{ "rows": [] }
Failure Modes
| ํจํด | ์์ธ | ๋์ฒ |
|---|
| ๋ชจ๋ ๋ก์ฐ๊ฐ stale | freshness_field ํฌ๋งท ๋ถ์ผ์น (๋นISO 8601) | ํ๋๊ฐ์ ISO 8601 ๋๋ Unix ms๋ก ๋ณํ ํ ์ฌํธ์ถ |
quality_score๊ฐ ์์ | ์ด์ ํจ๋ํฐ ํฉ์ฐ ์ด๊ณผ (0์ผ๋ก clamp๋จ) | ์ ์ ๋์. ์ฌ๊ฐํ ํ์ง ๋ฌธ์ ์๋ฏธ |
required_fields ๋ฌด์๋จ | ํ๋ผ๋ฏธํฐ ํค๊ฐ ๋ฌธ์์ด์ด ์๋ atom์ผ๋ก ์ ๋ฌ | MCP ๊ฒฝ์ ์ ์๋ ๋ณํ. ์ง์ Elixir ํธ์ถ ์ atom ํค ์ฌ์ฉ |
| outlier ๊ฐ์ง ์ ๋จ | numeric_fields ๋ฏธ์ง์ ๋๋ ๊ฐ์ด ๋ชจ๋ null | ํ๋๋ช
ํ์ธ ํ ์ฌํธ์ถ |