You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
docs: refresh README + architecture + ADR index for Tier 1/2 + themes
Sync the doc surface to the last several days of commits:
- root README: 12 résumé themes (was "two"), hybrid Tier 1/2 job
search, 31 ADRs (was 27), 74 test files (was 61), corrected
active board counts
- architecture.md: 12-theme ThemeSpec registry, cached_jobs
embedding column + the hybrid search RPC
- adr/README.md: index ADR-032, refresh the current-state note
- deployment.md: embed-on-write spends a little on embeddings (the
flat "$0" claim was stale); new operational-gotcha entry for the
embed-on-write HNSW churn incident
- docs/README.md: catalog the two Tier 2 SQL migration files
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Copy file name to clipboardExpand all lines: README.md
+6-6Lines changed: 6 additions & 6 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -30,11 +30,11 @@
30
30
31
31
| System | What it does |
32
32
|--------|--------------|
33
-
|**Live job search**| Cached index of ~12,000 open roles from Greenhouse, Lever, Ashby, and Workday — refreshed every 4 hours. Filter by company, work mode, role type, posted-within. Sort by relevance, recency, or alphabetical. |
33
+
|**Live job search**| Cached index of ~14,000 open roles from Greenhouse, Lever, Ashby, and Workday — refreshed every 4 hours. Hybrid relevance ranking fuses Postgres full-text search (with deterministic synonym / abbreviation expansion) and pgvector semantic similarity. Filter by company, work mode, role type, posted-within. Sort by relevance, recency, or alphabetical. |
34
34
|**Resume intake**| Upload PDF / DOCX / TXT, or chat one into existence with the conversational builder. Parsed into a normalized profile with skills, experience timeline, projects, publications, and certifications. |
35
35
|**JD review**| LLM-first JD parser with regex fallback. Surfaces hard skills, soft skills, and must-haves; shows match score against the loaded resume. |
36
36
|**Supervised pipeline**| Matchmaker → Forge (tailoring) → Gatekeeper (review) → Resume Generation → Cover Letter. Three-layer LLM retry stack with per-agent fallback isolation, deterministic floor on every stage. |
37
-
|**Artifact export**|Two themes (`classic_ats` for ATS parsers, `professional_neutral` for human readers) in DOCX or PDF. The same source data feeds either pathway. |
37
+
|**Artifact export**|12 résumé themes — 6 single-column (ATS-safe) + 6 bespoke two-column layouts, all from one typed `ThemeSpec` registry — in DOCX or PDF, with a matching cover letter. The same source data feeds either pathway. |
38
38
|**Grounded assistant**| Floating workspace chat with full context of the loaded resume, JD, analysis state, and saved jobs. Streams answers as they generate. |
39
39
|**Command palette**|`⌘K` / `Ctrl+K` from anywhere — jump between steps, load a saved job, re-ask a recent assistant question, or run the analysis. |
40
40
|**Tier enforcement**| Per-(user, period, counter) atomic quota gates on every gated action (tailored applications, premium applications, assistant turns, resume parses, resume-builder sessions, job searches, saved jobs, saved workspaces). Free / Pro / Business cap matrix. Premium opt-in routes review + resume-gen + cover-letter to `gpt-5.5` while keeping tailoring on mini for COGS reasons. Refund-on-failure so a transient workflow error doesn't burn a credit. |
@@ -45,9 +45,9 @@
45
45
46
46
The cached jobs layer lives in Postgres (`cached_jobs` table) and is refreshed by a scheduled worker that fans out across all four sources. Highlights:
47
47
48
-
-**~117 Greenhouse boards** + **30 Lever sites** + **36 Ashby boards** + **11 Workday Fortune-500 tenants** in the active source pool.
48
+
-**79 Greenhouse boards** + **6 Lever sites** + **36 Ashby boards** + **11 Workday Fortune-500 tenants** in the active source pool.
49
49
-**4-hour refresh cadence** via `pg_net` cron triggering the `/admin/refresh-cache` endpoint (6 refreshes per day at 00:00 / 04:00 / 08:00 / 12:00 / 16:00 / 20:00 UTC).
50
-
-**Relevance-ranked search**through a Postgres RPC that combines query token coverage with recency.
50
+
-**Hybrid relevance ranking**— a Postgres RPC fuses lexical full-text search (with deterministic synonym / abbreviation query expansion) and pgvector semantic similarity via Reciprocal Rank Fusion, so a role surfaces whether it matches on keywords or on meaning. Gracefully degrades to pure lexical if the semantic side is unavailable.
51
51
-**Saved-jobs drawer** with a 24-hour TTL — bookmarks survive page reloads but expire if you don't act on them, with an `EXPIRED` badge so nothing silently disappears.
52
52
53
53
See [ADR-013](docs/adr/ADR-013-cached-jobs-cache-layer-with-scheduled-refresh.md) and [ADR-014](docs/adr/ADR-014-postgres-rpc-for-ranked-search.md) for the load-bearing decisions.
@@ -74,10 +74,10 @@ Each agent follows the same operating shape: deterministic baseline first, LLM-a
74
74
75
75
## Engineering notes
76
76
77
-
-**61 Python test files** cover parsing, normalization, fitting, tailoring, orchestration, builders, exports, auth, quotas, persistence, the Lemon Squeezy webhook, voice transcription, artifact feedback, prompt-registry byte-identity, error handling, and the four ATS adapters.
77
+
-**74 Python test files** cover parsing, normalization, fitting, tailoring, orchestration, builders, exports, auth, quotas, persistence, the Lemon Squeezy webhook, voice transcription, artifact feedback, prompt-registry byte-identity, error handling, hybrid job search, and the four ATS adapters.
78
78
-**Quality runners** in `tests/quality/` produce evidence for each LLM-driven stage (parser, tailoring, review, resume gen, cover letter, assistant, JD parser, latency baseline). `backend/nightly_eval.py` wraps them into a single regression-checked batch — manual-only at pre-revenue stage by design, see [ADR-026](docs/adr/ADR-026-manual-only-nightly-eval-at-pre-revenue-stage.md).
79
79
-**Every LLM prompt loads from a versioned JSON registry** (`prompts/<name>/v1.json`) — all 11 builders migrated off Python f-string concats, each guarded by a byte-identity test so a template can't silently drift from its original.
80
-
-**27 ADRs** in `docs/adr/` record the architectural decisions, including the Streamlit-first → Next.js + FastAPI transition (ADR-012), DOCX-first export (ADR-015), conversational builder (ADR-016), state-aware assistant (ADR-017), three-layer retry stack (ADR-018), independent step navigation (ADR-019), tier resolution shim (ADR-020), atomic quota with refund (ADR-021), tier-aware model selection (ADR-022), Lemon Squeezy as Merchant of Record for v1 (ADR-023), the observability stack (ADR-024), the EU cookie consent banner (ADR-025), manual-only nightly eval (ADR-026), and the tier-gated export entitlement (ADR-027).
80
+
-**31 ADRs** in `docs/adr/` record the architectural decisions, including the Streamlit-first → Next.js + FastAPI transition (ADR-012), DOCX-first export (ADR-015), conversational builder (ADR-016), state-aware assistant (ADR-017), three-layer retry stack (ADR-018), independent step navigation (ADR-019), tier resolution shim (ADR-020), atomic quota with refund (ADR-021), tier-aware model selection (ADR-022), Lemon Squeezy as Merchant of Record for v1 (ADR-023), the observability stack (ADR-024), the EU cookie consent banner (ADR-025), manual-only nightly eval (ADR-026), the tier-gated export entitlement (ADR-027), LLM provider failover + premium reasoning tier (ADR-028), the single-source `ThemeSpec` registry (ADR-029), the résumé-builder agentic architecture (ADR-031), and the six bespoke two-column résumé themes (ADR-032).
81
81
-**Architecture details** live in [docs/architecture.md](docs/architecture.md); the day-2 operational runbook in [docs/deployment.md](docs/deployment.md).
|`docs/sql/supabase-cached-jobs-search.sql`|`search_cached_jobs_ranked` RPC: text-search + filters + sort + `LIMIT`/`OFFSET` pagination over `cached_jobs`. Was untracked (DB-only); now the source of truth. **service_role-only** EXECUTE — the REVOKEs are part of the canonical definition |
52
+
|`docs/sql/supabase-cached-jobs-search.sql`|`search_cached_jobs_ranked` RPC: text-search + filters + sort + `LIMIT`/`OFFSET` pagination over `cached_jobs` (Tier 1 lexical search). **service_role-only** EXECUTE — the REVOKEs are part of the canonical definition |
53
+
|`docs/sql/supabase-cached-jobs-pgvector.sql`| Tier 2 semantic-search schema: the `vector` extension, the `cached_jobs.embedding vector(1536)` column, and the HNSW cosine index |
54
+
|`docs/sql/supabase-cached-jobs-hybrid.sql`|`search_cached_jobs_hybrid` RPC: Reciprocal Rank Fusion of the Tier 1 lexical ranking and a pgvector semantic ranking (HNSW candidate pools). **service_role-only** EXECUTE |
53
55
|`docs/sql/job_cache_cron_setup.sql`|**Template, not source of truth.** The `cached_jobs` refresh pg_cron schedule. Defaults to `*/30`; production runs `0 */4`. `SELECT jobname, schedule FROM cron.job;` is authoritative |
54
56
55
57
Update trigger: only when a new migration lands. Old `.sql` files are append-only.
Copy file name to clipboardExpand all lines: docs/adr/README.md
+3-2Lines changed: 3 additions & 2 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -20,7 +20,8 @@ The accepted set is grouped into four thematic clusters to make the current prod
20
20
-[ADR-013: Cached jobs cache layer with scheduled refresh](ADR-013-cached-jobs-cache-layer-with-scheduled-refresh.md)
21
21
-[ADR-014: Postgres RPC for ranked job search](ADR-014-postgres-rpc-for-ranked-search.md)
22
22
-[ADR-015: DOCX-first artifact export with theme palette](ADR-015-docx-first-artifact-export-with-theme-palette.md)
23
-
-[ADR-029: ThemeSpec single-source + color-theme expansion](ADR-029-themespec-single-source-and-color-theme-expansion.md) — realises ADR-015's typed-`ThemeSpec` follow-up; one registry derives résumé + cover-letter + DOCX palettes + the backend gate set; first new theme `modern_blue` (single-column, ATS-safe). Two-column "presentation" layout reserved for a later gated phase
23
+
-[ADR-029: ThemeSpec single-source + color-theme expansion](ADR-029-themespec-single-source-and-color-theme-expansion.md) — realises ADR-015's typed-`ThemeSpec` follow-up; one registry derives résumé + cover-letter + DOCX palettes + the backend gate set; first new theme `modern_blue` (single-column, ATS-safe). Two-column "presentation" layout reserved for a later gated phase — since realised by ADR-032
24
+
-[ADR-032: Six bespoke two-column résumé themes](ADR-032-two-column-resume-themes.md) — extends ADR-029's `ThemeSpec` registry with six distinct two-column résumé layouts via a `twocol_layout` discriminator, retiring the single placeholder `presentation_twocol` slot; the registry now ships 12 themes (6 single-column ATS-safe + 6 two-column)
-[ADR-031: Résumé-builder agentic architecture (tool-calling loop, promise tracking, silent-fallback discipline)](ADR-031-resume-builder-agentic-architecture.md) — extends ADR-016 from form-filler to tool-using agent: `fetch_github_readme` + `web_search` (function-wrapped to sidestep OpenAI's JSON-mode incompatibility), full conversation history with char-budget guard, `proactive_offer` channel, `pending_followups[]` promise tracking, schema-strictness + registry pact-tests against the silent-fallback antipattern that surfaced twice this slice
26
27
-[ADR-017: Workspace assistant — ungated and state-aware context](ADR-017-workspace-assistant-state-aware-context.md)
@@ -56,7 +57,7 @@ The accepted set is grouped into four thematic clusters to make the current prod
56
57
57
58
## Current state note
58
59
59
-
As of 2026-05-17, the shipped product is a Next.js workspace deployed on Vercel backed by a FastAPI container on a Frankfurt VPS, with a Supabase EU project for Auth + persistence + the cached-jobs index. The agentic workflow runs Tailoring → Review → ResumeGen → CoverLetter on every analysis, with per-agent retry + fallback isolation. Tier enforcement is live across eight counters (Free / Pro / Business) with the Lemon Squeezy payment scaffold env-gated behind a "Coming soon" frontend fallback until the dashboard's final variant IDs land; export format/theme is additionally an entitlement gate (Free = PDF + `professional_neutral`, which is also the product-wide default theme; Pro/Business unlock DOCX + every non-default theme by exclusion — `classic_ats`, `modern_blue`, `creative_warm`, `architect_mono` (all single-column, ATS-safe) + the gated non-ATS two-column `presentation_twocol`) enforced server-side via the same 429 upgrade path (ADR-027). Theming is one typed `ThemeSpec` registry (ADR-029) deriving the résumé, cover-letter, and DOCX palettes plus the backend supported-theme set; its `layout` discriminator drives the single- vs two-column résumé renderer, so adding a theme is one registry entry. The observability stack (Sentry `jobagent-backend` + `jobagent-frontend` + a shared PostHog free-tier project tagged with `product: "jobagent"`) is wired with a custom EU cookie consent banner gating PostHog + Sentry Session Replay behind explicit user opt-in; consent persists in a parent-domain cookie so it is honoured across the marketing apex and the `app.` subdomain. `backend/nightly_eval.py` exists and is tested but is **not** on the production cron at pre-revenue stage — re-enabling is a single crontab edit when revenue justifies the recurring LLM spend.
60
+
As of 2026-05-22, the shipped product is a Next.js workspace deployed on Vercel backed by a FastAPI container on a Frankfurt VPS, with a Supabase EU project for Auth + persistence + the cached-jobs index. The agentic workflow runs Tailoring → Review → ResumeGen → CoverLetter on every analysis, with per-agent retry + fallback isolation. Tier enforcement is live across eight counters (Free / Pro / Business) with the Lemon Squeezy payment scaffold env-gated behind a "Coming soon" frontend fallback until the dashboard's final variant IDs land; export format/theme is additionally an entitlement gate (Free = PDF + `professional_neutral`, which is also the product-wide default theme; Pro/Business unlock DOCX + every non-default theme) enforced server-side via the same 429 upgrade path (ADR-027). Theming is one typed `ThemeSpec` registry (ADR-029, ADR-032) deriving the résumé, cover-letter, and DOCX palettes plus the backend supported-theme set; it ships 12 themes — 6 single-column (ATS-safe) and 6 two-column — and its `layout` / `twocol_layout` discriminators drive the renderer, so adding a theme is one registry entry. The observability stack (Sentry `jobagent-backend` + `jobagent-frontend` + a shared PostHog free-tier project tagged with `product: "jobagent"`) is wired with a custom EU cookie consent banner gating PostHog + Sentry Session Replay behind explicit user opt-in; consent persists in a parent-domain cookie so it is honoured across the marketing apex and the `app.` subdomain. `backend/nightly_eval.py` exists and is tested but is **not** on the production cron at pre-revenue stage — re-enabling is a single crontab edit when revenue justifies the recurring LLM spend.
0 commit comments