Foreman puts an agent on every stage of your development loop and keeps you on the judgment calls. Label a GitHub issue factory, @mention the bot on an issue or pull request, or delegate an issue in Linear, and Foreman moves the work through four stations, classifier, analyst, implementer, and reviewer, ending in a reviewed draft pull request on your repository. Along the way it triages incoming issues, fixes red CI on its own branches, and posts progress back where the work arrived. You mark ready and merge; those decisions never leave your hands.
The factory is built on eve, a filesystem-first framework for durable backend agents from Vercel. GitHub and Linear authenticate through Vercel Connect, and Vercel Blob and AI Gateway authenticate with your project's OpenID Connect (OIDC) token.
Deploy the template now, or read on for a deeper look at how it all works.
eve Software Factory Template
Four coding stations behind one orchestrator: triage, planning against a live checkout of your repo, implementation verified with your own checks, and independent review.
Copy link to headingQuick start with an AI coding agent
If you're working with an AI coding agent like Claude Code or Cursor, you can use this prompt to have it help you with building your factory:
I want to build a software factory with the eve framework, using the eve software factory template. Read the documentation at https://ask-foreman.dev/docs and follow it. It will cover deploying the template, building with eve, how the pipeline works overall, and more.
Copy link to headingVercel Plugin
The Vercel Plugin turns your AI coding agent (e.g., OpenAI Codex, Claude Code, or Cursor) into a Vercel expert. It adds skills, slash commands, and current knowledge of the tools this template uses, including Vercel Connect, Vercel Blob, Vercel Sandbox, and AI Gateway.
The plugin is optional; it isn't required to use eve or to follow this guide.
Copy link to headingMeet the stations
Foreman, the orchestrator, routes each work item through four stations in order.
Each station is its own subagent with its own instructions, model, sandbox, and tools; it runs in a fresh session, inherits nothing from the orchestrator, and works only from the brief it's handed.
| Station | Owns | Hands back |
|---|---|---|
classifier | Triage: type, priority, complexity, affected area, actionable or needs clarification | A structured classification the rest of the pipeline routes on |
analyst | Planning against a live checkout of your repository: approach, ordered steps, risks | A plan with acceptance criteria, plus an analysis artifact for detail |
implementer | Executing the plan in its own checkout, running your repo's checks, committing, pushing a branch | The branch name, a per-file change summary, and verification results |
reviewer | Independent judgment of the pushed branch against the acceptance criteria, on a different vendor | Approve, request changes, or reject, with evidence for each criterion |
One more subagent, researcher, joins when a work item needs a fact that isn't in the repository or its issues, like an upstream bug or a library version. It runs web searches and returns cited findings with confidence levels, surfacing the gaps it couldn't close rather than papering them over.
Three rules hold the pipeline together:
- The review is independent. The reviewer never sees the implementer's reasoning, only the pushed branch, and it runs on a different model vendor so it doesn't share the implementer's blind spots.
- The acceptance criteria are the contract. The analyst writes them, and the reviewer judges the implementation against them verbatim.
- Revisions are bounded. On a
request_changesverdict, the orchestrator sends the reviewer's findings back to the implementer and re-runs the review, at most twice. If the work still doesn't pass, it halts the line and reports the unresolved findings rather than opening a pull request.
Copy link to headingSetup and deployment
Copy link to headingWhat you need before deploying
You need four things to deploy and run the factory:
- A Vercel account.
- A GitHub repository for the factory to work on, where you can install a GitHub App with write access to contents, issues, and pull requests.
- A Linear workspace, if you want to delegate work from Linear.
For local development, you also need Node.js 24+, pnpm, and the Vercel CLI.
Copy link to headingDeploy to Vercel
Deploying with the one-click flow provisions everything the factory needs:
| Provisioned | Sets |
|---|---|
GitHub connector, with its trigger pointed at /eve/v1/github | GITHUB_CONNECTOR |
Linear connector, with its trigger pointed at /eve/v1/linear | LINEAR_CONNECTOR |
| Public Vercel Blob store for preferences, brain, and artifacts | Blob credentials |
| Prompt for your target repository and intake label | FACTORY_REPO, FACTORY_LABEL |
FACTORY_REPO is required at build time. If the value is missing, a clear error will indicate that. Everything else has a sensible default:
| Variable | Required | Default | What it does |
|---|---|---|---|
FACTORY_REPO | Yes | — | The owner/repo the factory works on |
FACTORY_SETUP_COMMAND | No | — | Runs once inside the sandbox checkout at build time (e.g. pnpm install), so every run starts with dependencies installed |
FACTORY_LABEL | No | factory | The issue label that hands an issue to the factory |
FACTORY_BRANCH_PREFIX | No | factory/ | Branch prefix marking the factory's own PRs, the only branches automated CI fixes touch |
FACTORY_BOT_NAME | No | the GitHub App's slug | The @mention name, resolved from the connector automatically when unset |
Copy link to headingConnect GitHub
The one-click flow installs the GitHub App and points its event trigger at the route the agent serves (/eve/v1/github), so there's nothing to wire up. The connector subscribes to issues, issue_comment, pull_request_review_comment, pull_request, and check_suite events, and the installation needs write access to contents, issues, and pull requests on FACTORY_REPO.
The factory answers to whatever you named your GitHub App: the @mention name is resolved from the connector's app slug at runtime, so a hardcoded handle can't collide with an unrelated GitHub user. After the deploy finishes, label an issue factory or @mention the bot on an issue to start work.
You can't test GitHub or Linear events locally, because they’re both forwarded to Vercel Connect, which verifies them and delivers them to your deployed project rather than to a local URL. Test the inbound webhook paths against a preview or production deployment; everything else runs in the local dev terminal UI (TUI).
Copy link to headingConnect Linear
Linear is optional. When connected, users delegate issues to the factory through Linear Agent Sessions; the factory works the item, posts progress as Agent Activities, and reports the pull request link back on the session. The Linear connection is app-scoped rather than per-user, with scopes limited to read, write, issues:create, and comments:create, and every write on it is denied during unattended runs so a prompt-injected issue can't fan out into the tracker.
Not using Linear? Delete agent/channels/linear.ts and agent/connections/linear.ts and remove LINEAR_CONNECTOR.
Copy link to headingHow work arrives
Work reaches the factory six ways:
- Label an issue
factory. The pipeline runs on its own, posts progress as stations complete, and ends with a draft PR linked to the issue. Only labelers with at least triage permission on the repository can trigger it. - @mention the bot on an issue or PR. Mentions from repo owners, members, and collaborators start an interactive session. Everyone else's mentions are acknowledged without a session.
- Delegate in Linear. Linear Agent Sessions run the same pipeline and report progress back in Linear.
- The dev TUI. Hand it a task locally. Changes to GitHub wait for your approval.
- Red CI on a factory PR. Foreman diagnoses the failure and pushes a fix to its own branches, never yours, capped at 2 attempts.
- Someone opens a pull request. Foreman posts one orienting comment for reviewers: a summary with a changed-files table, not a review.
Copy link to headingLocal development
You can run the factory locally in the dev TUI.
First, clone the repository that the one-click deploy flow created:
Then link it to the Vercel project you deployed and pull the environment variables:
vercel env pull writes a short-lived OIDC token into .env.local. Local runs use it to reach Vercel Blob, provision the station sandboxes, and call the model through AI Gateway. Start the dev server to open the TUI:
In the TUI, hand Foreman a task ("users report the password reset email arrives twice, fix it") and watch the four stations fire in order, ending in a draft PR on FACTORY_REPO.
Local runs are untrusted by design, so writes to GitHub wait for your approval in the TUI. Use it to confirm the gates stop work before it lands.
These are the commands you'll use day to day:
| Command | Does |
|---|---|
pnpm dev | Start the eve dev TUI |
pnpm validate | Lint, typecheck, and discovery diagnostics in one |
pnpm check / pnpm fix | Check formatting and lint rules, and auto-fix what it can |
pnpm typecheck | tsc --noEmit |
pnpm eval --tag fast | Run the cheap eval loop guarding routing and safety behavior |
npx eve info | Print every discovered tool, skill, connection, channel, and subagent |
eve deploy | Ship to production, the same as vercel deploy --prod |
Linting and formatting come from Ultracite, a Biome preset.
npx eve info is the fastest way to confirm a change landed: if a file you added doesn't appear, discovery didn't classify it as an authored slot, and .eve/discovery/diagnostics.json says why.
Copy link to headingHow the factory works
The orchestrator runs one loop: ground itself in the work item and the factory's memory, move the item through the stations in order, and deliver a reviewed draft pull request.
- Work arrives: a maintainer labels an issue
factory, @mentions the bot, or delegates an issue in Linear. The channel turns the event into a session and stamps the caller's trust at dispatch, on the signed webhook, before the model sees anything. - Ground in memory and the real issue. The orchestrator calls
get_user_preferencesfor the requester's standing notes (a default base branch, how they like PR descriptions structured) andread_factory_brainfor the factory's shared, durable notes about the target repository: build quirks, verification gotchas, recurring review findings. It then reads the actual GitHub or Linear issue in full, loads thetriaging-issuesskill, checks for duplicates against open and closed issues, and mirrors the classification onto the issue with labels from the repo's own vocabulary, never one it invented. - Route through the stations, in order, always. Classifier, then analyst, then implementer, then reviewer. Every delegation message is self-contained: stations run in fresh sessions and never see the orchestrator's history, so it includes the original work item verbatim, along with every prior stage output the station needs. Never skipping a station is a rule that doesn't bend; the classifier decides what is trivial, not the orchestrator.
- Stop for clarification when the classifier says so. If the classifier returns
needs_clarification, the pipeline stops. With a person on the other end, the orchestrator asks them the classifier's questions and waits. During an unattended run, it posts the questions as comments on the issue and stops; since nobody is watching, it never leaves a run waiting on input. - Long documents travel by id, not by pasting. The researcher and analyst save full memos as handoff artifacts in Vercel Blob and return an id; the orchestrator relays the id into later stations' briefs, and the implementer and reviewer open the document themselves with
read_artifact. An SEO-length analysis never passes through the orchestrator's context or a PR body. - Deliver, and remember what the run taught. When the reviewer approves, the orchestrator opens a draft pull request (head set to the branch the implementer pushed), writes the PR body from the pipeline's outputs including the reviewer's pass/fail against each acceptance criterion, and reports back on the originating thread. If the run surfaced a durable fact about the repository, it merges the note into the factory brain so every future run starts from it.
Every credential in this loop is brokered at runtime:
- GitHub and Linear through Vercel Connect
- Vercel Blob, Vercel Sandbox, and AI Gateway through the OIDC token
- Station git operations through installation tokens injected at the sandbox firewall, never inside the sandbox
Copy link to headingCode walkthrough
The whole factory is defined under agent/, and eve discovers each capability from the filesystem. Every tool's name is its filename, every subagent's name is its directory name, and every extension's namespace is its filename, so there's no central registry to wire up. These are the pieces that matter.
Copy link to headingThe GitHub surface
The GitHub channel lives in agent/channels/github.ts, and its intake hooks are where trust is decided:
Two details in the intake hooks carry the security model:
onCommentdispatches only for commenters whoseauthor_associationis OWNER, MEMBER, or COLLABORATOR, and stamps thetrustedauth attribute at dispatch. Mentions from anyone else never start a session, so arbitrary accounts on a public repository cannot drive the agent's write tools.onIssueverifies the labeler's repository permission against the API before dispatching, with triage as the floor. GitHub fires thelabeledaction even for labels attached at issue creation, which issue templates let unauthenticated reporters do, so checking the sender's permission is what keeps the unattended pipeline maintainer-triggered. The session's auth is then rewritten to a constructed autonomous principal carrying the intake issue number, so the run never executes as the labeler.
The channel also renders human-in-the-loop prompts as comments with a mention-based reply instruction, and answers route back through the same onComment gate. That's what makes a comment reply an authorization signal rather than a race anyone on a public repo can win: an untrusted account's "approve" never reaches the waiting session.
Copy link to headingThe Linear surface
The Linear channel in agent/channels/linear.ts is the second intake, and its trust decision is simpler on purpose:
Every Agent Session is stamped trusted at dispatch, because workspace membership is the gate on Linear: only members can open a session, so there's no association check to run the way the GitHub channel does for public commenters. The hook also injects the requester's name as session context, so progress notes and the final report carry attribution. Credentials are brokered by Vercel Connect, which supplies the app token and verifies inbound webhooks by their Vercel OIDC signature, so none of that lives in your code.
Linear sessions run the same pipeline as GitHub ones, and when an item spans both trackers (a Linear issue about a GitHub bug, or the reverse), the github-linear-bridging skill supplies the conventions: check whether the GitHub issue is already tracked in Linear before creating anything, backlink both directions, and mirror only state that changes decisions, not every comment or label.
Copy link to headingThe orchestrator that routes, not writes
The orchestrator's runtime configuration is minimal:
Everything else about the orchestrator is agent/instructions.ts, and its core rule is that Foreman is a routing layer, not a fifth station. It grounds the work item, delegates to exactly one station at a time with a complete brief, verifies handoffs, and assembles the result. It never writes code or performs deep analysis itself; if a station fails or returns something malformed, it retries once with a clarified message rather than doing the work.
Model assignments are centralized in agent/lib/models.ts so a swap is a one-line edit:
The model IDs route through the Vercel AI Gateway, which authenticates through the linked project, so there's no provider API key to set. One split is deliberate: the implementer runs the strongest coding model on a different vendor than the reviewer, and keeping those two apart is what keeps the review independent.
Copy link to headingStations as task-mode subagents
Each station is a directory under agent/subagents/ with the same shape: an agent.ts whose description is all the orchestrator sees when routing, an instructions.md, its own sandbox.ts where it needs a repo checkout, and a tools/ directory. Subagents inherit nothing from the orchestrator: no conversation history, no skills, tools, or connections. That's why every brief has to be complete.
The routing description is a contract, not a label. Here's the reviewer's:
The outputSchema on each station's agent.ts is what makes every delegation run in task mode: the station must run to completion and return structured output, and it cannot stop to ask a question or wait on an approval card. That's a design constraint, not an accident. Hitting an approval gate within a task-mode child would strand the run forever, so nothing within a station may need one; anything that needs approval lives on the orchestrator, and station-side effects must be inert by construction.
The analyst, implementer, and reviewer each hold their own sandboxed clone of FACTORY_REPO, provisioned once per template build through a shared bootstrap in agent/lib/github/repo-sandbox.ts. The clone and your FACTORY_SETUP_COMMAND (like pnpm install) are paid once at build; each session pays only a fetch to the repository's current default branch. That's why the analyst's plan names real files and the implementer verifies with your repo's own checks, not guesses.
Copy link to headingApproval policies as the authorization model
The orchestrator's GitHub surface is mounted as an eve extension in agent/extensions/github.ts: an explicit allowlist with no preset, so reads, triage writes, and PR authoring are in, and merge tools are deliberately absent from the surface entirely. Merging stays a human act, done in the GitHub UI.
The requireApproval map doubles as the authorization policy, with per-tool predicates in agent/lib/github/approval.ts. The interesting one is createPullRequest:
The policy receives the tool's input as well as its name, so it gates on what the call does rather than only what it's called: a draft PR cannot merge, so it runs for every caller, while anything that can ship, a non-draft PR or marking one ready, parks for a person no matter who asks. Draft pull requests are the unattended ceiling.
The full matrix, by caller class:
| Action | Unattended run (labeled issue) | Trusted mention or Linear session | Dev TUI |
|---|---|---|---|
| Open a draft pull request | Runs | Runs | Runs |
| Open a non-draft PR, mark a PR ready | Denied | Waits for approval | Waits for approval |
| Merge a pull request | Not in the tool surface | Not in the tool surface | Not in the tool surface |
| Apply or remove labels | Runs | Runs | Waits for approval |
| Comment on the intake issue | Runs | Runs | Waits for approval |
| Comment anywhere else | Denied | Runs | Waits for approval |
| Close or reopen an issue | Runs | Runs | Runs |
| Write the factory brain | Denied | Runs | Waits for approval |
| Write to Linear | Denied | Runs | Runs |
clear_user_preferences | Denied | Waits for approval | Waits for approval |
Two choices in that table are worth pausing on. Unattended runs are denied rather than parked, because nobody is watching an autonomous turn to answer an approval card, and a server-side denial costs one step instead of a stranded session. And closing or reopening an issue runs ungated for every caller, because it's reversible triage, a reopen undoes it, and the only sessions that reach the tools at all are trusted mentions, autonomous label runs, and the local dev TUI. updateIssue with state set follows the same close/reopen policy, so the two paths to the same action always behave alike.
Copy link to headingGit credentials never enter a sandbox
The implementer's one side effect, push_branch, is safe to run ungated inside a task-mode station because it is inert by construction:
validateBranch refuses main, master, refs/*, HEAD, and anything outside a conservative character set, so shell metacharacters can never reach the command line and a feature branch alone ships nothing. The credential itself never enters the sandbox: clones, fetches, and pushes target the literal https://github.com/<FACTORY_REPO>.git URL, never the model-writable origin remote, and the installation token is injected at the sandbox firewall as a header transform on egress to github.com, then dropped again in a finally:
Git remote config inside a sandbox (pushurl, per-branch remotes) is model-writable, which is exactly why the git helpers never go through origin: nothing the model writes can redirect the brokered credential.
Copy link to headingThe factory brain and per-user memory
Two kinds of durable state live in Vercel Blob, and their key derivation is the part worth reading.
The factory brain is one shared document per target repository: durable notes like build quirks, verification gotchas, and recurring review findings that every run reads at the start of a task.
The Blob key is derived entirely from FACTORY_REPO, resolved at module load, never from model input, so a session can't redirect a read or write to another object. Reads are open to every run, but writes are gated by factoryBrainPolicy: unattended runs are denied outright, because a labeled issue's body is untrusted input that must not be able to poison the context every future run reads. Trusted callers write directly; the dev TUI waits on an approval card.
User preferences are the opposite: one file per person, keyed by the framework-resolved principal, hashed so the stored path carries no raw identifier. Each session can only ever read or write its own user's file, and clear_user_preferences is irreversible and gated on approval. The reserved-namespace registry in agent/lib/blob.ts is what keeps any general-purpose Blob tool from using either prefix as a side channel.
Copy link to headingHandoff artifacts
Long documents move between stations by id rather than by pasting text through the orchestrator's context. The researcher and analyst save Markdown documents (up to 200,000 characters) to a private Blob under a reserved artifacts/ prefix with save_artifact and return an id; the implementer and reviewer read them back with read_artifact, and the orchestrator holds only the reader.
Artifact ids are the one Blob address the model supplies, which is why the id format is validated strictly:
The pattern is anchored, with no dots or slashes permitted, so a validated id cannot traverse out of the reserved prefix; without that, a caller could pass a path like ../factory-brain/<hash>.md and read a managed document through a tool that was never meant to reach one. An invalid id reads as not found, indistinguishable from a missing one, so a probe learns nothing from the difference. Saves never overwrite and mint their own suffixed id (analysis-dedupe-reset-emails-k3f9qz), which is what lets both artifact tools live ungated inside task-mode stations.
Copy link to headingNo self-delegation
The root's tools/agent.ts disables eve's built-in agent tool:
The built-in tool runs a fresh copy of the root agent, which would let the orchestrator delegate work to an undifferentiated clone of itself and bypass the four stations. All delegation goes through the declared subagents instead, so the pipeline is structural rather than a suggestion in the prompt.
Copy link to headingCoding judgment as skills
Three skills sit on the orchestrator, each a folder with a SKILL.md whose frontmatter description is the routing hint that decides when it loads:
| Skill | Loads when |
|---|---|
triaging-issues | A work item arrives from a GitHub issue or mention: dedupe against open and closed issues, label from the repo's own vocabulary, decide whether to ask or proceed, and ask for reproduction details well |
github-linear-bridging | An item spans both trackers: check whether a GitHub issue is already tracked in Linear, backlink both directions, and mirror only meaningful state |
writing-quality | Any prose meant for humans: PR descriptions, issue comments, review reports, Linear replies. Kills AI tells and swaps bloated wording for plain English from its references/ lookup tables |
Loading a skill only adds instructions to the turn; it never adds a new action the agent can take. Skills are per-agent, so the stations don't see the orchestrator's skills, which is another reason every brief has to carry what the station needs.
Copy link to headingEvals as the safety floor
The template ships an eval suite under evals/, organized as a failure taxonomy: routing/ asserts the classifier always runs first and labels follow classification, safety/ asserts deny-by-default over the whole write-tool list (a read-only question calls no write tool, a write parks on approval, a prompt-injected issue body doesn't move the agent, nothing pushes to main, unattended runs can't write the factory brain), and pipeline/ holds an opt-in run of the whole line that pushes a real branch.
Evals cost real model tokens, and the full-pipeline run pushes a real branch, so run it deliberately. Instruction-following on injected text remains model judgment; the prompt-injection eval keeps a floor under it while the structural bounds (the autonomous principal's denials, the firewall-brokered credential, the human gate on shipping) don't depend on the model behaving.
Copy link to headingCustomize the factory
There is no registry file: a tool's name is its filename, and a subagent's or skill's name is its directory name. Add a file to add a capability, delete it to remove one. The agent picks up changes to these files as you save.
| To change | Edit | Notes |
|---|---|---|
| The target repository | FACTORY_REPO in the project's environment | Changing it rebuilds the station sandboxes and gives the new repo its own factory brain |
| The orchestrator's behavior | agent/instructions.ts | Grounding, routing, the review loop, delivery |
| A station's craft | Its instructions.md and outputSchema in agent.ts | The description is all the orchestrator sees when routing |
| Models | agent/lib/models.ts | Any Gateway model ID works; keep implementer and reviewer on different vendors |
| Approval gates | agent/lib/github/approval.ts and the requireApproval map in agent/extensions/github.ts | Write tools not listed keep the SDK's approval-by-default |
| What the orchestrator can reach on GitHub | include in agent/extensions/github.ts | An allowlist with no preset; prefer adding a name here over loosening a gate |
| The intake label and branch prefix | FACTORY_LABEL and FACTORY_BRANCH_PREFIX environment variables | The implementer's instructions carry the default prefix as prose, so keep them in sync on an override |
| Triage, bridging, or prose conventions | The skill folders under agent/skills/ | A skill's frontmatter description decides when it loads |
| The safety floor | evals/ | One file per case; helpers.ts carries the shared write-tool list read-only evals assert against |
Two extensions are designed for, and the approval policies already anticipate them:
- Merge behind approval. Add
mergePullRequestto the extension's allowlist mapped toshipPolicy, and comment-driven merges park for a person the same way marking ready does today. - Continuous operation. A sweep schedule that dispatches one session per queued item inherits sensible write behavior automatically: the policies already recognize schedule turns via
isScheduleAppAuth, so reversible writes run and anything that ships still parks for a person. Cross-run dedupe state needs an external store, since the template has no application database.
Not using a surface? Delete its file; nothing references one by name, so removing it is the whole job.
| Not using | Delete |
|---|---|
| Linear | agent/channels/linear.ts and agent/connections/linear.ts |
| Web research | agent/subagents/researcher/ |
Keep all four stations: the pipeline's guarantees, independent review above all, come from every item passing through them in order.
Copy link to headingTroubleshooting
| Symptom | Likely cause | Fix |
|---|---|---|
| Labeling an issue doesn't start the pipeline | The labeler holds less than triage permission on the repository, or the GitHub connector isn't subscribed to the issues event. The channel verifies the labeler's permission against the API and acknowledges anything below triage without a session | Confirm the labeler is at least a triage-level collaborator and that the connector's trigger points at /eve/v1/github with the issues event subscribed, then remove and re-apply the label |
| @mentions don't get a response | The commenter's author_association isn't OWNER, MEMBER, or COLLABORATOR, or the mention uses a name the App doesn't answer to | Mention it from an owner, member, or collaborator account, using the GitHub App's own slug (or FACTORY_BOT_NAME if you overrode it) |
The build fails with a FACTORY_REPO error | The variable is required at module load, so a misconfigured factory fails discovery instead of producing a factory with no target | Set FACTORY_REPO to a plain owner/repo pair (like acme/widgets) in the project's environment and redeploy |
| Writes appear to stall in the dev TUI | The call is gated on approval and waiting for a decision. The dev principal is untrusted by design, so approval cards surface in the TUI | Approve or deny the pending call. To change which tools are gated, edit agent/lib/github/approval.ts and the requireApproval map in agent/extensions/github.ts |
| CI fixes stop after two attempts | The red-CI loop is bounded on purpose. Each session counts earlier fix-attempt comments on the pull request and stops after 2, so the factory can't loop on a failure it doesn't understand | Troubleshoot the failure yourself, or @mention the bot on the PR with a diagnosis to run an attended revision. The loop only touches branches carrying the factory/ prefix |
| Connectors work locally but fail in production | .env.local is local-only, and the deployed app reads the Vercel project's environment | Set GITHUB_CONNECTOR, LINEAR_CONNECTOR, and FACTORY_REPO in the project's production environment. The Deploy button sets them for you |
| Files you added don’t show up | eve walks agent/ at build time and only registers files that classify as an authored slot, so a naming or placement problem drops the file from discovery | Run npx eve info to see what eve discovered, and check .eve/discovery/diagnostics.json for why a file was skipped |
Give your software factory a browser
Foreman can reproduce bugs behind a login, verify shipped fixes on preview deployments, and record findings for every future run.