Skip to content

WW-100 Result

Implemented a deterministic transcript-text parser that produces reviewable FieldProposal values only. It never writes an AcademicRecord, creates a SkillRecord, or appends a ProveItem.

Files touched

  • Added transcript request/result models and ITranscriptProposalService.
  • Added TranscriptPreParser and registered it with API dependency injection.
  • Added the feature-gated POST /api/profile/propose-from-transcript endpoint.
  • Added nullable AcademicCourse.Skills.
  • Added targeted transcript parser tests.

Anchors and confidence

  • Cumulative-labelled GPA: 98; plain GPA: 92.
  • Transcript source kind: 100.
  • Exact season/year term header: 95.
  • Labelled earned/in-progress credit total: 94.
  • Course rows with column spacing: 88; tolerant single-space rows: 78.
  • Course-title technology inference: 65, because it is a suggestion rather than transcript fact.

Anchors cover GPA labels, season/year term headers, labelled credit totals, and course rows containing a department/number code plus title and either credits/grade or grade/credits, with optional trailing numeric transcript columns. Term/major GPA labels are not treated as cumulative. Malformed data-like lines become explicit gaps rather than fabricated values.

Course to skill flow

Obvious technology names in a course title produce ordinary Courses[N].Skills[] proposals. The repository currently has no server-side resume/transcript proposal accept endpoint: accepted resume fields are applied by the client and then saved. Accordingly, WW-100 does not invent persistence or evidence promotion. A future explicit accept flow must append a ProveItem with Kind = Course only after the user accepts the course-skill proposal; this parser itself cannot do so.

Council fix round

  • Added 100 ms timeouts to every transcript-text regex and converted per-line regex timeouts into unparsed gaps rather than request failures.
  • Changed cumulative GPA and credit totals to keep one best candidate per field, prefer later equal-confidence candidates, and protect explicitly cumulative values from ambiguous totals.
  • Delayed SourceKind = Transcript until at least one transcript anchor is recognized.
  • Cleared stale term context after an unrecognized term-like header.
  • Tightened SQL skill matching, capped source labels at 256 characters, and reduced transcript text input to 200,000 characters.
  • Documented that AcademicCourse.Skills is display-only and added proposal-shape, stale-term, candidate-selection, and adversarial-input tests.

Verification

  • dotnet build WorkWingman.slnx -c Debug: exit code 0; 22 pre-existing warnings, 0 errors.
  • dotnet test tests/WorkWingman.Tests/WorkWingman.Tests.csproj --filter "FullyQualifiedName~Transcript": exit code 0; 15 passed, 0 failed, 0 skipped, 15 total.