Rust Developer (AI-First)
Backend developer position. Build high-performance services and CLI tools in Rust with AI-assisted development.
To apply, fill out the form: https://docs.google.com/forms/d/1Q7Zl5fCf5TuaLxqf9DR3aI_bu3ye6WF8B82X4vXE7tc/viewform
The form includes a section for your test task submission. Your answer should be a link to a public GitHub repository. Read the task description below before filling out the form.
About the Position
We are looking for a Rust Developer who works AI-first: Claude, Cursor, Windsurf, or similar tools are your primary development instrument, not a fallback. You will build backend services and CLI tooling in Rust — first in sandbox projects under the guidance of engineers and AI capability leads, then on paid commercial projects with full responsibility for deadlines, quality, and deliverables.
Why Rust. Its compiler forces the AI agent to think through ownership, error handling, and edge cases before the code compiles. This drastically reduces the probability of runtime errors — though it does not eliminate them. That is what specifications and tests are for.
An engineer with AI knows why the code works — and can prove it through specifications, tests, and traceability. A vibe coder knows that it works, until it doesn’t. We hire engineers.
For details about how our internship works, check out our Internship Overview.
Learn more about our team at https://foreachpartners.com/.
How We Work
Our engineering philosophy is Parsimony-Driven Development (PDD) — every artifact, instruction, and line of code must justify its existence. If removing it introduces no ambiguity and loses no meaning, it should not be there.
We implement PDD through Specification-Driven Development (SDD) — specification precedes implementation. Before writing code, you formulate requirements, derive contracts, and only then implement. AI tools accelerate every stage but replace none.
SDD rests on four pillars: Traceability, DRY, Deterministic Enforcement, and Parsimony. You MUST read and understand these principles before starting the test task:
Required reading: Specification-Driven Development: Four Pillars
AI generates code. You are responsible for it. The competence we evaluate is not how fast you produce output — it is how well you verify correctness, enforce constraints, and catch what the model gets wrong. The operator owns the result, not the agent.
What You Will Do
- Build CLI tools and backend services in Rust using AI-assisted development
- Write specifications before code — API contracts, requirement annotations, test plans
- Enforce code quality through deterministic tooling (linters, validators, CI checks)
- Review and correct AI-generated code for correctness, safety, and performance
- Maintain traceability between requirements, code, and tests
What We’re Looking For
- AI Proficiency:
- Confident user of at least one AI IDE (Cursor, Windsurf, or Claude Code)
- Understanding of prompt engineering: how to structure instructions, provide context, and iterate on output
- Understanding of context engineering: what to include in the model’s context and what to leave out
- Ability to decompose tasks for AI and critically evaluate output
- Rust Foundations:
- Basic understanding of Rust (ownership, traits, error handling)
- Pet project experience is sufficient — deep expertise is not required
- Engineering Mindset:
- Understanding of why specifications matter
- Comfort with CLI tools, Git, and CI/CD basics
- Nice-to-Have:
- Experience with SQL, Docker, Linux CLI
- Familiarity with protobuf, OpenAPI, or JSON Schema
Why Apply?
- AI-First Culture: Work in a team where AI tools are the norm, not an experiment
- Structured Growth: Start in sandbox projects, prove your quality control skills, then move to paid commercial work
- Career Path: Outstanding interns transition to permanent roles with full engineering responsibility
Test Task
To apply, complete the test task below. This is how we evaluate your ability to work with AI tools on a real engineering problem.
You MUST use AI (Claude, Cursor, Windsurf, or similar) as your primary development tool. Manual coding without AI assistance is not what we’re evaluating.
Time budget: 4–6 hours with AI tools.
The Big Picture
You are building one piece of a larger SDD toolchain. Multiple interns across different specializations work on the same product:
- Rust service (your task) — scans codebases, computes traceability metrics, serves data via REST API
- Next.js dashboard — web interface consuming the API
- Flutter app — mobile interface consuming the API
- DevOps infrastructure — deploys and monitors the whole stack
All parts share a common API specification: SDD Navigator API · download YAML
SDD Navigator Service
Build a Rust HTTP service that scans a project codebase for @req annotations, cross-references them with requirements.yaml and tasks.yaml, computes coverage metrics, and serves results via the REST API defined in the SDD Navigator API spec.
Step 1: Write the specification first
Before writing any code, create a requirements.yaml for the service itself. Define at least 8 requirements covering: YAML parsing, annotation scanning across languages, coverage calculation, REST API endpoints, error handling, and self-hosting. Each requirement gets a unique ID (e.g., SCS-SCAN-001).
This file becomes the single source of truth for what the service does.
Each requirement MUST include a description field containing a MUST/SHOULD directive — a statement that can be verified. Example:
requirements:
- id: SCS-SCAN-001
title: Parse requirements.yaml
description: "Service MUST read requirements.yaml from the project root and validate that every entry contains id and title fields."
- id: SCS-SCAN-002
title: Scan @req annotations
description: "Scanner MUST find all @req annotations in .rs, .ts, .py, .js, .go files and classify each as impl or test based on file path."
Step 2: Implement the scanner core
The scanner reads a project directory and produces coverage data.
Input:
-
A
requirements.yamllisting requirements:requirements:
- id: FR-AUTH-001
title: User login
description: "System MUST authenticate users with email and password and return a signed JWT token."
- id: FR-AUTH-002
title: Password reset
description: "System MUST send a password reset email within 30 seconds of request." -
A
tasks.yamllisting work items linked to requirements:tasks:
- id: TASK-001
requirementId: FR-AUTH-001
title: Implement JWT login handler
status: done -
Source files with
@reqannotations in comments:/// @req FR-AUTH-001
fn login(credentials: &Credentials) -> Result<Token, AuthError> { ... }
Scanner MUST:
- Parse
requirements.yamlandtasks.yamlfrom the project root - Recursively scan source files for
@reqannotations - Support multiple languages:
.rs,.ts,.js,.py,.dart,.go(comments differ —//for Rust/TS/JS/Go/Dart,#for Python) - Distinguish implementation files from test files (
test_*,*_test.*,*.test.*patterns) - Calculate per-requirement coverage: impl count, test count, status (covered / partial / missing)
- Detect orphan annotations (referencing non-existent requirement IDs)
- Detect orphan tasks (referencing non-existent requirement IDs)
- Compute project-level summary: total, covered, partial, missing, percentage
Step 3: Implement the REST API
Serve scanner results via HTTP, conforming to the SDD Navigator API spec.
Use actix-web, axum, or another Rust HTTP framework. The API is single-project and flat — no /projects routing layer. Endpoints:
GET /healthcheck— service health and versionGET /stats— aggregate counts: requirements by type and status, annotation counts (impl/test/orphans), task counts by status with orphan count, overall coverage percentageGET /requirements— requirements list with filtering (?type=FR&status=missing) and sorting (?sort=id&order=asc)GET /requirements/{requirementId}— single requirement with all linked annotations and tasksGET /annotations— all@reqannotations; supports?type=impl|testand?orphans=trueGET /tasks— all tasks fromtasks.yaml; supports?status=open|in_progress|doneand?orphans=truePOST /scan— trigger re-scan; returns202immediately withstatus: scanningGET /scan— current scan status; poll afterPOST /scanto track completion
Error handling:
- Missing files → clear error with expected path
- Malformed YAML → error with line number
- Empty source directory → warning, not crash
- Permission errors → skip with warning, continue scan
- No panics under any input
Step 4: Write comprehensive tests
- Unit tests: YAML parsing, annotation scanning per language, coverage calculation, filtering, sorting
- Integration tests: fixture directories with sample projects (
fixtures/), API endpoint tests with test HTTP client covering the flat endpoint structure (/requirements,/annotations,/tasks,/stats,/scan) - Edge cases: empty requirements, no annotations, malformed input, mixed languages, nested directories, orphan annotations, orphan tasks
- Every test MUST have a
// @req SCS-XXX-NNNannotation referencing which requirement from Step 1 it verifies
Step 5: Self-hosting and verification
Self-hosting: the service scans its own codebase. The repository’s requirements.yaml defines the service’s own requirements, and source code contains @req annotations referencing them. Running sdd-coverage scan ... --strict on the repo itself MUST pass.
Deterministic checks (the developer MUST run before submitting):
cargo fmt --checkcargo clippy -- -D warningscargo testcargo build --release- Self-hosting check:
./target/release/sdd-coverage scan --requirements requirements.yaml --source ./src --tests ./tests --strict
Deliverables
Provide a link to a public GitHub repository containing:
- Full source code with
Cargo.toml requirements.yamlfor the service itself- Test fixtures (sample projects for integration tests)
README.md: what the service does, how to build, how to run (CLI and server modes), API documentation referencePROCESS.md— your AI development process artifact (see below)
How We Evaluate
We are fully transparent about evaluation. Below are the exact prompts we use.
Step 1: You generate PROCESS.md
After completing the task, run the following prompt against your full AI conversation history. Commit the output as PROCESS.md in the repository root.
Analyze all AI conversations used during development of this project.
For each conversation, extract timestamps (start time, end time) from the chat metadata.
Produce a markdown document PROCESS.md with the following sections:
1. **Tools Used** — which AI tools (IDE, model, plugins) the developer used and for what.
2. **Conversation Log** — for each AI session: start/end timestamps, topic, what the
developer asked for, what was accepted, what was rejected or corrected.
3. **Timeline** — chronological list of major steps with timestamps and duration.
4. **Key Decisions** — what architectural and implementation choices the developer made,
and why. What alternatives were considered?
5. **What the Developer Controlled** — which parts of the output the developer reviewed,
tested, or rewrote. Be specific: list files, functions, and config sections.
What verification steps did the developer take before accepting AI output?
6. **Course Corrections** — moments where the developer identified incorrect, incomplete,
or suboptimal AI output and changed direction. What was the issue, how was it caught,
and what did the developer do instead?
7. **Self-Assessment** — which SDD pillars (Traceability, DRY, Deterministic Enforcement,
Parsimony) are well-covered in the submission and which need improvement.
Step 2: We evaluate your repository
We run the following prompt against your submission. You can run it yourself before submitting:
Evaluate this repository against the SDD (Specification-Driven Development) four pillars:
1. **Traceability**: Do commits reference requirement IDs? Do code and tests link to
requirements via @req annotations? Does the service's own codebase have a
requirements.yaml and enforce traceability on itself (self-hosting)?
2. **DRY**: Are API response types defined once and shared? Are language comment patterns
configured once, not hardcoded per scan? Is scanner logic shared between CLI and
HTTP modes? Are there duplicated constants or type definitions?
3. **Deterministic Enforcement**: Are cargo fmt, clippy, and tests used to verify
correctness? Is there a self-validation script that checks traceability? Can any
check be automated further? Are there manual verification steps that could be scripted?
4. **Parsimony**: Are dependencies in Cargo.toml minimal and justified? Are there
premature abstractions or unused modules? Is the README concise and factual?
For each pillar: rate as PASS / PARTIAL / FAIL with specific file references and line
numbers. Produce a summary table and a list of concrete violations.
A good submission is honest, not polished. We value a candidate who catches AI mistakes over one who ships fast without checking.
If you feel overwhelmed by the volume of new concepts here — that is normal. What we describe is the cutting edge of AI-assisted engineering. These are not widely known practices yet. Open Cursor or Claude, and study this material together with your AI tool. Just remember: it is you who is learning, not your agent. Move to practice as quickly as possible — only hands-on work turns information into applicable skill.
We look forward to seeing how you build with AI — and how you think about what AI builds for you.