diff --git a/docs/CURRENT/AEG-V16-016_VENDOR_BOUNDARY_SLICE_NOTE.md b/docs/CURRENT/AEG-V16-016_VENDOR_BOUNDARY_SLICE_NOTE.md new file mode 100644 index 00000000..58af87f9 --- /dev/null +++ b/docs/CURRENT/AEG-V16-016_VENDOR_BOUNDARY_SLICE_NOTE.md @@ -0,0 +1,28 @@ +# AEG-V16-016 — Vendor boundary fitness + +## Scope + +- **WBS / Requirement / UI / Test:** AEG-V16-016 / REQ-V16-UI4-08 / UI-V16-UI4-08 / T-V16-UI4-08 +- **Classification:** behavior-preserving validation-tool refactoring. No application provider, API, schema, or component semantics change. + +## Source / Assumption / Unknown / Decision Required + +- **Source:** `docs/CURRENT/CATALOGS/WBS_MASTER.csv`, `contracts/ui/ui-adapter.v4.json`, `tools/validate_v16.py`, and `frontend/src/shared/ui/adapter/`. +- **Assumption:** WBS Master is an extensible source-of-truth catalog; adding approved WBS rows must not make a vendor-boundary validator fail. +- **Unknown:** the acceptance evidence for AEG-V16-009 through AEG-V16-015 is absent from the progress tracker. This slice does not recreate or approve it. +- **Decision Required:** reconcile the Master and tracker before recording AEG-V16-016 as COMPLETED; dependency AEG-V16-015 has no attached acceptance evidence. + +## Acceptance mapping + +| Acceptance requirement | Evidence | +| --- | --- | +| Feature direct vendor import is zero | `tools/validate_v16.py` scans only `.ts`/`.vue` sources and rejects PrimeVue/AG Grid imports outside the approved adapter boundary. | +| Validator remains valid as WBS evolves | Master WBS IDs must be nonblank and unique; the validator no longer uses a stale fixed total row count. | +| Reproducible evidence | `python tools/validate_v16.py` result is recorded in the WBS tracker after execution. | + +## Execution evidence — 2026-08-08 + +- `python tools/validate_v16.py`: `PASS=1 WARN=2 FAIL=0`. Warnings explicitly do not claim a full source archive or external-runtime evidence. +- `frontend: pnpm test -- --run src/shared/ui/adapter/tests/uiAdapter.contract.spec.ts src/shared/ui/tests/adapterCompatibility.spec.ts`: 2 files / 4 tests passed. +- `frontend: pnpm typecheck`: passed. +- An initial test invocation from repository root failed because that directory has no `package.json`; it is not used as evidence. The frontend-directory invocation above is the preserved result. diff --git a/docs/CURRENT/CATALOGS/WBS_PROGRESS_TRACKER.csv b/docs/CURRENT/CATALOGS/WBS_PROGRESS_TRACKER.csv index 495f2882..3d1b62c9 100644 --- a/docs/CURRENT/CATALOGS/WBS_PROGRESS_TRACKER.csv +++ b/docs/CURRENT/CATALOGS/WBS_PROGRESS_TRACKER.csv @@ -7,6 +7,7 @@ AEG-X-005,S0,Cross,Security auth 고도화,COMPLETED,2026-08-04,"docs/decisions/ AEG-X-006,S0,Cross,Outbox publisher 고도화,COMPLETED,2026-08-04,"docs/CURRENT/ARTIFACTS/AEG-X-006_ACCEPTANCE_EVIDENCE.md + src/KArtSell.BuildingBlocks/Reliability/DapperOutboxWriter.cs + OutboxPollerJob.cs",BE/SRE,"✅ Outbox→Inbox async pipeline verified: DapperOutboxWriter (transactional), OutboxPollerJob (idempotent), DapperInboxStore (deduplication), 5 consumer implementations. Acceptance_Evidence: All criteria met. 177/177 tests PASS." AEG-X-007,S0,Cross,Serilog/OTel correlation 고도화,COMPLETED,2026-08-06,"tests/KArtSell.ArchitectureTests/PiiRedactionTests.cs (6 tests) + commit e7913db",SRE/Security,"✅ PII redaction policy VERIFIED: SSN/Email/CreditCard/ApiKey redaction (6 tests). Commit e7913db adds pattern-based sanitization validation. All tests PASS (249/253)." AEG-V16-017,S6,Cross,FieldShell 표준,IN_PROGRESS,TBD,"docs/CURRENT/AEG-V16-017_FIELDSHELL_SLICE_NOTE.md; frontend/src/shared/ui/components/FieldShell.vue; frontend/src/shared/ui/components/tests/FieldShell.spec.ts","FE Lead","2026-08-08: FieldShell now owns label/error/help/ARIA relationships for KsTextField, KsTextArea, KsSelect, KsDateField, and KsNumberField. Actual evidence: frontend pnpm typecheck PASS; pnpm test PASS (19 files, 42 tests); pnpm build PASS. Build emitted unrelated tracked .js drift, excluded from this Slice. COMPLETED is blocked pending WBS Master/tracker reconciliation and AEG-V16-016 vendor-boundary acceptance evidence." +AEG-V16-016,S0,VS-00,Vendor boundary fitness,IN_PROGRESS,TBD,"docs/CURRENT/AEG-V16-016_VENDOR_BOUNDARY_SLICE_NOTE.md; tools/validate_v16.py; frontend/src/shared/ui/adapter/tests/uiAdapter.contract.spec.ts","FE Lead","2026-08-08: Removed stale fixed WBS row-count assertion; validator now verifies WBS ID integrity and reports vendor imports outside the approved adapter boundary. Actual evidence: python tools/validate_v16.py PASS=1 WARN=2 FAIL=0; targeted adapter tests 4/4 PASS; frontend typecheck PASS. COMPLETED is blocked because dependency AEG-V16-015 has no approved acceptance evidence in the tracker." AEG-X-008,S0,Cross,OpenAPI artifact 고도화,COMPLETED,2026-08-04,.gitea/workflows/openapi-gate.yml + docs/api/openapi.json,BE/FE Architect,"✅ OpenAPI diff gate implemented: CI/CD automation detects breaking changes (3 checks: parameter removal, status code removal, field removal), blocks merge without approval, auto-comments on PR" AEG-VS-00-01,S0,VS-00,정책·범위·실패상태 계약 확정,COMPLETED,2026-08-06,"docs/CURRENT/SLICE_SPECS/VS-00-SLICE_SPEC.md + commit e7913db",PM/Architect,"✅ SLICE_SPEC produced: VS-00-SLICE_SPEC.md (state transitions, RBAC, governance gates, DQ rules, compliance). Commit e7913db. 249/253 tests PASS." AEG-VS-00-02,S0,VS-00,데이터 시점·스키마·정합성 계약,COMPLETED,2026-08-06,"contracts/data/platform-data-contract.v1.json + commit e7913db",Data Architect/DBA,"✅ DATA_CONTRACT v1.0 produced: PIT envelope (published_at/correlation_id/revision), 5 table schemas, DQ rules/lineage, GDPR/PCI-DSS compliance. JSON schema + validation. 249/253 tests PASS." diff --git a/tools/validate_v16.py b/tools/validate_v16.py index b145b2a9..63f9f7df 100644 --- a/tools/validate_v16.py +++ b/tools/validate_v16.py @@ -26,10 +26,12 @@ for p in (root/'frontend/src').rglob('*.vue'): for base in [root/'frontend/src',root/'src',root/'db/migrations',root/'docs/CURRENT']: for p in base.rglob('*'): if p.is_file() and p.suffix.lower() in {'.ts','.vue','.cs','.sql','.md'} and re.search(r'__[A-Z][A-Z0-9_]+__',p.read_text(encoding='utf-8')): fail(f'unresolved token {p.relative_to(root)}') -checks={'docs/CURRENT/CATALOGS/WBS_MASTER.csv':(664,'WBS_ID'),'docs/CURRENT/CATALOGS/TECH_DEBT_REGISTER.csv':(148,'ID'),'docs/CURRENT/CATALOGS/DECISION_LOG.csv':(96,'Decision_ID'),'docs/CURRENT/CATALOGS/TRACEABILITY_MATRIX.csv':(121,'Requirement_ID'),'docs/CURRENT/CATALOGS/FE_COMPONENT.csv':(58,'ID'),'docs/CURRENT/CATALOGS/JOB_CATALOGUE.csv':(28,'Job_ID'),'docs/CURRENT/CATALOGS/SOURCE_COVERAGE_MATRIX.csv':(4,'File')} -for rel,(count,key) in checks.items(): +checks={'docs/CURRENT/CATALOGS/WBS_MASTER.csv':(None,'WBS_ID'),'docs/CURRENT/CATALOGS/TECH_DEBT_REGISTER.csv':(148,'ID'),'docs/CURRENT/CATALOGS/DECISION_LOG.csv':(96,'Decision_ID'),'docs/CURRENT/CATALOGS/TRACEABILITY_MATRIX.csv':(121,'Requirement_ID'),'docs/CURRENT/CATALOGS/FE_COMPONENT.csv':(58,'ID'),'docs/CURRENT/CATALOGS/JOB_CATALOGUE.csv':(28,'Job_ID'),'docs/CURRENT/CATALOGS/SOURCE_COVERAGE_MATRIX.csv':(4,'File')} +for rel,(expected_count,key) in checks.items(): _,data=rows(rel) - if len(data)!=count: fail(f'{rel} count {len(data)} != {count}') + # WBS Master is an approved, extensible work catalog. Its identity integrity, + # rather than a historical row total, is the stable validation contract. + if expected_count is not None and len(data)!=expected_count: fail(f'{rel} count {len(data)} != {expected_count}') vals=[x.get(key,'').strip() for x in data] if any(not x for x in vals): fail(f'{rel} blank {key}') if key!='Requirement_ID' and len(vals)!=len(set(vals)): fail(f'{rel} duplicate {key}')