-
Notifications
You must be signed in to change notification settings - Fork 0
Pipeline Steps & Run Orchestration
Relevant source files
- src-tauri/src/pipeline/steps.rs
- src-tauri/src/worker.rs
- src/lib/pipeline.test.ts
- src/lib/pipeline.ts
- src/lib/styles/layout/roles.css
- src/lib/styles/layout/workspace.css
The pipeline orchestration system manages the lifecycle of automated job discovery, data extraction, and fit analysis. It implements a "queue tasks ARE the steps" model where each stage of a pipeline run is a durable, retryable unit of work persisted in a SQLite-backed queue. This design ensures that failures in late stages (e.g., LLM analysis) do not require re-executing expensive upstream work (e.g., web scraping).
The pipeline is driven by a pump_once execution loop. In production, a background worker thread (Task-6) continuously calls pump_once until the queue is empty.
- Claim: The loop claims the next pending task from the
SqliteQueuesrc-tauri/src/pipeline/steps.rs#15-17 - Dispatch: The task is matched to a specific execution handler based on its
stagename src-tauri/src/pipeline/steps.rs#14-17 - Telemetry: Before execution,
step_startedis emitted to theEventSink. After execution, the outcome is recorded in the vault as aChecknote andstep_doneis emitted src-tauri/src/pipeline/steps.rs#65-70 - Handoff: On success, the handler typically enqueues the next task in the chain, passing its output as the next task's payload src-tauri/src/pipeline/steps.rs#1-5
The following diagram bridges the logical pipeline concepts to the Rust functions and structures that implement them.
Title: Pipeline Run Orchestration
flowchart LR
subgraph subGraph2 ["Step Chains"]
D1["careers-scrape"]
D2["structure-listings"]
D3["finalize"]
J1["jd-scrape"]
J2["structure-jd"]
J3["gap-detect"]
J4["research-gaps"]
S1["fit-score"]
S2["alignment"]
end
subgraph subGraph1 ["Worker Thread"]
P["pump_once()"]
T["QueuedTask"]
D["dispatch()"]
V["Vault: checks/*.md"]
S["EventSink (TauriSink)"]
end
subgraph subGraph0 ["Entrypoints (Tauri Commands)"]
A["fetch_jobs_for_company()"]
Q["SqliteQueue"]
B["fetch_job_details()"]
C["rescore_job()"]
end
P --> T
P --> D
D --> V
D --> S
D --> D1
D1 --> D2
D2 --> D3
D --> J1
J1 --> J2
J2 --> J3
J3 --> J4
D --> S1
S1 --> S2
J3 --> S1
A --> Q
B --> Q
C --> Q
Sources: src-tauri/src/pipeline/steps.rs#1-26src-tauri/src/worker.rs#91-112src-tauri/src/worker.rs#121-157
The discovery chain is used to find new job listings from a company's careers page. It is initiated via start_discoverysrc-tauri/src/pipeline/steps.rs#108
| Step | Function/Logic | Data Flow |
|---|---|---|
| careers-scrape | run_scrape_step |
Scrapes the careers_url. Returns sanitized HTML. |
| structure-listings | build_structure_listings_prompt |
LLM extracts a list of RawListing objects from HTML. |
| finalize | prefilter |
Filters listings by title/URL; writes new Job stubs to the vault. |
Scrape Failure Policy:
-
Terminal(e.g., 404): Task marked dead immediately src-tauri/src/pipeline/steps.rs#21 -
FixEncoding: Retries once with a percent-encoded URL src-tauri/src/pipeline/steps.rs#22 -
EscalateProxy: Re-enqueues usingProxyTier::Stealth(75 credits) src-tauri/src/pipeline/steps.rs#23-24
Sources: src-tauri/src/pipeline/steps.rs#11-13src-tauri/src/pipeline/steps.rs#19-26src-tauri/src/pipeline/steps.rs#98-108
When a user requests details for specific roles, the system executes two distinct runs: job_detail followed by an automatic handoff to job_scoring.
This chain focuses on extracting the full context of a single job.
- jd-scrape: Fetches the full job description page src/lib/pipeline.ts#10
- structure-jd: Uses LLM to parse the JD into structured fields (skills, comp, stack) src/lib/pipeline.ts#11
- gap-detect: Inspects the
Jobstruct for missingRESEARCHABLE_FIELDSsrc-tauri/src/pipeline/steps.rs#39 - research-gaps: (Conditional) If gaps exist, performs a web-search-enabled LLM step to fill them src/lib/pipeline.ts#13
Once the JD is structured, the pipeline transitions to analysis.
- fit-score: Executes the
fit::score_fitengine against the user'sTargetCriteriasrc-tauri/src/pipeline/steps.rs#144-148 - alignment: Generates a natural language narrative explaining the fit scores src-tauri/src/pipeline/steps.rs#44-49
When the job_detail run completes successfully, the finalize_job_detail step automatically triggers start_rescore_runsrc-tauri/src/worker.rs#13-16 This creates a new run ID but maintains the same subject (the job slug), allowing the UI to show a continuous progress strip src-tauri/src/worker.rs#29-40
Title: Detail to Scoring Handoff
sequenceDiagram
participant Q as SqliteQueue
participant P as pump_once
participant V as Vault (Job Note)
participant E as EventSink
P->>P: Execute gap-detect/research-gaps
P->>V: update_job_field (Finalize Detail)
Note over P: Detail Run Complete
P->>Q: start_rescore_run(job_slug)
Q-->>P: New Run ID (job_scoring)
P->>E: run_finished(detail_run | "complete")
P->>Q: claim_next(fit-score)
P->>E: step_started(scoring_run | "fit-score")
Sources: src-tauri/src/pipeline/steps.rs#1-9src-tauri/src/worker.rs#31-40src/lib/pipeline.ts#5-17
The system supports both manual and system-driven cancellations.
- abort_running_runs: Used during worker crashes or fatal errors. It marks all tasks for a given set of
run_idsas discarded in theSqliteQueueand updates theCheckstatus to "failed" src-tauri/src/pipeline/steps.rs#144-152 - cancel_run: A Tauri command that adds a
run_idto a sharedHashSet<String>. Thepump_onceloop checks this set via theis_cancelledclosure before starting any step src-tauri/src/worker.rs#26-27src-tauri/src/worker.rs#134-135 - abort_set: A helper that identifies all runs related to a subject (e.g., if a detail run fails, the pending scoring run is also aborted) src-tauri/src/worker.rs#143-144
Sources: src-tauri/src/worker.rs#136-156src-tauri/src/pipeline/steps.rs#143-145src/lib/pipeline.ts#56-59
The EventSink trait abstracts the delivery of live progress updates.
- TauriSink: The production implementation. It uses
app.emitto sendrun:stepandrun:finishedevents to the Svelte frontend src-tauri/src/worker.rs#44-47 - StepEvent Payload: Includes
run_id,subject(job or company slug),stage, andstatus. Thedetailfield is used for sub-phase info like "stealth" proxy retries src-tauri/src/worker.rs#29-40 - Frontend Display: The
phaseLabelfunction in TypeScript maps these internal stage names to human-readable strings (e.g.,structure-jd→ "Reading the JD…") src/lib/pipeline.ts#92-114
Sources: src-tauri/src/pipeline/steps.rs#62-70src-tauri/src/worker.rs#48-89src/lib/pipeline.ts#62-84