tools/xdata/ 는 xvoice3 등 TTS 프로젝트들의 데이터(spk2path, context CSV)를
공통 스키마 플러그인 규약으로 파싱·관리한다. Primary 저장소는 NocoDB
tts-data/dataset_variants 테이블이며(ADR 0002), 파일 레지스트리(JSON) 는
오프라인 재조회·재생성용 스냅샷으로 병행 저장된다.
관련 결정:
| 경로 | 역할 |
|---|---|
tools/xdata/core.py | Registry / StorageRoot / 플러그인 레지스트리 |
tools/xdata/schemas/base.py | DataSchema ABC (프로젝트 스키마 인터페이스) |
tools/xdata/_plugins.py | setuptools entry_points xdata.schemas 기반 플러그인 발견 |
tools/xdata/cli.py | argparse CLI (parse/modify/update/export/query/view/schemas/migrate/fs-sync) |
tools/xdata/fs_walker.py | FS 경로 → variant 추출 (KOR/MAIN 1차, 규약: wiki/tech/fs-path-convention.md) |
tools/xdata/preprocessing.py | 전처리 축 정본 + 디렉토리 suffix 파서 (PREPROC_TOKEN_MAP) |
tools/xdata/migrations/phase2_schema_v2.py | 6-field → 4-field natural_key 마이그레이션 |
tools/xdata/audit.py | dataset_variant_changes 이벤트 생성·diff·fail-soft emit |
tools/scripts/nocodb_backup.py | NocoDB 테이블 → JSONL atomic 백업 (fs-sync 전 스냅샷) |
tools/scripts/nocodb_bootstrap_audit.py | dataset_variant_changes 테이블 + _meta 등록 부트스트랩 |
tools/scripts/import_legacy_changelog.py | 과거 registry_changelog.jsonl → audit 이벤트 import |
tools/integrations/nocodb/writer.py | fail-soft write-through (실패 시 JSONL 스풀) |
tools/integrations/nocodb/replay.py | 스풀 → NocoDB 재전송 CLI |
{speaker_id}/{language}/{utterance_style}/{phoneme_source}
예: bih/KOR/MAIN/manual (4번째 자리는 phoneme_source: manual/ip_info/ip_info2/raw 등 — phoneme_encoding(예: ko_ipa)과 혼동 금지)
phoneme_encoding / phoneme_source_version / preprocessing / data_source
는 variant 내부의 processed_versions[] 로 내려가서 한 variant 아래 여러
전처리 조합을 병렬 관리한다.
모든 명령은 harness xdata … 또는 직접 xdata … 로 호출 가능.
harness xdata parse \
--project xvoice3 \
--registry /path/to/registry.v2.json \
--source spk2path \
--file /HDD0/data_list/spk2path.tsv \
--storage-root nfs_train:/HDD0/TRAIN_DATA_S98_01 \
--server server_162
harness xdata modify \
--project xvoice3 \
--registry /path/to/registry.v2.json \
--key bih/KOR/MAIN/manual \
--set inclusion_policy=excluded \
--set 'notes=["outlier"]'
--set field=value 는 값을 JSON 으로 파싱 시도 후 실패하면 문자열로 저장한다.
# 미리보기
harness xdata update --project xvoice3 --registry REG.json \
--source spk2path --file NEW.tsv --dry-run
# 적용
harness xdata update --project xvoice3 --registry REG.json \
--source spk2path --file NEW.tsv
harness xdata export --project xvoice3 --registry REG.json \
--format spk2path --out /tmp/spk2path.tsv --json
--json 은 {path, records, format} 메타만 stdout 으로 내보낸다 (본문은 파일).
harness xdata query --project xvoice3 --registry REG.json -f language=KOR --json
harness xdata view --project xvoice3 --registry REG.json --json
harness xdata schemas list --json
# 0) 백업 (apply 전에 항상 권장)
python -m tools.scripts.nocodb_backup --table dataset_variants --out-dir backups/nocodb
# 1) dry-run — added/modified/removed/pending_count + pending_report 경로
harness xdata fs-sync --project xvoice3 \
--root server_162:/HDD0/TRAIN_DATA_S98_01 \
--registry /HDD1/raymond/xvoice3/data_list/registry.v3.json \
--dry-run
# 2) 적용 — accepted 만 upsert, pending 은 `pending_<ts>.json` 로 항상 분리
harness xdata fs-sync --project xvoice3 \
--root server_162:/HDD0/TRAIN_DATA_S98_01 \
--registry /HDD1/raymond/xvoice3/data_list/registry.v3.json
--root 포맷은 server_tag:/abs/path 단일. 경로 규약은
wiki/tech/fs-path-convention.md §5 (R1~R8) 정본.
harness xdata migrate --registry OLD.json --out NEW.json
parse/modify/update 는 tools.integrations.nocodb.writer.post_with_spool
로 dataset_variants (table_id: meeukod33twsor6) 에 write-through 한다.
$HARNESS_NOCODB_SPOOL_DIR (기본 ~/.harness/spool/) 에 JSONL 로 적재된다.HARNESS_NOCODB=disabled 면 즉시 스풀로 direct.python -m tools.integrations.nocodb.replay [--table ID] [--json].컬럼 매핑:
natural_key / project / speaker_key / inclusion_policy → 단순 필드processed_versions / derived_from / tags / notes / attrs → JSON 문자열(LongText)dataset_variant_changesxdata 의 변경 이력은 NocoDB tts-data/dataset_variant_changes 테이블에 이벤트
row 로 기록된다 (table_id mryfgqxoe1643yg, unique=event_id). 현재 구현 기준
emit 경로는 fs-sync apply (sync_run 1건/실행) 만 배선되어 있으며,
parse/modify/update 등 다른 CLI write 경로는 추후 PR 에서 배선 예정 — 그 사이
개별 variant/pv timeline 은 dataset_variants 의 inverted
(variant|pv).last_change_event_id 로 추적한다.
설계 근거: docs/superpowers/plans/2026-04-24-registry-audit-log.md.
before / after 컬럼은 LongText 에 JSON 문자열로 저장. 빈 칸 = null (NocoDB
Text nullable 관례) — consumer 는 cell and json.loads(cell) 패턴으로 파싱.
| event_type | 트리거 | 현재 배선 |
|---|---|---|
variant_added / variant_removed | natural_key 신규·삭제 | 미배선 (audit.diff_variants 유틸만 제공) |
variant_field_changed | inclusion_policy/tags/notes/derived_from 등 variant 최상위 필드 변경 | 미배선 |
pv_added / pv_removed | processed_version 추가·삭제 (version_key 기준) | 미배선 |
pv_field_changed | preprocessing/paths/experimental 등 pv 필드 변경 | 미배선 |
schema_migration | 마이그레이션·스키마 변경 수동 기록 | 수동 (audit.emit) |
legacy_import | 과거 registry_changelog.jsonl import | import_legacy_changelog 1회성 |
sync_run | fs-sync 1회 batch 요약 (added_count/modified_count/removed[키]/removed_count/pending_count/root) | fs-sync apply (자동) |
apply 경로 — fs-sync 1회당 sync_run 배치 이벤트 1건을 audit.emit 으로 기록한다.
변경된 variant/pv 에는 동일 event_id 가 variant_last_change_event_id /
processed_versions[*].last_change_event_id 로 tagging 되어 timeline 추적이 가능하다.
--reason 옵션으로 이벤트 사유를 명시할 수 있다 (기본값: "fs-sync").
harness xdata fs-sync --project xvoice3 \
--root server_162:/HDD0/TRAIN_DATA_S98_01 \
--registry /HDD1/raymond/xvoice3/data_list/registry.v3.json \
--reason "daily ingest 2026-04-24"
python -m tools.scripts.import_legacy_changelog --dry-run
python -m tools.scripts.import_legacy_changelog --apply
event_id 는 (timestamp, natural_key, event_type, payload) 해시 → 재실행해도
upsert no-op. 기본 입력 경로는 /HDD1/raymond/xvoice3/data_list/registry_changelog.jsonl.
python -m tools.scripts.nocodb_bootstrap_audit --probe
python -m tools.scripts.nocodb_bootstrap_audit --apply
프로젝트 스키마는 배포 패키지의 [project.entry-points."xdata.schemas"]
섹션으로 등록한다. 예 (xvoice3/pyproject.toml):
[project.entry-points."xdata.schemas"]
xvoice3 = "xdata_plugin.schema"
해당 모듈은 탑레벨에서 @register_schema 를 호출해야 list_schemas() /
CLI --project 에서 인식된다. 허용 목록을 좁히려면 XDATA_SCHEMAS="xvoice3"
환경변수 사용. 테스트·실험용 명시 모듈 로딩은 XDATA_SCHEMAS_MODULES.
| 증상 | 원인 | 조치 |
|---|---|---|
unknown project | 스키마 플러그인 미등록 | pip install -e <worker-repo> 후 harness xdata schemas list 확인 |
| NocoDB 400 (SingleSelect) | inclusion_policy 에 정의 외 값 | default / opt_in / excluded 중 선택 |
| write-through 가 조용히 누락 | 네트워크 차단 | ~/.harness/spool/*.jsonl 확인 → replay |
harness xdata --help 가 harness 헬프만 | argparse REMAINDER 동작 | harness xdata <subcmd> --help 로 확인 |
--json 은 체이닝 수요가 있는 하위명령(query/view/schemas + export 메타) 에만 달렸다. 쓰기·마이그레이션은 체이닝 대상 아님 (플랜 Q9).pytest tests/xdata/ tests/test_nocodb_*.py.