Documentation
What Dualzo does
Dualzo is a governance layer around AI-written code. A GitHub issue or an in-app prompt becomes a plan; a human approves that plan; an AI coding provider carries it out task by task; your repository's own lint and test commands validate the result in a sandbox; a pull request is opened. Every step is written to an append-only audit log.
By default Dualzo never merges anything. You review the pull request and merge it yourself, exactly as you would a colleague's. A repository can instead be set to commit directly to a branch you choose — see Delivery method below.
Getting started
Four steps, roughly ten minutes:
- Install the Dualzo GitHub App and pick the repositories it may touch.
- Connect a repository. Dualzo indexes it and proposes validation commands.
- Review and confirm those commands. Tasks are blocked until you do.
- Start a task — write a prompt, or label a GitHub issue.
1. Connect GitHub
Dualzo reaches your code through a GitHub App installation, not through your personal token. Go to Repositories → Install the GitHub App, choose the account and the specific repositories to grant, and you are returned to Dualzo with an installation recorded against your workspace.
Then connect a repository from the list. Connecting kicks off indexing: Dualzo shallow-clones the default branch, detects the ecosystem and primary language, parses the manifest, maps the test layout, reads CI configuration, and builds an architecture summary. Indexing never executes your code — it only reads it.
You can revoke access at any time from GitHub, or disconnect the repository from Dualzo.
2. Confirm validation commands
From your manifest scripts, Makefile targets, and CI workflow steps, Dualzo proposes an ordered command per kind: install, lint, typecheck, test, build. Open Repository → Settings, correct anything wrong, and confirm.
If the repository has no test command, you can still confirm by acknowledging "reduced validation". That acknowledgement is recorded and printed on every pull request produced from the repository, so a reviewer always knows what was and was not checked.
3. Choose a model
Dualzo is the governance layer; the model doing the coding — Claude, Codex, Gemini, or Grok — is picked per task. Dualzo runs the model for you, so there are no API keys to set up. Models are only ever run on work that was approved.
Model usage is included in the Dualzo subscription and measured in credits. Each workspace has a usage limit that refills automatically; when it runs out, new tasks wait until it refills.
4. Start a task
A task is called an Execution. There are five ways one begins:
| Entry point | How it starts |
|---|---|
| Labeled GitHub issue | Add the "dualzo" label to an issue. Creating the issue alone does nothing — the label is the trigger, and re-applying it will not create a duplicate. |
| In-app prompt | New task → pick a repository, describe the change in your own words. |
| Scheduled task | New task → set "When" to a custom date. It runs automatically on that date through the same pipeline, then stops. |
| Suggested task | If the repository opts in, indexing surfaces TODO and FIXME markers as suggestion cards on the dashboard. Start turns one into a task. |
| Auto-fix failing CI | If the repository opts in, a GitHub Actions run that fails on the default branch opens a fix task automatically. |
A task that runs now can span up to 5 connected repositories — for example an API and the frontend that calls it. Dualzo plans the change across all of them, validates each repository with its own commands, and opens one pull request per repository. Scheduled tasks cover a single repository.
A good prompt names the outcome and the constraint, not the keystrokes: "Add rate limiting to the public API and cover it with a feature test" works better than "edit RouteServiceProvider".
Attaching images and files
Tasks that run now can carry up to 4 images and up to 3 files. Which types you can attach depends on the provider and model you pick: the form lists them under Attachments and updates as you switch. Drag files onto the form, choose them, or paste a screenshot. Scheduled tasks cannot carry attachments.
Files are sent to the provider's CLI exactly as you uploaded them — nothing is converted, re-encoded or extracted — so only formats the CLI reads natively are offered. Claude: PNG, JPEG, GIF, WebP, PDF and text files (txt, md, csv, json, yaml, xml). Gemini and Grok: PNG, JPEG, WebP, PDF and text files. Codex: PNG, JPEG, WebP and text files. Word and Excel files cannot be attached; export them to PDF or CSV first.
Limits: 4 MB per image, 10 MB per file. Password-protected PDFs and text files that are not UTF-8 are refused. If you switch to a model that cannot read a file you already attached, the form says so before the task is created.
5. Approve the plan
Dualzo sends the issue or prompt plus a budgeted slice of Project Memory to your model, and gets back an ordered plan: internal tasks with instructions and acceptance criteria, the files expected to change, the commands to run, and rollback notes. Nothing executes yet.
Workspace admins get an email with the plan and single-use, expiring signed links; the request is also posted to any chat channels you have connected, and the same controls appear on the task page and in the Approvals inbox. Any member of the workspace can decide:
- Approve — the execution is queued and starts running.
- Modify — you type instructions, planning re-runs with them, and a fresh approval request goes out.
- Reject — the task ends there.
Each plan carries a risk level and a confidence score from 0 to 100. Confidence is computed by Dualzo in PHP — from how many files are expected to change, whether those paths appear in the test inventory, whether a test command is confirmed, and your workspace's historical pass rate — not by the model rating its own work.
Auto-approve: when a workspace admin creates a task (now or scheduled) with auto-approve on, the plan starts without waiting for anyone. The approval is still recorded in the audit log. Auto-approve has no effect on tasks created by members, and an auto-approved run always opens a pull request — it never commits directly.
What validation actually runs
After each internal task, your confirmed commands run in order — install, lint, typecheck, test, build — skipping kinds you left unconfigured. They run inside an ephemeral container built on your ecosystem's base image, with:
- network access only during the install step;
- CPU, memory, and wall-clock limits;
- read-only mounts everywhere except the working directory;
- none of Dualzo's own secrets in the environment — only the environment variables you add for the repository.
If a command fails, its output is fed back to the model for up to two fix attempts. Still failing, the execution moves to Needs review rather than pushing anything.
Environment variables
If your tests or build need configuration — an application key, a test API key, a feature flag — add it under Repository → Settings → Environment variables. Every variable is passed to each validation command (install, lint, typecheck, test and build) when it runs in the sandbox. Values are stored encrypted.
Click Add variable, enter a name and a value, then click Save variables. Each row shows where it stands:
- Saved — the row matches what is stored.
- Not saved — the row is new or you changed it. It is not used until you click Save variables.
- Needs a name — the row has a value but no name. Rows without a name are skipped when you save.
Deleting a row also takes effect only when you click Save variables. Use letters, numbers and underscores in names, and don't start a name with a number. Saved changes apply to every validation run from then on.
- Variables reach only your validation commands. The AI model that writes the code never sees them, and they are not added to pull requests.
- Every step except install runs without network access, so a variable pointing at a real database or an external service cannot connect during lint, typecheck, test or build. Use an in-memory or file-based database for tests, and fake calls to external services.
- Dualzo sets CI=true for every command and manages HOME itself, so don't set either of those.
- Every member of the workspace can view and edit the variables. Each save is recorded in the audit log with the number of variables, never their values.
Pull requests
When everything is green, the branch is pushed and a pull request is opened against the repository's target branch (the default branch unless you chose another). The body contains a summary, what changed per task, a testing checklist, rollback instructions, the AI's explanation, which validation commands ran (with a reduced-validation notice where it applies), and a link back to the Dualzo audit page.
Once the PR is open, Dualzo tracks it: merging or closing it on GitHub updates the state here and is audited.
Delivery method
Each repository has a delivery method, chosen when you connect it and changeable in Repository → Settings:
- Create PR — the default. A validated pull request is opened and you merge it.
- Commit directly — you pick a target branch (for example develop). A run starts from that branch, is validated against it, and when everything passes the commits are pushed straight to it with no pull request.
When a task fails
A task in Needs review shows the plan, per-task status, the cumulative diff, and the failing output. You have three options:
- Abandon — the branch is deleted and the task closes.
- Edit plan and re-run — your instructions go back into planning, and the new plan needs approval again.
- Take over — the branch is pushed as-is and a draft pull request is opened, labelled needs-human and clearly marked unvalidated.
Scheduled and suggested tasks
A scheduled task is a saved prompt that runs once, automatically, on a date you pick — useful for a change you want made on a specific day. Manage them on the Scheduled page, where you can pause, resume, or delete each one.
Suggested tasks come from indexing: TODO and FIXME markers found in your source appear as dashboard cards. Start turns one into a task; Dismiss rejects it for good. Auto-fix CI opens a task when a workflow fails on the default branch. Both are per-repository opt-ins under Repository → Settings.
Giving the model more context
Besides the code itself, you can give plans three kinds of context about a repository. All of it is used only within each task's context budget and is presented to the model as data, not instructions.
Team notes
On the repository's Knowledge page, add short, lasting guidance — conventions, gotchas, preferences such as "always use the repository pattern for data access". Notes are included in every plan for that repository. The same page shows what Dualzo learned about the repository during indexing.
Reference files
Admins upload specs, schema dumps or data samples — as text files, PDFs or Word, Excel and PowerPoint documents — under Repository → Settings → Reference files, and are offered the chance right after connecting a repository. Members can see the list; only admins can upload or delete.
- Text files in UTF-8 — txt, md, csv, tsv, json, yaml, xml, sql or log — up to 1 GB each.
- PDF, Word (.docx), Excel (.xlsx) and PowerPoint (.pptx) files up to 10 MB each. Dualzo reads their text: Word paragraphs, Excel sheets row by row, and PowerPoint slides in order. Scanned PDFs (pictures of pages), password-protected files, and older .doc, .xls and .ppt files cannot be read.
- Each repository holds up to 1 GB of files in total, with no limit on how many. Pick as many files as you like at once: they upload three at a time and the rest wait their turn.
- Files go straight from your browser to private, encrypted storage. Dualzo checks the whole file; one it cannot read is rejected and deleted, with the reason shown next to the file.
- Secret-looking values such as keys and passwords are hidden before a file is used. Files are never executed and never served back.
When you start a task, tick the reference files it should use; unticked files are left out. The task's page lists the files it was given. For each ticked file the task reads the beginning of the file — roughly the first 4,000 characters — so put the most important content first. Database dumps and exports work differently: see below.
Uploads left unfinished are cancelled after 24 hours, and failed files are removed after 7 days. Files of a disconnected repository are deleted after 30 days; reconnecting it before then keeps them.
Database dumps and exports
Upload a database dump or export as a reference file and Dualzo reads its structure — tables or collections, columns or fields, keys and indexes — from the whole file, however big, up to 1 GB. The data rows in it are skipped as the file is read and never stored. If the file held data rows, the file itself is deleted once its structure is saved, so your data is not kept and the file stops counting towards the 1 GB.
| Database | Files Dualzo reads |
|---|---|
| PostgreSQL | A plain .sql dump from pg_dump, with or without data. |
| MySQL / MariaDB | A .sql dump from mysqldump, with or without data. |
| SQLite | A .sql file from sqlite3 .dump or .schema. |
| SQL Server | A .sql script from Generate Scripts in SQL Server Management Studio. |
| Oracle | A .sql DDL script, for example exported with SQL Developer. |
| MongoDB | The <collection>.metadata.json files mongodump writes, mongoexport output (.json, one document per line or as an array, or .csv with an _id column), a MongoDB Compass schema export, or a $jsonSchema validator in a .json file. |
- When a task uses the file, it gets the structure, not the start of the file: the tables most related to the task come first, with their keys and relationships. If a live database is also connected, its tables take precedence.
- For MongoDB exports, Dualzo learns each field's name and type from the documents and discards the values.
- The file row shows what was read, for example "Database structure: 30 tables, 42 foreign keys, 18 indexes."
- Binary backups cannot be read — pg_dump custom format (.dump, .backup), SQL Server .bak, Oracle .dmp, MongoDB .bson and archives, and SQLite .db files. The upload says which text export to use instead, for example pg_dump --schema-only --format=plain.
- A .sql file with only data rows and no table definitions is refused. A .sql file of ordinary queries, with no table definitions and no data, is used as a text file.
Database schema
Admins can connect a live PostgreSQL, MySQL/MariaDB, Microsoft SQL Server / Azure SQL or MongoDB database under Repository → Settings → Live database, so plans know your real structure: tables or collections, columns or fields, keys and indexes. Dualzo reads structure only — never rows or documents — and members see the connection's status.
- Use a read-only login. The form includes a step-by-step guide for creating one, with commands to copy. A login that can write, or a superuser, is refused and its password deleted at once. For MongoDB, the login must hold only the read role.
- The database must be reachable from the internet over TLS, on a standard database port. Allow the Dualzo IP address shown in the guide through your firewall. Private and internal network addresses are refused.
- Connecting needs two-factor authentication on your account and a fresh code from your authenticator app. Changing the connection needs a fresh code and the password again.
- MongoDB: paste a mongodb:// or mongodb+srv:// connection string. Dualzo keeps the hosts, database and username, and stores the password separately, encrypted. Only username-and-password logins with TLS are accepted. Collections, indexes and validation rules are read.
- For MongoDB collections without validation rules, you can turn on "Sample documents to learn field names and types". Dualzo then looks at up to 50 documents per collection, keeps only field names and types, and discards the values without storing them. Sampling is off by default.
- The structure is read again every night and whenever you click Refresh schema. If that fails three times in a row, the connection is marked failed and admins are emailed; plans keep using the last structure that was read. Very large schemas are shortened, with the tables most related to the task first.
- Credentials are encrypted, never shown again, never logged and never sent to the model. Disconnecting the database, or the repository, deletes them.
Notifications
Approval requests and decisions arrive by email and in the in-app notification bell. Admins can also post them to Slack, Microsoft Teams, Google Chat or Discord from Workspace → Notifications by pasting an incoming-webhook URL. Buttons in chat open the same signed approval links in your browser. Each member chooses which emails they receive.
Members and roles
Invite teammates by email from the Members page; they join by following a signed link. There are two roles:
- Admin — manages billing, members, repositories, notification channels and database connections, and can auto-approve tasks.
- Member — starts tasks, follows their progress, and approves, modifies or rejects plans. Members can view and edit a repository's environment variables and see its reference files and database status, but cannot change billing, members or other repository settings.
Workspaces are fully isolated: nothing in one workspace is visible from another, regardless of role.
Billing and free credits
- Team plan: $119 per month, 5 seats included.
- Free credits are occasionally offered as a time-limited signup promotion. Outside of an active promotion, no free credits are granted. When a workspace has none and no active subscription, it is gated to the billing page until you subscribe — your data stays put.
- Payments run through Paddle, which is the merchant of record and handles tax. Invoices are listed on the billing page.
- Cancelling takes effect at the end of the paid period, and you can resume any time before it lapses.
- Only workspace admins can see or change billing.
How far a credit session goes, per model
| Tier | Model | Typical cost per task | Tasks in one session |
|---|---|---|---|
| Budget / fast | Gemini 3.7 Flash | ~7 credits | ~320 tasks |
| Budget / fast | Codex GPT-5.4 mini | ~15 credits | ~150 tasks |
| Standard | Gemini 3.1 Pro | ~35 credits | ~64 tasks |
| Standard | Codex GPT-5.4 | ~70 credits | ~32 tasks |
| Standard | Claude Sonnet 5 | ~100 credits | ~22 tasks |
| Heavy / frontier | Claude Opus 5 | ~350 credits | ~6 tasks |
Audit log
Every governed action — webhook received, plan built, approval given, execution run, validation result, pull request opened, billing change — is written to an append-only log. Nothing in the application can edit or delete an entry; records are pruned automatically after 90 days.
Filter the whole workspace log by event, actor, and date on the Audit page, or read a single task's events in order on its own timeline.
Security and your code
- Your code is never used to train models.
- Only a budgeted slice of the repository goes to your model provider — the artifacts and files relevant to the task, never the whole repository.
- Indexing parses statically. Your code executes only inside the validation sandbox.
- Model provider keys are managed by Dualzo, stored in encrypted columns, and excluded from logs and serialisation.
- Two-factor authentication (authenticator app) is available under Settings → Security, and is required before connecting a database.
- Database connections are read-only and read structure only. Their credentials are encrypted, never logged and never sent to the model.
- Environment variables are stored encrypted and passed only to your validation commands, never to the model.
- Reference files are stored privately and encrypted, secret-looking values are hidden before a file is used, and files are never executed or served back.
- GitHub webhooks are signature-verified on the raw body before anything is parsed.
- Working directories are deleted at the end of every job, including failed ones.
- Attached images and files are stored privately, are visible only to members of your workspace, and are never shared through public links. All attached files are deleted automatically one year after the task finishes.
- Attached files are never opened or converted by Dualzo; they reach your provider's CLI unchanged, and their content is marked for the AI as data, not instructions.
Troubleshooting
| Symptom | Most likely cause |
|---|---|
| I labeled an issue and nothing happened | Check the label matches the repository's configured one exactly, the repository is connected, and its validation commands are confirmed. The Audit page shows whether the webhook arrived at all. |
| A task is stuck in Analyzing | Planning is a background job, and it waits while attached documents are still being read. If it never finishes or fails, the task page shows the reason; try Re-run or pick another model. If it keeps happening, contact support. |
| Validation fails on a command that passes locally | The sandbox has no network outside the install step and starts from a clean checkout. Commands relying on local caches need adjusting in Repository → Settings, and configuration your tests read from the environment belongs under Environment variables. |
| A variable is not reaching my tests | Check that its row shows Saved. Rows without a name are skipped, and new or changed rows are used only after you click Save variables. |
| My tests cannot reach our database or an outside API | Only the install step has network access. Use an in-memory or file-based database for tests and fake outside calls. To share your real database structure with plans, connect it under Database schema. |
| A database connection is refused | The Live database section in Repository → Settings shows the reason. Usual causes: the login can write (create a read-only one with the guide), the host is a private address or not reachable from the internet, the Dualzo IP address is not allowed through your firewall, TLS is off, or the port is not a standard database port. |
| A reference file shows Failed | The reason is shown next to the file. Usual causes: a text file that is not UTF-8 (save it as UTF-8 and upload it again), a scanned PDF with no text in it, a password-protected file (remove the password first), or an older .doc, .xls or .ppt file (save it as .docx, .xlsx or .pptx). |
| My database dump was refused | Binary backups (.dump, .backup, .bak, .dmp, .bson, .db) cannot be read; export a plain .sql file or a MongoDB .metadata.json or mongoexport file instead. A .sql file with data rows but no CREATE TABLE statements is refused too: export with the schema, for example pg_dump --schema-only or mysqldump --no-data. |
| No pull request was opened | A pull request cannot be opened while validation is failing. Open the task and look at the failing step, then re-run or take over. |
| I cannot see the billing page | Billing is admin-only. Ask a workspace admin, or check which workspace you are in with the switcher. |
| The whole app redirects me to billing | The free credits ran out for that workspace. Subscribing restores access; nothing was deleted. |
FAQ
- Which languages are supported?
- Any. Language support comes from detection, manifest parsing, and your repository's own commands — not from hand-written per-language analyzers. Ecosystems with a dedicated sandbox image are PHP, Node, Python, JVM, Go, and Ruby, with a generic fallback for everything else.
- Does Dualzo merge code?
- Not by default: it opens a pull request and stops, and merging is your decision. If you set a repository to commit directly, validated changes approved by a person are pushed to the target branch you chose — merging that branch onward is still up to you.
- Can it run without approval?
- Only if a workspace admin turns on auto-approve for a task they create. Otherwise every plan needs a human approval before any code is executed. Either way the approval is recorded in the audit log, and validation still has to pass.
- Can two tasks run on the same repository at once?
- No. One execution runs per repository at a time; the rest queue behind a lock.
- Can Dualzo change my database?
- No. A database connection uses a read-only login, logins that can write are refused, and only the structure is read — never your data.
- Can I upload my database dump instead of connecting the database?
- Yes — useful when the database is not reachable from the internet. Upload a .sql dump (PostgreSQL, MySQL/MariaDB, SQLite, SQL Server or Oracle) or MongoDB export of up to 1 GB as a reference file. Dualzo keeps only its structure and deletes the file if it held data rows. A live connection stays up to date by itself; an uploaded dump shows the structure as it was when you exported it.
- What happens to my data if I cancel?
- Nothing is deleted when a subscription ends — the workspace is gated until you subscribe again. Deleting your account removes your data on the schedule in the Privacy Policy.
- Who pays for model usage?
- Dualzo runs the models on its own provider accounts, so you do not need an API key. Usage is measured in credits as part of your Dualzo plan.