The Problem

Job applications today are a manual, browser-bound chore. You fill out the same fields a hundred times, solve CAPTCHAs that prove you’re human (but waste your time), upload the same PDF to every portal, and wait. The process assumes a human on both sides.

But what if neither side needs to be human at the application stage?

The headhunter-agent project already eliminates the browser on the candidate side: it’s a native Clojure/JavaFX desktop app that evaluates job postings, profiles candidates, and generates tailored PDFs — all without a web browser. The missing piece was an employer-facing protocol that closes the loop: machine-readable job postings, automated discovery, and signed application submission.

This post describes the M2M Job Application Protocol v1.0.0: a full-stack protocol for machine-to-machine recruiting, designed as an extension to headhunter-agent.

System Context

The protocol connects four actors:

Architecture Diagram

The Four Sub-Protocols

The M2M protocol decomposes into four sub-protocols that execute in sequence:

Architecture Diagram

1. Discovery — DNS TXT Records

No central registry. No API keys. No sign-ups.

Employers publish a single DNS TXT record on their domain:

Architecture Diagram

The TXT record format is intentionally simple:

Architecture Diagram

A Babashka fallback directory service aggregates known endpoints for discovery when DNS is unavailable:

Architecture Diagram

2. Fetch — Machine-Readable Job Postings

Employers serve job postings as JSON-LD over HTTPS. The schema extends schema.org/JobPosting with M2M-specific fields for protocol metadata:

Architecture Diagram

The JSON-LD posting carries everything a machine needs: title, description, skills, compensation range, and crucially, the application endpoint and employer public key.

Architecture Diagram

3. Verify — Cryptographic Handshake

Every participant generates an Ed25519 keypair. No CA hierarchy, no certificate authorities. Trust is established through DNS binding:

Architecture Diagram

Applications are signed at two levels:

Architecture Diagram
  1. Envelope signature: canonical JSON of the entire package (minus the signature field) is signed with Ed25519
  2. Attachment signature: each file’s SHA-256 digest is independently signed, enabling individual file verification
Architecture Diagram

4. Submit — Signed Application Delivery

The signed package is delivered as a multipart HTTP POST:

Architecture Diagram

The employer responds with a signed acknowledgment:

Architecture Diagram

Full Data Flow

Here’s the complete flow from discovery to submission:

Architecture Diagram

Protocol Stack

Architecture Diagram

Application Lifecycle State Machine

Architecture Diagram

Implementation Architecture

The protocol is implemented as eight Clojure namespaces under career-ops.m2m, extending the existing headhunter-agent:

Architecture Diagram

Each namespace has a single responsibility:

Module File Lines Responsibility
core core.clj 159 CLI routing for bb m2m {keygen,discover,fetch,apply,verify,serve}
crypto crypto.clj 133 Ed25519 key generation, signing, verification, SHA-256 digests, canonical JSON
schema schema.clj 106 JSON-LD @context, structural validation for all message types
registry registry.clj 85 DNS TXT lookup + HTTP directory fallback
fetch fetch.clj 66 Job posting HTTP fetcher with schema validation
submit submit.clj 91 Application package assembly, attachment signing, multipart POST
verify verify.clj 82 Inbound envelope + attachment signature verification
directory directory.clj 76 Optional Babashka HTTP directory aggregator server

CLI Usage

The protocol is exposed through a unified CLI:

Architecture Diagram

The bb m2m apply command chains the entire pipeline:

  1. Discover — DNS lookup for employer endpoint
  2. Fetch — HTTP GET for JSON-LD job posting
  3. Evaluate — Existing 3-stage MAS pipeline (legitimacy, fit, cheat sheet)
  4. Tailor — Gemini-powered resume tailoring, compiled via Typst
  5. Sign — Ed25519 signature on package + attachment digests
  6. Submit — Multipart POST to employer endpoint
  7. Acknowledge — Verify employer’s signed receipt

Security Model

Architecture Diagram
Threat Mitigation
Employer impersonation DNS TXT binds public key to domain; TLS validates transport
Candidate impersonation Ed25519 signature on every application envelope
Replay attack Timestamps + server-enforced freshness window
Tampered resume Per-attachment SHA-256 digest + independent Ed25519 signature
Man-in-the-middle TLS 1.3 for all HTTP; signatures provide end-to-end integrity
Registry poisoning Directory entries are signed; primary discovery is DNS (DNSSEC-ready)

No-CAPTCHA Guarantee

The protocol explicitly eliminates all human verification:

Architecture Diagram

Protocol Extension Points

Architecture Diagram

Integration with headhunter-agent

The protocol extends the existing project without breaking any existing functionality:

Architecture Diagram

The existing MAS pipeline (Legitimacy check → Fit Analysis → Cheat Sheet) remains unchanged. The M2M module calls it as a step in the apply workflow, then adds signing and submission on top.

Implementation Roadmap

The protocol is designed for incremental delivery:

Architecture Diagram
Phase Components Dependency
P0 crypto.clj, schema.clj, core.clj (keygen + verify) None
P1 registry.clj (DNS), fetch.clj P0
P2 submit.clj, verify.clj P0, P1
P3 directory.clj P0
P4 Full bb m2m apply with MAS pipeline P0-P3
P5 Employer-side verification library P0, P2

The Bigger Picture

The M2M Job Application Protocol is a small piece of a larger vision: moving all white-collar recruiting from human-mediated workflows to autonomous agent coordination.

The protocol is:

The specification and implementation are part of the headhunter-agent project, which is MIT-licensed open source.

For the full protocol specification, including detailed message formats, schema definitions, and the complete Clojure implementation, see the repository at gitlab.com/nurazhar/headhunter-agent.

Architecture Diagram