lucidRESUME is a free, open-source desktop editor for evidence-backed resumes. You write and own the human prose. The app keeps a separate, higher-resolution JobML representation for ATS and AI systems, with every machine-facing claim linked to the evidence that supports it.
C#
7
221 commits
updated Sep 30, 2026
NOTE: lucidRESUME is a research project and not intended as a product for general use.
Human prose for people. Evidence-linked JobML for machines.
lucidRESUME is a free, open-source desktop editor for evidence-backed resumes. You write and own the human prose. The app keeps a separate, higher-resolution JobML representation for ATS and AI systems, with every machine-facing claim linked to the evidence that supports it.
It builds a structured ledger from your resumes, LinkedIn data, repositories, and other sources, then uses that ledger to:
The ledger and deterministic extraction pipeline run locally on your machine. No account is required. Data leaves your machine only when you explicitly configure a cloud AI provider, import a remote source, or use an online job-search service.
OpenAI is the primary full-strength provider for assisted ingestion and optional drafting. Anthropic and Ollama are also supported. grug 9B through LLamaSharp is an experimental offline path. These providers can offer an explicitly labelled prose draft or sample. A draft is not accepted prose, evidence, or a published claim. The person remains the author and decides what to edit, accept, and publish.
Projection itself is deterministic. It selects reviewed resume, LinkedIn, and GitHub ledger records and starts with the accepted human prose. An optional, bounded editing stage may tighten those selected passages with local grug 9B or OpenAI. The deterministic planner first fits complete source sentences to a compact per-section budget. Model edits are then accepted section by section; any edit that changes claim or evidence identity, invents a number, borrows an unsupported vacancy term, or exceeds its budget falls back to the valid human selection. Detailed experience remains selective. Accepted roles omitted from the detailed projection are preserved in a compact end-of-experience chronology when they lasted more than three months; shorter engagements are left in the complete career record. Chronology lines are deterministic ledger projections and never go through a prose-editing model. The result exports as one evidence-linked artifact in Markdown, Word, or PDF. Published documents use inline numbered citations and a compact cJobML References section. A citation can open the exact role or project in the published full career transcript. Full JobML retains the passage selectors, drift hashes, review state, and semantic metadata omitted from the compact document. Transcript links expose the fuller candidate-maintained account; repositories, articles, releases, qualifications, and similar artefacts remain distinguishable as stronger external evidence. See the design article. See resume output and template design for the full flow, template rationale, and configuration.
Built with .NET 10 + Avalonia. Runs on Windows, macOS, and Linux.
Every skill is backed by evidence.
lucidRESUME doesn't just list what you say you know - it builds a skill ledger where each skill is tied to:
No invented skills. No output-time guessing. Extraction is recorded once with its method, confidence, source, and review state.
An optional local Ollama Nimble decision layer can resolve bounded ingestion ambiguities after local rules and NER have proposed candidates. It can classify an unknown section or prose-linked skill, or select an already-extracted person or employer span. It cannot generate a new name, company, claim, or evidence value. Every decision is probability-gated, source-hashed, and recorded for review. Nimble is disabled by default. See the local setup and decision guide. Cloud API keys entered in Profile are held by the operating system credential store, never in the JSON settings file.
This is the foundation everything else builds on - matching, projection, gap analysis, and career direction.
The two representations have different jobs:
lucidRESUME is not an automated job application service and it is not intended to disguise machine-written text as human writing. Its purpose is to let human writing remain human while giving ATS and AI systems a precise, verifiable view.
The experimental JobML 0.1 editor places authoritative human Markdown on the
left, editable JobML on the right, and live evidence links between them. Selecting
a link highlights both the supporting prose and machine reference. As prose
changes, claims are marked valid, changed, missing, or ambiguous;
inferred claims never become evidence without explicit acceptance. Markdown may
be shorter for a particular role while JobML retains higher-resolution external
evidence. Its default Document tab is a debounced live DOCX projection through
the selected output template, rendered by Morph beside those evidence links. It
does not re-extract or reinterpret the ledger. See the
JobML specification,
cJobML publication specification,
implementation profile, and
GitHub repository extension.
![]() | ![]() |
Every major job site wants your email, your browsing history, and permission to sell your profile. AI resume tools send your CV to some SaaS vendor's cloud. Paid tools charge monthly for table-stakes features.
lucidRESUME does things differently:



career_record, including sources and optional semantic artefactslucidRESUME.Web is an ASP.NET Core control for the narrow publish-and-compile
workflow. It does not ingest LinkedIn exports, repositories, or old CVs. That
happens upstream in the desktop application. The control accepts the already
exported Markdown + JobML career_record, publishes an immutable revision,
accepts a job description, and returns a shorter evidence-bounded projection with
Markdown, Word, and PDF downloads. Each published application receives an opaque
URL whose browser view shows the résumé, its selected claims, and links into the
complete transcript. The same publication exposes full JobML and cJobML to machine
clients. The application career ledger remains the
canonical source; the published JobML document is its portable projection.
OpenAI is the default interactive editor. The local LLamaSharp path batches the
projection in ordered groups of three and can recover complete section objects
from a truncated response without accepting an incomplete edit. The compiler
keeps the reviewed summary outside model editing, orders experience in reverse
chronology, and deterministically adds the detected target title, canonical
evidence-backed skills, role-relevant projects, and reviewed education.

builder.Services.AddLucidResumeCompiler(builder.Configuration);
var app = builder.Build();
app.UseAntiforgery();
app.MapLucidResumeCompiler();
app.Run();
Run the included host with:
dotnet run --project samples/lucidRESUME.Web.Sample
The control is mounted at /resume by default. The current career-record
projection is served at /resume/api/jobml; immutable source revisions and
application-specific publication URLs carry ETags and cache headers. API keys
remain server-side. See the
web compiler guide.
For the adjacent Mostlylucid site checkout, run
scripts/run-local-resume-integration.sh to serve the compiler at
http://127.0.0.1:8080/resume/. Publish the reviewed Markdown and JobML career
record locally, paste a job description, then use the resulting evidence link to
inspect the full transcript, ordered source chunks, cJobML, Word, and PDF. The
sample's App_Data publications are ignored by Git; keep private career records
out of commits. Local Ollama setup and gateway configuration are in the
web compiler guide.

Seven job board adapters searched in parallel (Adzuna, Reed, Findwork, Arbeitnow, JoinRise, Jobicy, Remotive). Near-duplicate detection via embedding similarity. Hoover role flagging.
JSON Resume (standard schema), Markdown, DOCX (Word via OpenXml), and tagged PDF/UA (QuestPDF). DOCX uses real Word lists and named headings; both office formats keep identity in the document body and avoid tables, sidebars, text boxes and repeated résumé headers.
lucidresume parse --file cv.docx [--output result.json]
lucidresume evidence --resume cv.docx [--output ledger.json]
lucidresume match --resume cv.docx --job "JD text"
lucidresume compound-match --resume cv.docx --jobs-dir jds/
lucidresume explain --resume cv.docx --job "JD text"
lucidresume tailor --resume cv.docx --job "JD text" [--full-jobml https://example.net/career.jobml] [--output projected.md]
lucidresume drift --resume1 old.docx --resume2 new.docx
lucidresume export --file cv.docx --format pdf|docx|markdown|json
lucidresume validate --resume cv.docx
lucidresume fix --resume cv.docx [--output fixed.md]
lucidresume generate --resume cv.docx --prompt "draft a 2 page cloud resume" [--full-jobml https://example.net/career.jobml]
lucidresume anonymize --resume cv.docx [--output anon.json]
lucidresume rank --dir resumes/ --job "JD text"
lucidresume search --prompt "senior .NET developer remote"
lucidresume extract-jd --job "JD text" [--output jd.json]
lucidresume github-import --username scottgal --output repositories.json
lucidresume package-audit --publisher mostlylucid --output packages.json
lucidresume batch-test --dir resumes/
lucidresume jobml validate --file resume.jobml.md
lucidresume jobml reconcile --file resume.jobml.md
lucidresume jobml coverage --file resume.jobml.md
lucidresume jobml cold-parser-probe --file resume.jobml.md
lucidresume jobml career-record --resume-dir /path/to/resumes --github scottgal --nuget-publisher mostlylucid --output career.jobml.md
lucidresume jobml compact --file resume.jobml.md --full-jobml https://example.net/career.jobml --output resume.md
lucidresume jobml link-post --file resume.jobml.md --claim claim-id --url https://example.net/article --output linked.jobml.md
Role projections include compact cJobML citations in Markdown, Word, and PDF by
default. Pass --cjobml false to tailor, generate, or render for a
human-only copy. --full-jobml gives transcript references an exact deep link.
Compact references can cite transcript sections and public evidence without
copying full passages, selectors, or drift hashes out of the full JobML career
record.
Relevance and recency should not erase a defining older role. Mark a role as Always include on the My Data page, or place an invisible directive directly below its Markdown heading:
### Program Manager II | Microsoft Corp
<!-- lucidresume:career-anchor -->
The full JobML career_record publishes this as
projection: { include: always }. Compilers reserve anchor sections before
ranking ordinary roles. The preference does not strengthen the role's claims or
bypass evidence validation.
CLI and server configurations may anchor every role for selected companies:
{
"Tailoring": {
"CareerAnchorCompanies": ["Microsoft", "Dell"]
}
}
Company anchoring is explicitly configured by the author. lucidRESUME does not maintain an inferred employer-prestige score.
| Platform | Download |
|---|---|
| Windows | lucidRESUME-...-win-x64.zip or win-arm64.zip |
| macOS | lucidRESUME-...-osx-arm64.tar.gz (Apple Silicon) or osx-x64.tar.gz (Intel) |
| Linux | lucidRESUME-...-linux-x64.tar.gz or linux-arm64.tar.gz |
lucidRESUME.app. On Windows or Linux,
run lucidRESUME.exe or lucidRESUME respectively.The desktop app downloads its local ONNX models (about 600 MB) on first launch. They are cached in the user data directory, outside the signed application bundle. No account or setup wizard is required.
macOS users: the bundle is ad-hoc signed but not notarized. If Gatekeeper blocks it, Control-click the extracted app and choose Open. If needed, run
xattr -dr com.apple.quarantine ./lucidRESUME.appon that app only.
AI assistance is optional. It can recover structured candidates from difficult source documents or offer a clearly labelled authoring draft. Every inferred record is stored with provenance and requires review. Draft prose remains unaccepted until a person edits and approves it. Resume projection and export work without a language model.
Option 1: OpenAI (primary full-strength provider)
openaiOption 2: Local AI with LLamaSharp (experimental)
llamasharp and click Download local modelThe model is loaded lazily and uses its embedded chat template. Apple Silicon uses the Metal support included in the LLamaSharp CPU backend; other platforms have a portable CPU fallback. Set LlamaSharp:ModelPath, ContextSize, or GpuLayerCount in lucidresume.json to override the defaults. Relative model paths resolve under the user data directory, outside the signed application bundle.
Option 3: Local AI with Ollama
ollama pull qwen3.5:4bollama under Profile → AI ProviderOption 4: Anthropic
anthropicFor developers who want to build from source:
git clone https://github.com/scottgal/lucidRESUME
cd lucidRESUME
dotnet run --project src/lucidRESUME/lucidRESUME.csproj
Requires .NET 10 SDK. The default solution is desktop-only, so dotnet build lucidRESUME.sln and dotnet test lucidRESUME.sln do not require mobile workloads. See docs/release.md for the release workflow.
5-layer RRF fusion for both resume and JD extraction: structural patterns + ONNX NER (2 models) + skill taxonomy centroids (19,983 skills from 1.3M LinkedIn jobs) + optional LLM candidate extraction + entity lookup (11K companies, 7K locations). All signals run during ingestion and are fused by reciprocal rank fusion with multi-source confidence boosting. The resulting evidence records are persisted with provenance and review state.
Export is deliberately less clever. It is a projection of accepted ledger records. It does not rerun NER or an LLM, and it refuses stale evidence. This keeps the human prose and the JobML evidence graph reversible: each rendered claim points back to the exact ingested evidence and source revision that justified it.
Skill taxonomy: 19,983 preprocessed entries from the documented Kaggle/LinkedIn datasets ship with the application, together with priority data and compact leadership profiles for Lead Developer, Head of Engineering, CTO and VP Engineering. These source terms are the reproducible seeds for exact matching and locally materialised role centroids. No personal résumé, ledger or user database is part of the preload. Used by both resume and JD parsers to find skills embedded in prose.
The exact clean-install boundary, dataset provenance and release audit are documented in Product data and clean-install contract.
ONNX embeddings (all-MiniLM-L6-v2, 384-dim) power semantic matching throughout. DocLayNet YOLO model detects document structure from rendered page images — titles, section headers, tables, lists — producing a structural hash for template identification. Docling (Docker) adds ML-based PDF layout detection for complex documents; PdfPig with column detection as local fallback.
lucidRESUME (Avalonia UI: My CV, JobML Editor, My Data, Career, Jobs, Add Job, Project, Pipeline, Profile, Help)
├── Ingestion Resume parsing, DocLayNet layout detection, Morph preview, LinkedIn import
├── Extraction ONNX NER (2 models) + Microsoft.Recognizers pipeline
├── Parsing DOCX/PDF/TXT extraction, ATS pattern detection, template learning
├── JobSpec JD parsing (5-layer RRF: Structural + NER + Taxonomy + LLM + Entity), URL scraping
├── JobSearch 7 job board adapters + orchestrator + deduplicator
├── Matching Skill ledger, skill graph, career planner, taxonomy centroids, entity lookup
├── AI LLamaSharp/Ollama/Anthropic/OpenAI ingestion and draft-authoring providers
├── Compiler Complete JobML master -> deterministic role-specific projection
├── Web Embeddable ASP.NET Core publish, preview, and export control
├── EmailTracker IMAP scanning, email classification, application matching
├── Export JSON Resume + Markdown + DOCX + PDF exporters
├── Collabora Installed-editor discovery and LibreOffice fallback
├── Avalonia.UITesting UI automation framework (REPL, MCP, script runner)
└── Core Domain models, interfaces, persistence (SQLite + sqlite-vec)
Dependency rule: everything depends inward on Core. Core depends only on Microsoft.Data.Sqlite and sqlite-vec.
| Pattern | Where | Why |
|---|---|---|
| 5-Layer RRF Fusion | Resume + JD extraction | Structural + NER + Taxonomy + LLM + Entity Lookup vote, best candidate wins |
| Skill Taxonomy | Matching module | 19,983 skills from 1.3M LinkedIn jobs — cross-industry, not just tech |
| Entity Lookup | JD parser | 11K companies + 7K locations from LinkedIn/Adzuna validate NER candidates |
| Skill Ledger | Matching module | Every skill backed by evidence with provenance |
| Skill Graph + Communities | Career planner | Leiden community detection with UMAP visualisation |
| Template Learning | DOCX parser | First parse learns structure, subsequent parses are deterministic |
| ATS Pattern Detection | PDF parser | YAML rulesets identify resume templates/ATS systems |
dotnet test lucidRESUME.sln # 479 tests across 12 projects
| Project | Tests | Coverage |
|---|---|---|
| Core.Tests | 101 | Persistence, models, reviewed transcript overlays, multi-resume, export, linked posts |
| Extraction.Tests | 25 | NER, recognizers, RRF fusion pipeline |
| AI.Tests | 46 | Providers, embeddings, bounded decisions, deterministic projection, gated live OpenAI checks |
| Matching.Tests | 64 | Skill scoring, filters, voting, job-search resilience, projection quality |
| JobSpec.Tests | 16 | JD parsing, deterministic flattened-title extraction, salary extraction |
| EmailTracker.Tests | 25 | Classifier, matcher |
| GitHub.Tests | 44 | Language map, repository assessment, package families, LinkedIn parsing, reviewed document merge |
| JobML.Tests | 29 | Parsing, validation, drift, reversible links, cJobML projection |
| Compiler.Tests | 24 | Deterministic evidence selection, compact chronology and projection orchestration |
| Web.Tests | 5 | ASP.NET Core endpoint and projection control |
| App.Tests | 2 | Native operating-system credential storage |
| Avalonia.UITesting.Tests | 98 | Input, scripts, locators, screenshots, REPL |
The Chrome evidence filler has a separate TypeScript suite:
cd extensions/lucidresume-chrome
npm ci && npm run check && npm test && npm run build
The UI automation layer is published as a standalone NuGet package — Mostlylucid.Avalonia.UITesting — so any Avalonia desktop app can use it. Real pointer/touch/wheel/gesture input via Avalonia's IInputManager, region/control snipping for manuals, YAML scripts, GIF video, REPL, and an MCP server. Source lives in src/Mostlylucid.Avalonia.UITesting/.
# Run a YAML test script
dotnet run --project src/lucidRESUME/lucidRESUME.csproj -- \
--ux-test --script ux-scripts/e2e-full-flow.yaml --output ux-screenshots
# Interactive REPL
dotnet run --project src/lucidRESUME/lucidRESUME.csproj -- --ux-repl
# MCP server (for LLM-driven UI control)
dotnet run --project src/lucidRESUME/lucidRESUME.csproj -- --ux-mcp
PRs welcome. Run the tests before submitting:
dotnet test
The codebase follows a strict inward dependency rule - keep domain logic in Core and wire everything in the app shell.
This is free and unencumbered software released into the public domain. See LICENSE or unlicense.org for details.
No strings attached. No attribution required. Use it however you like.
0 followers · starred Aug 2026
C#
96.4%
TypeScript
2.4%
lucidRESUME is a free, open-source desktop editor for evidence-backed resumes. You write and own the human prose. The app keeps a separate, higher-resolution JobML representation for ATS and AI systems, with every machine-facing claim linked to the evidence that supports it.
C#
7
221 commits
updated Sep 30, 2026
NOTE: lucidRESUME is a research project and not intended as a product for general use.
Human prose for people. Evidence-linked JobML for machines.
lucidRESUME is a free, open-source desktop editor for evidence-backed resumes. You write and own the human prose. The app keeps a separate, higher-resolution JobML representation for ATS and AI systems, with every machine-facing claim linked to the evidence that supports it.
It builds a structured ledger from your resumes, LinkedIn data, repositories, and other sources, then uses that ledger to:
The ledger and deterministic extraction pipeline run locally on your machine. No account is required. Data leaves your machine only when you explicitly configure a cloud AI provider, import a remote source, or use an online job-search service.
OpenAI is the primary full-strength provider for assisted ingestion and optional drafting. Anthropic and Ollama are also supported. grug 9B through LLamaSharp is an experimental offline path. These providers can offer an explicitly labelled prose draft or sample. A draft is not accepted prose, evidence, or a published claim. The person remains the author and decides what to edit, accept, and publish.
Projection itself is deterministic. It selects reviewed resume, LinkedIn, and GitHub ledger records and starts with the accepted human prose. An optional, bounded editing stage may tighten those selected passages with local grug 9B or OpenAI. The deterministic planner first fits complete source sentences to a compact per-section budget. Model edits are then accepted section by section; any edit that changes claim or evidence identity, invents a number, borrows an unsupported vacancy term, or exceeds its budget falls back to the valid human selection. Detailed experience remains selective. Accepted roles omitted from the detailed projection are preserved in a compact end-of-experience chronology when they lasted more than three months; shorter engagements are left in the complete career record. Chronology lines are deterministic ledger projections and never go through a prose-editing model. The result exports as one evidence-linked artifact in Markdown, Word, or PDF. Published documents use inline numbered citations and a compact cJobML References section. A citation can open the exact role or project in the published full career transcript. Full JobML retains the passage selectors, drift hashes, review state, and semantic metadata omitted from the compact document. Transcript links expose the fuller candidate-maintained account; repositories, articles, releases, qualifications, and similar artefacts remain distinguishable as stronger external evidence. See the design article. See resume output and template design for the full flow, template rationale, and configuration.
Built with .NET 10 + Avalonia. Runs on Windows, macOS, and Linux.
Every skill is backed by evidence.
lucidRESUME doesn't just list what you say you know - it builds a skill ledger where each skill is tied to:
No invented skills. No output-time guessing. Extraction is recorded once with its method, confidence, source, and review state.
An optional local Ollama Nimble decision layer can resolve bounded ingestion ambiguities after local rules and NER have proposed candidates. It can classify an unknown section or prose-linked skill, or select an already-extracted person or employer span. It cannot generate a new name, company, claim, or evidence value. Every decision is probability-gated, source-hashed, and recorded for review. Nimble is disabled by default. See the local setup and decision guide. Cloud API keys entered in Profile are held by the operating system credential store, never in the JSON settings file.
This is the foundation everything else builds on - matching, projection, gap analysis, and career direction.
The two representations have different jobs:
lucidRESUME is not an automated job application service and it is not intended to disguise machine-written text as human writing. Its purpose is to let human writing remain human while giving ATS and AI systems a precise, verifiable view.
The experimental JobML 0.1 editor places authoritative human Markdown on the
left, editable JobML on the right, and live evidence links between them. Selecting
a link highlights both the supporting prose and machine reference. As prose
changes, claims are marked valid, changed, missing, or ambiguous;
inferred claims never become evidence without explicit acceptance. Markdown may
be shorter for a particular role while JobML retains higher-resolution external
evidence. Its default Document tab is a debounced live DOCX projection through
the selected output template, rendered by Morph beside those evidence links. It
does not re-extract or reinterpret the ledger. See the
JobML specification,
cJobML publication specification,
implementation profile, and
GitHub repository extension.
![]() | ![]() |
Every major job site wants your email, your browsing history, and permission to sell your profile. AI resume tools send your CV to some SaaS vendor's cloud. Paid tools charge monthly for table-stakes features.
lucidRESUME does things differently:



career_record, including sources and optional semantic artefactslucidRESUME.Web is an ASP.NET Core control for the narrow publish-and-compile
workflow. It does not ingest LinkedIn exports, repositories, or old CVs. That
happens upstream in the desktop application. The control accepts the already
exported Markdown + JobML career_record, publishes an immutable revision,
accepts a job description, and returns a shorter evidence-bounded projection with
Markdown, Word, and PDF downloads. Each published application receives an opaque
URL whose browser view shows the résumé, its selected claims, and links into the
complete transcript. The same publication exposes full JobML and cJobML to machine
clients. The application career ledger remains the
canonical source; the published JobML document is its portable projection.
OpenAI is the default interactive editor. The local LLamaSharp path batches the
projection in ordered groups of three and can recover complete section objects
from a truncated response without accepting an incomplete edit. The compiler
keeps the reviewed summary outside model editing, orders experience in reverse
chronology, and deterministically adds the detected target title, canonical
evidence-backed skills, role-relevant projects, and reviewed education.

builder.Services.AddLucidResumeCompiler(builder.Configuration);
var app = builder.Build();
app.UseAntiforgery();
app.MapLucidResumeCompiler();
app.Run();
Run the included host with:
dotnet run --project samples/lucidRESUME.Web.Sample
The control is mounted at /resume by default. The current career-record
projection is served at /resume/api/jobml; immutable source revisions and
application-specific publication URLs carry ETags and cache headers. API keys
remain server-side. See the
web compiler guide.
For the adjacent Mostlylucid site checkout, run
scripts/run-local-resume-integration.sh to serve the compiler at
http://127.0.0.1:8080/resume/. Publish the reviewed Markdown and JobML career
record locally, paste a job description, then use the resulting evidence link to
inspect the full transcript, ordered source chunks, cJobML, Word, and PDF. The
sample's App_Data publications are ignored by Git; keep private career records
out of commits. Local Ollama setup and gateway configuration are in the
web compiler guide.

Seven job board adapters searched in parallel (Adzuna, Reed, Findwork, Arbeitnow, JoinRise, Jobicy, Remotive). Near-duplicate detection via embedding similarity. Hoover role flagging.
JSON Resume (standard schema), Markdown, DOCX (Word via OpenXml), and tagged PDF/UA (QuestPDF). DOCX uses real Word lists and named headings; both office formats keep identity in the document body and avoid tables, sidebars, text boxes and repeated résumé headers.
lucidresume parse --file cv.docx [--output result.json]
lucidresume evidence --resume cv.docx [--output ledger.json]
lucidresume match --resume cv.docx --job "JD text"
lucidresume compound-match --resume cv.docx --jobs-dir jds/
lucidresume explain --resume cv.docx --job "JD text"
lucidresume tailor --resume cv.docx --job "JD text" [--full-jobml https://example.net/career.jobml] [--output projected.md]
lucidresume drift --resume1 old.docx --resume2 new.docx
lucidresume export --file cv.docx --format pdf|docx|markdown|json
lucidresume validate --resume cv.docx
lucidresume fix --resume cv.docx [--output fixed.md]
lucidresume generate --resume cv.docx --prompt "draft a 2 page cloud resume" [--full-jobml https://example.net/career.jobml]
lucidresume anonymize --resume cv.docx [--output anon.json]
lucidresume rank --dir resumes/ --job "JD text"
lucidresume search --prompt "senior .NET developer remote"
lucidresume extract-jd --job "JD text" [--output jd.json]
lucidresume github-import --username scottgal --output repositories.json
lucidresume package-audit --publisher mostlylucid --output packages.json
lucidresume batch-test --dir resumes/
lucidresume jobml validate --file resume.jobml.md
lucidresume jobml reconcile --file resume.jobml.md
lucidresume jobml coverage --file resume.jobml.md
lucidresume jobml cold-parser-probe --file resume.jobml.md
lucidresume jobml career-record --resume-dir /path/to/resumes --github scottgal --nuget-publisher mostlylucid --output career.jobml.md
lucidresume jobml compact --file resume.jobml.md --full-jobml https://example.net/career.jobml --output resume.md
lucidresume jobml link-post --file resume.jobml.md --claim claim-id --url https://example.net/article --output linked.jobml.md
Role projections include compact cJobML citations in Markdown, Word, and PDF by
default. Pass --cjobml false to tailor, generate, or render for a
human-only copy. --full-jobml gives transcript references an exact deep link.
Compact references can cite transcript sections and public evidence without
copying full passages, selectors, or drift hashes out of the full JobML career
record.
Relevance and recency should not erase a defining older role. Mark a role as Always include on the My Data page, or place an invisible directive directly below its Markdown heading:
### Program Manager II | Microsoft Corp
<!-- lucidresume:career-anchor -->
The full JobML career_record publishes this as
projection: { include: always }. Compilers reserve anchor sections before
ranking ordinary roles. The preference does not strengthen the role's claims or
bypass evidence validation.
CLI and server configurations may anchor every role for selected companies:
{
"Tailoring": {
"CareerAnchorCompanies": ["Microsoft", "Dell"]
}
}
Company anchoring is explicitly configured by the author. lucidRESUME does not maintain an inferred employer-prestige score.
| Platform | Download |
|---|---|
| Windows | lucidRESUME-...-win-x64.zip or win-arm64.zip |
| macOS | lucidRESUME-...-osx-arm64.tar.gz (Apple Silicon) or osx-x64.tar.gz (Intel) |
| Linux | lucidRESUME-...-linux-x64.tar.gz or linux-arm64.tar.gz |
lucidRESUME.app. On Windows or Linux,
run lucidRESUME.exe or lucidRESUME respectively.The desktop app downloads its local ONNX models (about 600 MB) on first launch. They are cached in the user data directory, outside the signed application bundle. No account or setup wizard is required.
macOS users: the bundle is ad-hoc signed but not notarized. If Gatekeeper blocks it, Control-click the extracted app and choose Open. If needed, run
xattr -dr com.apple.quarantine ./lucidRESUME.appon that app only.
AI assistance is optional. It can recover structured candidates from difficult source documents or offer a clearly labelled authoring draft. Every inferred record is stored with provenance and requires review. Draft prose remains unaccepted until a person edits and approves it. Resume projection and export work without a language model.
Option 1: OpenAI (primary full-strength provider)
openaiOption 2: Local AI with LLamaSharp (experimental)
llamasharp and click Download local modelThe model is loaded lazily and uses its embedded chat template. Apple Silicon uses the Metal support included in the LLamaSharp CPU backend; other platforms have a portable CPU fallback. Set LlamaSharp:ModelPath, ContextSize, or GpuLayerCount in lucidresume.json to override the defaults. Relative model paths resolve under the user data directory, outside the signed application bundle.
Option 3: Local AI with Ollama
ollama pull qwen3.5:4bollama under Profile → AI ProviderOption 4: Anthropic
anthropicFor developers who want to build from source:
git clone https://github.com/scottgal/lucidRESUME
cd lucidRESUME
dotnet run --project src/lucidRESUME/lucidRESUME.csproj
Requires .NET 10 SDK. The default solution is desktop-only, so dotnet build lucidRESUME.sln and dotnet test lucidRESUME.sln do not require mobile workloads. See docs/release.md for the release workflow.
5-layer RRF fusion for both resume and JD extraction: structural patterns + ONNX NER (2 models) + skill taxonomy centroids (19,983 skills from 1.3M LinkedIn jobs) + optional LLM candidate extraction + entity lookup (11K companies, 7K locations). All signals run during ingestion and are fused by reciprocal rank fusion with multi-source confidence boosting. The resulting evidence records are persisted with provenance and review state.
Export is deliberately less clever. It is a projection of accepted ledger records. It does not rerun NER or an LLM, and it refuses stale evidence. This keeps the human prose and the JobML evidence graph reversible: each rendered claim points back to the exact ingested evidence and source revision that justified it.
Skill taxonomy: 19,983 preprocessed entries from the documented Kaggle/LinkedIn datasets ship with the application, together with priority data and compact leadership profiles for Lead Developer, Head of Engineering, CTO and VP Engineering. These source terms are the reproducible seeds for exact matching and locally materialised role centroids. No personal résumé, ledger or user database is part of the preload. Used by both resume and JD parsers to find skills embedded in prose.
The exact clean-install boundary, dataset provenance and release audit are documented in Product data and clean-install contract.
ONNX embeddings (all-MiniLM-L6-v2, 384-dim) power semantic matching throughout. DocLayNet YOLO model detects document structure from rendered page images — titles, section headers, tables, lists — producing a structural hash for template identification. Docling (Docker) adds ML-based PDF layout detection for complex documents; PdfPig with column detection as local fallback.
lucidRESUME (Avalonia UI: My CV, JobML Editor, My Data, Career, Jobs, Add Job, Project, Pipeline, Profile, Help)
├── Ingestion Resume parsing, DocLayNet layout detection, Morph preview, LinkedIn import
├── Extraction ONNX NER (2 models) + Microsoft.Recognizers pipeline
├── Parsing DOCX/PDF/TXT extraction, ATS pattern detection, template learning
├── JobSpec JD parsing (5-layer RRF: Structural + NER + Taxonomy + LLM + Entity), URL scraping
├── JobSearch 7 job board adapters + orchestrator + deduplicator
├── Matching Skill ledger, skill graph, career planner, taxonomy centroids, entity lookup
├── AI LLamaSharp/Ollama/Anthropic/OpenAI ingestion and draft-authoring providers
├── Compiler Complete JobML master -> deterministic role-specific projection
├── Web Embeddable ASP.NET Core publish, preview, and export control
├── EmailTracker IMAP scanning, email classification, application matching
├── Export JSON Resume + Markdown + DOCX + PDF exporters
├── Collabora Installed-editor discovery and LibreOffice fallback
├── Avalonia.UITesting UI automation framework (REPL, MCP, script runner)
└── Core Domain models, interfaces, persistence (SQLite + sqlite-vec)
Dependency rule: everything depends inward on Core. Core depends only on Microsoft.Data.Sqlite and sqlite-vec.
| Pattern | Where | Why |
|---|---|---|
| 5-Layer RRF Fusion | Resume + JD extraction | Structural + NER + Taxonomy + LLM + Entity Lookup vote, best candidate wins |
| Skill Taxonomy | Matching module | 19,983 skills from 1.3M LinkedIn jobs — cross-industry, not just tech |
| Entity Lookup | JD parser | 11K companies + 7K locations from LinkedIn/Adzuna validate NER candidates |
| Skill Ledger | Matching module | Every skill backed by evidence with provenance |
| Skill Graph + Communities | Career planner | Leiden community detection with UMAP visualisation |
| Template Learning | DOCX parser | First parse learns structure, subsequent parses are deterministic |
| ATS Pattern Detection | PDF parser | YAML rulesets identify resume templates/ATS systems |
dotnet test lucidRESUME.sln # 479 tests across 12 projects
| Project | Tests | Coverage |
|---|---|---|
| Core.Tests | 101 | Persistence, models, reviewed transcript overlays, multi-resume, export, linked posts |
| Extraction.Tests | 25 | NER, recognizers, RRF fusion pipeline |
| AI.Tests | 46 | Providers, embeddings, bounded decisions, deterministic projection, gated live OpenAI checks |
| Matching.Tests | 64 | Skill scoring, filters, voting, job-search resilience, projection quality |
| JobSpec.Tests | 16 | JD parsing, deterministic flattened-title extraction, salary extraction |
| EmailTracker.Tests | 25 | Classifier, matcher |
| GitHub.Tests | 44 | Language map, repository assessment, package families, LinkedIn parsing, reviewed document merge |
| JobML.Tests | 29 | Parsing, validation, drift, reversible links, cJobML projection |
| Compiler.Tests | 24 | Deterministic evidence selection, compact chronology and projection orchestration |
| Web.Tests | 5 | ASP.NET Core endpoint and projection control |
| App.Tests | 2 | Native operating-system credential storage |
| Avalonia.UITesting.Tests | 98 | Input, scripts, locators, screenshots, REPL |
The Chrome evidence filler has a separate TypeScript suite:
cd extensions/lucidresume-chrome
npm ci && npm run check && npm test && npm run build
The UI automation layer is published as a standalone NuGet package — Mostlylucid.Avalonia.UITesting — so any Avalonia desktop app can use it. Real pointer/touch/wheel/gesture input via Avalonia's IInputManager, region/control snipping for manuals, YAML scripts, GIF video, REPL, and an MCP server. Source lives in src/Mostlylucid.Avalonia.UITesting/.
# Run a YAML test script
dotnet run --project src/lucidRESUME/lucidRESUME.csproj -- \
--ux-test --script ux-scripts/e2e-full-flow.yaml --output ux-screenshots
# Interactive REPL
dotnet run --project src/lucidRESUME/lucidRESUME.csproj -- --ux-repl
# MCP server (for LLM-driven UI control)
dotnet run --project src/lucidRESUME/lucidRESUME.csproj -- --ux-mcp
PRs welcome. Run the tests before submitting:
dotnet test
The codebase follows a strict inward dependency rule - keep domain logic in Core and wire everything in the app shell.
This is free and unencumbered software released into the public domain. See LICENSE or unlicense.org for details.
No strings attached. No attribution required. Use it however you like.
0 followers · starred Aug 2026
C#
96.4%
TypeScript
2.4%