docs(cv-qa): verify baseline and map integration coverage

This commit is contained in:
cesnimda
2026-10-26 19:22:01 +01:00
parent ef425c288b
commit 249d06848a
3 changed files with 118 additions and 0 deletions
@@ -0,0 +1,71 @@
# CV-QA-00 architecture and baseline coverage
26 October 2026. Baseline `ef425c288b38ae0e91dcc216a5c8b6c02c433ab5`; branch `test/cv-integration-acceptance`, containing CV-UX `4a0af62`. Clean local/fetched import HEAD matched. All 84 CV-import indexed evidence hashes matched. Fresh isolated MariaDB entry run: 70/70, no skips (`.artifacts/cv-integration-qa/entry-mariadb-01`), not production.
Authority: `docs/architecture/current.md` → `overview.md`; CV-UX/CV-import ACCEPTANCE reports and CV-QA handoff; RD21 SAVE_CONTRACT; latest P9-SEC-02 addendum/verdicts; Phase 9 preservation inventory/Phase10 handoff. Historical RD21/provider blocks were superseded by actual provider qualification. P9-SEC-02 records RD21 RESOLVED and narrow trained-BART/cache compatibility PASS, with Python security CONDITIONAL PASS (vendor PyPI query gap), hosted MariaDB BLOCKED/isolation UNVERIFIED. That is not qualification of the new CV Ollama adapter or production. Original Phase10 deletion eligibility requires candidate-specific caller/route/inventory/test proof; production-only gates do not automatically block separately scoped development.
## Lifecycle and owners
```mermaid
flowchart LR
U[CareerProfilePage upload] --> V[ProfileCvController.Import validation]
V --> A[CvUploadArtifact + CvExtractionRun]
A --> Q[cv.process operation / worker lease]
Q --> S[SummarizerService → FastAPI app.py]
S --> P[bounded parser_child.py / Docling native]
P --> B[ordered id/text/kind/page blocks]
B --> I[CvDocumentInterpreter]
I --> G[CvDocumentReview.Ground]
G --> R[CvImportReview / owned source endpoint]
R --> T[apply-reviewed / expectedVersion / ExecuteAtomicAsync]
T --> C[CareerProfileService + Mapper + children/history/Identity]
C --> E[CvBuilderEditor / resolver / variant overrides]
E --> D[template physical renderer / preview / revisioned PDF]
D --> J[ApplicationAssetsService / frozen application package]
```
`CvDocumentReview`/`CvImportReview` currently expose only nonempty incoming typed leaves. `add` means accepting an emitted field; it cannot create missing fields/records. New extracted records are already appended, but missing-record authoring, explicit target selection and source assignment are absent. `CvDocumentInterpreter` handles positional pipe rows and section lists; later undelimited lines can be wrongly attached to the last global record. Transport discards Docling hierarchy/geometry/table cells, so the order of two unlabeled text lines cannot prove employer versus title. Ground currently selects the first document-wide substring, losing repeated-occurrence association.
Canonical writes remain `CareerProfileService.ExecuteAtomicAsync/SaveVersionAsync`, `CareerProfileMapper` and `CareerProfileValidator`. CV documents/settings/overrides/history retain `CvVariantService`, existing resolver/editor and physical renderers. Letter/application revisions remain `JobApplication.Version`/`ApplicationAssetsService`. No second profile, queue, revision or renderer is proposed.
## Field-level entry matrix
Each row follows source → interpreted field → generic emitted-field review → canonical destination → existing atomic persistence → CV Editor output. `CvDocumentImportTests` covers grounding/selected fields/provenance/duplicates; `CvImportReviewedPersistenceTests` covers durable transactional apply. `CvBuilderTests` and native document suites cover output owners, but do not by themselves prove imported-field integration. Statuses below are entry evidence, not final decisions.
| Source / extracted canonical field | Review control at entry | Destination / editor output | Entry classification and existing evidence |
|---|---|---|---|
| Labelled name → contact.fullName | emitted string correction | contact / CV header | Supported with incomplete evidence: real import journeys |
| Email → contact.email | emitted string correction | contact / header | Supported with incomplete evidence: parser + import journeys |
| Phone → contact.phone | emitted string correction | contact / header | Supported with incomplete evidence: labelled parser, PDF fixture |
| Title → contact.headline | emitted string correction | contact / header | Partially implemented: labelled only |
| Location → contact.location | emitted string correction | contact / header | Partially implemented: labelled only |
| Website/LinkedIn/GitHub → contact.website/linkedIn/gitHub | emitted string correction | contact / links | Supported with incomplete evidence: links regression; missing values cannot be authored |
| Portfolio/other links → contact.links[].label/url | emitted leaves | contact / labelled links | Partially implemented: existing link preservation tested, missing creation absent |
| Summary/specialisms → summary[] | emitted item correction | long-tail summary / summary | Supported with incomplete evidence: real PDF journey |
| Role/employer → jobs[].title/company | emitted leaves | work children / experience | Partially implemented: pipe grammar, extracted-add tests; missing authoring absent |
| Employment start/end → jobs[].start/end | emitted leaves | work children / original date strings | Partially implemented: partial-date/current tests; multiline dates unresolved |
| Current employment → jobs[].isCurrent | emitted true only | work children / current-date output | Partially implemented: cannot author false/missing field |
| Job location → jobs[].location | absent unless emitted | work children / experience | Missing deterministic mapping/review authoring |
| Responsibilities/achievements → jobs[].bullets[] | emitted item correction | work children / bullets | Partially implemented: list merge/provenance tested, next-record misattribution gap |
| Explicit job technologies → jobs[].skills[] | absent unless emitted | work children / skills | Missing deterministic mapping/review authoring |
| Institution/qualification → education[].institution/qualification | emitted leaves | education children / education | Partially implemented: pipe grammar; missing authoring absent |
| Qualification level → education[].qualificationLevel | absent unless emitted | education children / education | Missing stated-level mapping/review authoring; must not infer |
| Study dates → education[].start/end | emitted leaves | education children / dates | Partially implemented: partial dates supported, multiline segmentation absent |
| Education location/details → education[].location/details[] | emitted details only | education children / details | Partially implemented: location missing, continuation unsafe |
| Skills/frameworks/tools → skills[] | emitted scalar correction | skills long-tail / skills | Supported with incomplete evidence: normalized source indices tested; no schema for categories/proficiency |
| Language/proficiency/notes → languages[].name/level/notes | nonempty emitted leaves | languages long-tail / languages | Partially implemented: missing level stays unknown, missing authoring absent |
| Certification → certifications[].name/issuer/location/date/details[] | emitted name/issuer/date | certification children / certifications | Partially implemented: PDF table association defect, location/details missing |
| Project → projects[].name/role/location/start/end/bullets[]/skills[] | emitted name/role/bullets | project children / projects | Partially implemented: other fields/missing-record authoring absent |
| Awards → awards[] | emitted items | long-tail / awards | Supported with incomplete end-to-end evidence |
| Publications → publications[] | emitted items | long-tail / publications | Supported with incomplete end-to-end evidence |
| Organisations → organisations[] | emitted items | long-tail / organisations | Supported with incomplete end-to-end evidence |
| Interests → interests[] | emitted items | long-tail / interests | Supported with incomplete end-to-end evidence |
| References → references[] | emitted items | long-tail / references | Supported with incomplete end-to-end evidence |
| Courses/custom → otherSections[].title/items[] | emitted items | long-tail / custom sections | Partially implemented: retained source; cannot reclassify missing typed records |
| Stable IDs, normalized sorting dates, metadata/version | no caller authoring | canonical owner-generated/internal | Unsupported by design as extracted facts; source date precision retained |
| Experience duration, new skill-category/proficiency entities | none | no corresponding canonical contract | Unsupported by design; preserve source in custom/detail instead |
| AI interpretations / OCR/layout model results | none active | disabled/disconnected seam | Blocked by external qualification; no real CV-model evidence |
## Preservation impact
All 57 groups / 33 routes remain in scope; no historical status is upgraded by this audit. Direct changes: PRES-C01/C02/C03 (canonical/import), C05–C10/C12 (consumption/overrides/history/rendering), W05/W06/W07/W12 (associations/letters/frozen/progress), E05/E07/E08/E09 (draft/keyboard/access/ownership), S04/S05 (privacy/portability). Other groups remain regression coverage. No route removal or cleanup. See the dated Phase 9 preservation addendum and final checkpoint reconciliation.
+40
View File
@@ -0,0 +1,40 @@
# CV Integration QA Implementation Plan
> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:executing-plans. Root owns sequencing, UI, evidence and Git; scoped workers may implement independent backend/parser units. Steps use checkbox syntax.
**Goal:** Repair source-backed missing-record/field mapping and safe structural interpretation, then qualify the complete import/profile/editor/document lifecycle.
**Architecture:** Extend existing review contracts with explicit typed field mappings tied to owned source blocks and deliberate current-record targets. Retain unresolved semantic relationships; never guess unlabeled employer/title roles. Reuse canonical transactions/revisions, queue, MUI and physical renderer.
**Tech Stack:** Existing .NET9/EF/Pomelo, React/MUI/TypeScript, pinned Docling/FastAPI, disposable MariaDB12.2.2, Playwright and unchanged PDF oracles.
**Spec:** Owner CV-QA-01 attached request; ARCHITECTURE_AND_COVERAGE.md records actual entry contracts/gaps.
## Global constraints and approach
Branch `test/cv-integration-acceptance` contains `ef425c2`. No main merge, production/service/schema/cache operations, destructive migration, live CV-model activation, broad AI selection or Phase10 implementation. Use synthetic documents and bounded isolated test resources. Commit/push/verify every validated checkpoint. Preserve old benchmark/acceptance/goldens, all 57 groups and 33 routes.
Approaches considered: positional/lexicon guessing would improve apparent recall while misattributing facts; activating model inference violates the explicit gate. Chosen implementation: deterministic semantics when actually labelled/header-defined; source-preserving abstention and user-controlled mapping when ambiguous. This is an engineering choice under the owner's explicit autonomous instruction, not a new human approval claim.
## Review focus
- A valid job followed by another unlabeled employer/title/date must not absorb the latter as achievements.
- Repeated words in different records must retain the correct source occurrence, not the first global match.
- A missing record/field can be created without accepting any rejected original proposal; mapping-only application is valid.
- Explicit existing-record targets are revision-bound, owner-scoped and cannot silently become another target after 409.
- Retried mappings, rollback/projection failures and competing first/existing writes cannot duplicate or lose canonical data.
## Checkpoint tasks
- [x] **CV-QA-00:** verify ef425c2/remote/ancestry/raw evidence; audit source/authority; fresh actual MariaDB70; field matrix and preservation delta; commit/push/verify.
- [ ] **CV-QA-01:** add failing backend/controller/provider tests for explicit source-backed record/field mappings and mapping-only apply. Extend review DTO with owned source blocks, field catalog and current-record target labels. Request mappings have stable client ID, allowlisted category, optional target index, and fields `{name,value,sourceBlockId,corrected}`; no caller IDs/metadata/derived dates/arbitrary patches. Apply under existing revision/transaction, stamp actual source identity, include mappings in idempotency/audit; validator/size bounds remain. Root adds accessible EN/NB generic mapping controls and UI tests for rejection, source selection and stale retained drafts. Run focused tests/provider; commit/push/verify.
- [ ] **CV-QA-02:** red tests in CvMultilineImportTests for labelled multiline records, safe header-defined table order, repeated source occurrences and ambiguous record after resolved record. Update CvDocumentInterpreter to preserve source units and section-local state, attach only clear continuations, retain ambiguity for explicit assignment. Ground respects validated selected source block evidence. Extend a separate frozen synthetic corpus/oracle with both orders/missing dates/headings/overlaps/lists/tables; preserve original corpus/hash. Report parsing versus interpretation versus mapping versus reviewed correctness, denominators/F1/record/provenance/abstention. Real Docling fixtures; commit/push/verify.
- [ ] **CV-QA-03:** qualify same/revised/older/overlapping imports and explicit targets, similar-but-distinct employers, partial/conflicting dates, per-field rejection, source/corrections/mobile/keyboard. Extend reviewed HTTP/browser tests; fix bounded defects; commit/push/verify.
- [ ] **CV-QA-04:** actual MariaDB multi-record mapping/partial approval/rejected-field readback, replay/stale/concurrent first/existing write, rollback and owner checks. Existing lease/cancel/recovery retained; measure database interruption scope honestly. Commit/push/verify.
- [ ] **CV-QA-05:** real Docling new/old-user journeys through authoring, durable readback, variants/customizations/template/order/visibility, new revision, editor, application association and frozen letter/package preservation. Minimal fixes only; commit/push/verify.
- [ ] **CV-QA-06:** unchanged Windows/Linux24CV+4letter oracles plus rendered imported content (long work/skills/education/Unicode/templates/boundaries), semantic completeness and original portable fonts. Commit/push/verify.
- [ ] **CV-QA-07:** real malformed/bomb/external/size/page/prompt/ownership/retention/cancel/exhaustion tests; latest advisory/disposition evidence and new lock audit kept separate. Bounded concurrent synthetic uploads and observable latency/CPU/memory/temp-disk/failure measurements; no model benchmark. Commit/push/verify.
- [ ] **CV-QA-08:** available automated accessibility/keyboard/focus/locale/theme/zoom/reflow/reduced-motion checks and representative visual inspection; genuine human/device checklist remains open if unavailable. Commit/push/verify.
- [ ] **CV-QA-09:** fresh full suites/native exits/source/runtime hashes/discovery membership, exact totals without overlap; independent decisions and severity/impact/action/phase10-vs-production scope. Candidate-specific Phase10 inventory and unmet entry criteria; do not start cleanup. Final review, fix bounded findings, commit/push/verify/stop.
Native commands use the repository SDK (`C:/Users/Connor/.dotnet/dotnet.exe`), existing Jest/Playwright runners, `scripts/mariadb-integration.py`, existing isolated sidecar build and Linux PDF helper. Serialize .NET build/browser/provider lanes. Workers write tests before implementation and coordinate RED/GREEN execution through root to avoid apphost locks. Root runs integration and the complete final freeze; a fresh reviewer checks the final implementation.