Skip to content
ErrorDock

AI root cause and fixes

How ErrorDock analyses an issue with repository context, how confidence is computed from checkable facts, and the four locks in front of any repository write.

Current availability: Repository writing is not enabled in the current beta setup. The approval and pull-request workflow below describes the implemented capability, not an active beta entitlement. AI analysis requires your own model key.

ErrorDock can read a production error, say why it happened and propose a validated patch. Opening a pull request is switched off in production during the beta: root-cause analysis and fix proposals work today, and the pull-request workflow described further down is built but not enabled.

Symptom            System.NullReferenceException in Shop.Api.CartTotals.Apply
Immediate failure  cart.Discount.Value was read while Discount was null
Root cause         A domain change made Discount optional without updating its readers
Confidence         78 / 100          ← ErrorDock's, computed from checkable evidence
Checks             applies ✓  structure ✓  build –  tests –  secrets ✓  review !

Everything on this page spends more effort on refusing than on producing. That is deliberate. Every other subsystem in ErrorDock is wrong in ways you can see — a query returns the answer or it does not, a percentile is a sketch and says so. A model is wrong in a way that reads exactly like being right: fluent, specific, citing a file and a line number, and completely invented.

Setting it up

AI features run on your own Anthropic or OpenAI key, configured per organisation under Settings → AI. That is the only mode: there is no ErrorDock-billed pool and no shared key. You also set the budget, and every provider request is recorded against it with its token counts and estimated cost.

Three separate grants control what is possible, and they are all off until somebody turns them on:

Grant Who
Analysis and fix generation Member, through ai.analysis.run and ai.fix.generate
Repository writes Admin only, through ai.source.write
Provider, key, policy and budget Admin, through settings.update

Three findings, never one paragraph

Conflating these is the characteristic failure of this whole category of tool, so they are three separate required fields:

Field Example
Symptom NullReferenceException — what you already saw
Immediate failure Discount.Value dereferenced while null — the operation and the value
Root cause A domain change made Discount optional without updating its readers

Only the third tells anybody what to do.

InsufficientEvidence is a first-class outcome with its own storage and its own screen treatment, recorded together with what would have settled the question. It is not a failure to be retried until it produces prose.

Evidence is verified before it is stored

Every citation is checked against data ErrorDock already held: a file must have been in the stack trace or actually read, a commit must be one of the deployment's suspects, a runtime value must be in the evidence summary that was sent.

A citation that does not check out is kept but not marked, and does not get to carry the file reference it invented. Keeping it matters — "487 of 503 events" is real evidence that came from the prompt rather than from a file.

The confidence score is ours

model confidence    0.95   ← what the model said about itself. Stored for evaluation. Never shown.
system confidence   78     ← computed from checkable facts. This is what you see.

A model asked how sure it is produces a number correlated with how fluent its answer was. Rendering that would be rendering fluency as certainty. What the screen shows is computed from whether an in-app frame mapped to a file, whether source was actually read, whether the runtime evidence supported the claim, whether a suspect commit exists, and how many occurrences there are.

The score is allowed to disagree with the prose, and it does.

Fix proposals

Nothing in the generation path applies anything. ErrorDock reads the files the analysis cited, asks for edits, applies them in memory, classifies every path, scores the risk, validates, and stores the result.

Edits are search-and-replace, not a diff and not whole files:

Format How it fails
Unified diff Line numbers reconstructed from memory, applied by fuzzy matching — the machinery that quietly applies a hunk to the wrong place
Whole-file bodies Costs the entire file in output tokens, and every untouched line is a transcription risk
Search-and-replace Costs only what changed, and fails cleanly: the anchor appears exactly once, or it does not

An anchor matching twice is refused as ambiguous; an anchor matching zero times is refused as stale. Picking the first match is how a tool edits the wrong overload of a method and produces a patch that compiles and is wrong. Only files the model actually read may be modified, and that is enforced by the applier rather than asked of the prompt.

Path policy

Classification Examples
Forbidden .env, *.pem, *.key, *.sql, id_rsa — the redactor stripped their contents, so any edit would be written blind
Forbidden package-lock.json, go.sum, Cargo.lock — written by the resolver that produced them
Restricted .github/workflows/, /infra/, Dockerfile, migrations, package.json — legitimate to change, with review
Allowed Everything else, including tests

A manifest says what the project wants and is a reasonable thing to change; a lockfile says what a resolver produced and is only ever correct if the resolver wrote it.

Validation

Six stages, each stored as its own row: does it apply, is the structure intact, does it build, do the tests pass, does it introduce a secret, and what does a second model think of it — a reviewer that has not seen the first opinion.

Anything that could not be checked is reported as unavailable, which is not a pass. ErrorDock does not run your test suite: a sandbox executing arbitrary repository code is a different product with a different security review. The build and test stages are configured seams, and they say so rather than pretending to have run.

The four locks on a repository write

Lock Owned by Default
The installation's repository-writes switch Whoever runs the server Off
The organisation's pull-request setting Your administrator Off
The ai.source.write permission Whoever grants roles — Admin, not Member —
An explicit request carrying an idempotency key Whoever presses the button —

Immediately before the write, every time, ErrorDock rechecks whether the files this patch was written against have moved — and produces the content that will be committed from that check. There is no other way to obtain it, which is what makes the check impossible to skip by accident. A patch whose files moved is marked superseded rather than retried.

The branch name derives from the issue id and nothing that can change:

errordock/fix-3f2a1b4c5d6e

All files go in one commit through the Git Data API, because a patch is a unit: a build that briefly saw half of it is a build nobody asked for. The commit is attributed to ErrorDock and records who authorised it — never the other way round. A commit attributed to the developer who pressed a button is a lie in git blame, in the one place a team most needs the truth.

Nothing merges. There is no merge method, no auto-merge policy and no plan for one. Branch protection is never bypassed; a rejection from a protection rule is reported as blocked, which is your own configuration doing exactly what you set it up to do.

Untrusted input

Everything arriving from your application — exception messages, breadcrumbs, request data — is attacker-influenced text. The defence that matters is the one that does not depend on the model behaving: the applier will only touch files the model actually read, forbidden paths are refused outright, and nothing reaches a repository without a person confirming it.

Quotas

Limit Default
Analyses per organisation per hour 60
Fix generations per organisation per hour 20
Files in a patch before it needs a human decision 5
Changed lines 300

Audit

Every machine action is attributed to an automation actor, not to a person:

ai.configuration_updated   ai.analysis_started      ai.analysis_completed
ai.repository_files_read   ai.fix_generated         ai.fix_validated
ai.branch_created          ai.commit_created        ai.pull_request_created

ai.repository_files_read records the list of paths, not their contents. The question it answers is "what of ours left the building"; storing the source would make the audit log a second copy of the repository.

Deliberately absent

Auto-merge at any risk level. Autonomous remediation. A chat interface over issues. Running your tests. Executing migrations. Fine-tuning or training on your data. "Explain this code" without an issue behind it. GitLab, Bitbucket and Azure DevOps. Background queued analysis.

There is no chat box and no free-text prompt: every model call is one bounded operation with a stored result somebody can read afterwards.

Last updated October 20, 2026