We are at the forefront of agentic AI. We develop self-improving, recursive agentic systems for the most complex use cases: systems that enter unfamiliar environments, map their constraints, form and test hypotheses, write their own code and evaluation harnesses, coordinate specialised agents, and turn verified experience into better tools, skills, memory and operating policy. Our goal is not a chatbot that follows a script, but an adaptive engineering system that can investigate, build, measure, learn and return to the next problem more capable than before.
We hire at every level, from Junior to Senior and above. There is no take-home quiz with one right answer. Before we speak, you read about a role, choose a challenge yourself (one we propose, or one you invent), complete it independently in a fork of this repository, and open a pull request that describes the improvement.
The pull request is your application. We read it before the call. When we talk, your work becomes the center of the conversation: what you chose, how you approached it, what the evidence showed, and what you would do next.
Try Zenera Neo first
Before choosing a role or challenge, install the Zenera Neo command-line tool and spend a few minutes exploring what it can do:
npm i -g @zenera/cli
zen --help
zen init --help
zen run --help
zen inspect --helpThis quick look will give you context for the product, its project workflow and the kinds of problems in the challenges below. You do not need to configure a model or create a project yet.
Why we use this format
A real contribution shows more than a generic exercise. It lets you choose a problem that reflects your strengths and gives both of us concrete work to discuss. The fork keeps your work independent from the main repository; the pull request makes your decisions and evidence easy to review. You complete the challenge at home before speaking with us, then we use the conversation to explore your reasoning rather than asking you to perform under artificial interview conditions.
Roles
| Role | In one line |
|---|---|
| QA Engineer | Decide what generated data must promise, find where it does not, and test it. |
| Software Engineer | Build and harden the runtime, the CLI, the faker and the sandbox. |
| DevOps / Release Engineer | Make building, testing and publishing boring. |
| Solutions Engineer | Turn a customer's problem into a working agent project. |
Every role file has the same parts: about the role, what you would do, what we look for, what we expect at each level, and a set of example challenges.
How it works
- Read the role file you are applying for.
- Choose one example challenge, adapt it, or write your own (see below). Take what suits your level; going above it is welcome, going below it is not held against you.
- Do it in your fork, on a branch named after what you change.
- Open a pull request that describes the improvement, the way you would for any contribution.
- Send us the link, with the role, the challenge (or "own challenge") and the level you apply at, through the channel where you applied.
- We review it before the call so we understand the work and can prepare useful questions.
- We talk. We go through the challenge together: your choices, trade-offs, evidence and what you learned.
The pull request itself reads like an ordinary contribution. Do not write "hiring", "application" or a task id in a branch name, a commit message, a title or a description. The pull request is public; the link to your application is the message in step 5.
Nobody assigns you a task. The choice is part of the evaluation: what you pick, and what you decide is out of scope, tells us as much as the result.
Challenge difficulty
Every example has a difficulty label. It describes the judgement and depth involved, not how long the work should take.
- Easy Do one thing and report what you saw. A good starting point for Junior and Middle candidates.
- Medium Build a small, correct artefact. Suitable for candidates at every level.
- Hard The obvious solution is subtly wrong. Typical for Senior candidates.
- Expert An open design question judged on reasoning and trade-offs, not volume. Typical for Senior candidates and above.
Do not do every challenge. One done well, with its limits stated, beats five done thinly.
Propose your own challenge
Propose your own if none of ours fits. Keep it inside the repository's subject: agents, the runtime, the CLI, the faker, RAG, the docs. The pull request description (template below) must state:
- the problem, in two sentences, and who has it;
- the scope: what you will do and what you will not;
- how a reviewer can tell it worked.
In your message to us (step 5), add the difficulty label you would give it, and why.
An unrealistic scope is a worse sign than a small one.
How to submit
This is the standard fork-and-pull-request workflow on GitHub.
1. Fork the repository. Open Fork ZeneraNeo on GitHub, sign in if GitHub asks, and choose your account as the owner. GitHub will create an independent copy where you can complete the challenge.
2. Clone your fork.
git clone https://github.com/YOUR-USERNAME/ZeneraNeo.git
cd ZeneraNeo
npm installnpm install also turns on the commit hook, which runs a secret scan and formats the files you
stage. Do not bypass it.
3. Create a branch. Never work on main. Name it after the feature or the fix, in the style the
repository already uses.
git checkout -b faker-serve-long-paged-lists
git checkout -b fix-wide-character-wrapping4. Make changes and commit. Small commits, each with a message that says what changed and why.
git add .
git commit -m "Let the faker serve a chosen number of pages"5. Push the branch to your fork.
git push origin faker-serve-long-paged-lists6. Open the pull request. On the original repository (or your fork) you will usually see
Compare & pull request. Set the base repository to andreyryabov/ and its branch to
main; set the head to your fork's branch. Give it a title that says what changed ("Let the faker
serve a chosen number of pages") and the description below, then click Create pull request.
7. Send us the link. See step 5 of how it works above.
Where the work goes
| Kind of task | Put it |
|---|---|
| Changes the product (code, tests, docs, scripts) | Where it belongs in the repository |
| A report, a strategy, a design, a dataset, a test suite of yours | A folder named after the subject, such as reports/ |
Before you push: npm run typecheck and npm test -- --exclude '**/ should pass for
anything that touches packages/.
What the pull request description says
The pull request is the deliverable. Write it for a reader who was not there.
## Problem
Who has it, and what happens today. Two sentences.
## The improvement
What is better now than before. One paragraph, no history of your afternoon.
## How I know
The commands you ran, the seed, the output that shows it. Reproducible.
## What I decided not to do
Scope you cut, and why. Anything you could not check.
## Open questions
What you would ask the maintainers.A pull request with a clean diff and a clear description is read first.
Ground rules
- The mock is under test as much as you are. For tasks that use it, finding a real defect in it is a result, not an obstacle. Say what you saw, what you expected, and why.
- Separate three kinds of "wrong": the contract (the body violates the schema), the semantics (it validates but is about the wrong thing), and state (two calls disagree because the mock remembers nothing). Only the first is certainly a bug.
- Show evidence: the request, the response, the seed, the command.
- You may use any tools, including AI assistants. You must be able to explain every line you submit, and say which parts you did not write yourself.
- Pull requests are public. Never commit a key, a token, a
.envor personal data. - Do not copy another applicant's pull request.
The mock
Several tasks use a local mock of two familiar APIs. Nothing needs a real mailbox or calendar:
@zenera/ serves them from the
mock API examples,
and the answers are written once by a model.
| Spec | Shaped after | What it is good for |
|---|---|---|
mail.yaml | Gmail REST | Search (q), ids-only listing, pageToken paging, send, labels, threads |
calendar.yaml | Google Calendar | Time windows, recurrence, attendees, freeBusy, pageToken paging |
npm i -g @zenera/cli @zenera/faker
zen key add openai # or any provider `zen key add` knows
zen faker build examples/mock-apis/specs/*.yaml # write every generator up front
zen faker serve examples/mock-apis/specs/*.yaml --seed 42 --port 8787
curl -s 'localhost:8787/users/me/messages?maxResults=5'--seed 42 makes the same request answer the same way, which is what lets you assert on data.
GET / lists what is served and how paging was recognised; GET / has a form for
every operation. Each response carries x-faker-operation and x-faker-cache (hit, miss or
regenerated).