WW-99 Result — HonestyGuard trust anchor¶
Tailored-resume choke point¶
The job-specific path is:
IDocumentService.GenerateAsync / RegenerateAsync
→ DocumentService.GenerateAsync
→ IClaudeDrafter.DraftDocumentsAsync
→ ClaudeDrafter.TryDraftWithLlmAsync
→ ILlmHarness.GenerateAsync.
The point of no return is ClaudeDrafter.TryDraftWithLlmAsync, immediately before
BuildProfileBlock assembles the profile and the resulting prompt is sent to the selected
ILlmHarness. The generation path calls HonestyGuard.FilterMaterialSkills(intake.SkillRecords)
once and gives those Prove-derived names absolute precedence.
SkillRecord had no production consumer before this ticket; the existing tailoring prompt read
only legacy IntakeProfile.TopSkills strings. The council bridge now routes those strings around
the Prove-only filter through a separate UnverifiedLegacy prompt channel while typed Prove
records use ProvenMaterial. The two channels never blend: any Prove material wins outright and
legacy strings are ignored.
The UnverifiedLegacy block labels its values as legacy free text that is not Prove-validated and
instructs the model to use only the exact strings, never invent supporting evidence, never upgrade
confidence, and omit rather than embellish a weak match.
Filter¶
HonestyGuard.FilterMaterialSkills keeps a record only when at least one ProveItem has a
nonblank RefId. Claim-only, Aspire-only, hollow Prove items, and
in-progress-study-plan-claim-only records are removed unconditionally. Missing, null, or malformed
Prove data fails closed. The WW-97 compile-time [Obsolete(error: true)] lock is
removed now that the implementation and production call site are real.
Legacy TopSkills are never passed to that method or converted into SkillRecord.
The top-level drafting flag drafting.skillsProveOnlyStrict
(FeatureFlags.SkillsProveOnlyStrict) defaults OFF. OFF enables only the explicitly unverified
legacy bridge when no Prove records exist. ON omits legacy skills; if nonblank legacy skills were
present, GeneratedDocuments.Warnings carries: “Skills omitted: none have Prove evidence yet.
Add verified skills in Skills & Growth, or leave strict mode off until then.” A genuinely empty
profile produces neither a skills block nor a warning.
The review-fix round closes four additional silent-failure paths:
- the documents UI renders every generated warning as a warning banner;
- a feature-flag read failure fails closed to strict mode and adds the distinct warning “Could not read drafting settings; skills section may be incomplete.”;
- hollow Prove items no longer count as evidence, and a null skill list returns empty;
- Prove-backed records with blank names fall through to the legacy/strict selection path instead of suppressing all visible skill content.
Honest education language¶
The same tailored prompt assembly now renders every EducationEntry.InProgress credential with
the centralized approved phrase DegreeAdvisorCopy.DegreeInProgress ("Degree in progress"), so it
cannot imply completion.
No study-plan skill prompt template exists beyond the new SkillRecord seam. The explicit
in-progress study-plan test proves such a Claim-only record never reaches the prompt; a future
consumer must use the same Prove-only gate and may describe unproved work only as studying or
working toward it, never as present competency.
Degree-advisor copy gate¶
DegreeAdvisorCopy establishes a centralized, extensible approved-strings catalog with
evidence-calibrated education-screen, requirement-progress, and degree-in-progress wording.
DegreeAdvisorCopyTests scans every approved string against an extensible banned-phrase data set:
unlocks, guarantees, and qualifies you for the job, using case-insensitive substring checks.
API shape¶
The new IntakeProfile.SkillRecords seam preserves SkillRecord's three distinct typed axes:
Claim, Prove, and Aspire. No aggregate, composite, rating, or score type was introduced.
Verification¶
dotnet build WorkWingman.slnx -c Debug: exit 0; 0 errors; 22 pre-existing warnings.dotnet test tests/WorkWingman.Tests/WorkWingman.Tests.csproj --filter "FullyQualifiedName~HonestyGuard|FullyQualifiedName~ClaudeDrafter|FullyQualifiedName~DegreeAdvisor": exit 0; 133 passed, 0 failed, 0 skipped.frontend:npx tsc -p tsconfig.json --noEmit: exit 0; no diagnostics.frontend:npm test: exit 0; 67 files passed, 1049 tests passed, 0 failed.