An open-core job-application pipeline. Discovery → scoring → materials → verification → launch packets — with honest automation as the product: it only ever claims what you tell it is true.
Keel is the public half of a real production pipeline that holds 208 verified submissions in its ledger (ledger-verified, as of 2026-09-23) using this exact discipline: fit scoring, truthfulness gates, clean-form checks, and fail-closed handling. The execution layer (how applications are actually submitted) stays private by design — publishing submission fingerprints would get the pipeline blocked by ATS vendors. See SPLIT.md.
Live terminal demo on sample data (22s): fit scoring, prescreen gates, and the ATS capability radar refusing a board it can't reach honestly.
⭐ If the honest-automation contract resonates, star the repo — it's the fastest way to help other builders find Keel.
- Discovery — search query playbooks and sweep prompts for finding real
postings in your target lanes (
engines/discovery_queries.md,engines/sweep_worker_prompt.md). - Scoring — a 100-point fit model with a banded action policy
(
engines/fit-scoring-model.md,engines/score_roles.py). - Materials — truthful resume tailoring from your verified profile
(
engines/resume_tailor.py,engines/cover_letter_generator.md). - Answer bank — your canonical form answers + banded-question rules +
hard gates. The single source of truth; the pipeline never invents what is
not in it (
engines/answer_bank.example.json). - Prescreen — pre-launch packet screening: office/relocation/travel
commitments, essays, attestations, and unmappable required questions get
PARKED to your input queue, never invented (
engines/prescreen.py). - ATS detection — platform identification and a capability radar that
probes whether direct submission is viable (
engines/ats.py,engines/edge_probe.py,engines/api_direct_detect.py). - Apply loop — builds launch packets for eligible READY leads: verified
form values, banded rules, hard gates, and the per-field verification
protocol, with a documented EXECUTOR CONTRACT for your submission layer
(
engines/apply_loop.py). - Verification retry — records posting-presence observations from public
board APIs without promoting READY or inferring death from missing evidence.
Budget-deferred work keeps its turn (
engines/verify_retry.py). - Telemetry & analytics — append-only event log, outcome analytics with
fail-closed reporting rules, employer-response intake via a pluggable mail
source (
engines/log_event.py,engines/outcome_analytics.py,engines/inbox_listener.py). - Dashboard — self-contained HTML dashboard from ledger + queues
(
engines/build_dashboard.py).
The 0.5.1 optimization pass reduces repeated board reads and cache eviction work, preserves unattempted work under request limits, and hardens uncertain broker outcomes and rate-limit handling. See the reproducible measurements and security boundaries.
The productivity controller connects those public runtime paths to a shared
resource budget. Inspect with productivity-status, then use productivity-once
to plan or run one bounded stage. It records committed progress, retains replay
protection and pauses intake when existing work needs attention. See the
operator instructions and measurement limits.
Version 0.6.1 adds indexed replay history, fixed trial cohorts and an exact-attempt receipt projection interface for qualified hosts. See the sustained operation guide for setup, comparisons and migration limits.
Version 0.6.2 adds host-preflight, a synthetic controller rehearsal, read-only
budget inspection and recovery fixes. The host handoff
separates observed local checks from live deployment and provider qualification.
Version 0.6.3 adds productivity-advice and actual-controller process-crash
qualification. The evidence loop guide explains measured
bottlenecks, conservative follow-up budgets and the five restart boundaries.
- Keel never submits an application. The public loop stops at the launch packet: a verified, prescreened bundle (form values, banded rules, hard gates, per-field verification protocol) plus a documented EXECUTOR CONTRACT for whatever submission layer you attach. Managed execution is the hosted tier — keeping it private also protects it from ATS fingerprinting at scale.
- Keel never invents qualifications. Anything your profile can't support is reported as a gap, never bridged with fiction.
- Keel promises no submissions. The public repo is the discipline and the tools. The private production pipeline that proved the discipline works holds 208 verified submissions as of 2026-09-23 — counted from its ledger under the docs/geo/stats.json methodology (201 evidenced / 1 pointer / 0 url-only / 6 unevidenced), never estimated. See the honesty report for the evidence-graded count and its methodology, and the comparison with auto-apply bots.
Real terminal session (synthetic data, real engines): an unmapped question
is reported instead of invented, an unverifiable posting parks, and a
submission counts only on explicit confirmation. Run it yourself:
python3 demo/honesty_gates_demo.py. See also demo/.
From the v0.2.0 release zip — or a clone
(git clone https://github.com/KeelDev-tech/keel && cd keel):
./setup.sh # "Make it mine" — personalizes your working copy
# (non-interactive shells skip the prompts; edit data/
# with YOUR truth afterward)
# edit data/applicant_profile.json and data/answer_bank.json with YOUR truth
./start.sh # status overviewThen (run from the workspace root):
KEEL_HOME=$PWD python3 engines/score_roles.py --in sample_data/discovered_roles.example.json --out data/scored.json
python3 -m unittest discover -s tests # run the test suiteTo watch the full loop end-to-end on demo data, seed one scored lead into
the queue and build its launch packet. (The sample roles score SKIP under
the template rubric — its lane weights are yours to fill — so the demo
forces the top-scoring one to READY/APPLY with a placeholder resume, purely
to show the packet mechanics. apply_loop makes read-only HTTP
liveness/form-intel probes as documented.)
KEEL_HOME=$PWD python3 - <<'EOF'
import json, os
home = os.environ["KEEL_HOME"]
scored = json.load(open(f"{home}/data/scored.json"))
rows = scored if isinstance(scored, list) else scored.get("entries", [])
lead = max(rows, key=lambda r: r.get("fit_score", 0))
lead["status"] = "READY" # demo override: scoring said SKIP
lead["action_band"] = "APPLY" # demo override
os.makedirs(f"{home}/data/resumes", exist_ok=True)
open(f"{home}/data/resumes/demo-resume.pdf", "w").write("demo placeholder")
lead["materials"] = {"resume": "data/resumes/demo-resume.pdf"}
json.dump({"entries": [lead]},
open(f"{home}/data/queues/standard-queue.json", "w"), indent=2)
print("seeded", lead["role_id"])
EOF
KEEL_HOME=$PWD python3 engines/apply_loop.py # build one launch packet
KEEL_HOME=$PWD python3 engines/build_dashboard.py # render the dashboarddata/launch-packets/<role_id>.json is the finished product: verified form
values, banded rules, hard gates, and the EXECUTOR CONTRACT your own
submission layer (browser automation, ATS APIs, or manual review) runs
behind. The dashboard renders at dashboard/dashboard.html.
Requirements: Python 3.10+ — stdlib only, no dependencies to install. CI runs the same suite on 3.10 / 3.11 / 3.12 (ci.yml).
Fresh-clone failure modes, from experience:
./setup.shor./start.shfails on a fresh clone. Run from the repo root (cd keelfirst) with Python 3.10+ onPATH(python3 --version). The scripts assume the working-tree layout and won't work from insideengines/.- The smoke suite fails. Run
python3 -m unittest discover -s testsfrom the repo root — the same command CI runs on 3.10 / 3.11 / 3.12. One red test names its module and line; read the engine's docstring contract before changing production code, since a new test can encode a superseded contract while the engine is right. - A module crashes on import with
ModuleNotFoundError. Tracked code must run from a clean clone with stdlib only (no pip installs). Engines must neversys.path.insertan absolute private-machine path at import time, and must degrade gracefully when a git-ignored helper is absent (e.g.build_dashboard.pyonce broke on clean clones becauseengines/safe_io.pywas missing). - The dashboard shows "Unknown" counts.
build_dashboard.pyrenders "Unknown" — never a healthy zero — when a source file is missing or malformed. Checkdata/application-ledger.json,data/queues/, and the warning banner at the top of the page.
- Truthfulness gates — hard requirements the profile can't support are reported as gaps, never bridged with fiction.
- Explicit confirmation — a submission counts only on explicit confirmation evidence. Nothing else.
- Fail closed — unverifiable postings, unmappable required questions, missing attestations: park, never proceed.
- No fingerprinting surface — nothing in this repo helps ATS vendors identify or block automated applications (see SPLIT.md).
Keel is a flat engines/ package of small, single-purpose modules —
discovery, scoring, materials, prescreen, ATS detection, the apply loop,
verification retry, telemetry, and the dashboard builder — wired together by
keel_paths.py (home-directory resolution) and guarded by the
honest-automation contract above. Two files define the project's shape:
- docs/ARCHITECTURE.md — the full system picture: module map, data flow, queue/ledger conventions, extension points.
- SPLIT.md — the open-core boundary: exactly what is public, what stays private, and why.
Start with docs/PERSONALIZE.md to make a copy yours.
engines/ all pipeline modules (flat package)
tests/ acceptance tests
docs/ architecture, personalization, contributing
docs/assets/ wordmark, social preview, dashboard screenshot
sample_data/ sanitized examples (never real applications)
launch/ launch drafts (Show HN, thread, talking points)
dist/ built zips (from ./package.sh)
See CONTRIBUTING.md for the full contributor guide (the technical ground rules also live in docs/CONTRIBUTING.md). Bug reports and feature requests live under .github/ISSUE_TEMPLATE/; security reports go through GitHub Security Advisories — see SECURITY.md. Changes are tracked in CHANGELOG.md.
Machine-readable canon for language models: llms.txt (short) and llms-full.txt (full). Citation-ready Q&A docs live in docs/geo/ — FAQ, honest-automation explainer, comparison, alternatives, stats — plus a machine-readable stats snapshot and releases feed. The Pages site (https://keeldev-tech.github.io/keel/) serves the same files with JSON-LD structured data.
Apache-2.0 — see LICENSE.
QRESOLVE retrieves evidence-backed answers for the question tray, with factual reuse off by default. See question resolution for local commands, authorization and recovery behavior.



