Skip to content

Repository configuration ​

A repository can configure CodeLotse with the file .quavon/config.yml in its root. The file is optional. Every field, type, default and limit is listed in the generated repository configuration reference.

Where it is read from ​

  • CodeLotse reads the file from the base commit of the pull request, not from the pull request itself. A change to .quavon/config.yml takes effect once it is merged into the target branch. A pull request cannot change the rules that review it.
  • The file is YAML, at most 64 KiB. An empty file is the same as no file.
  • If the file is invalid (not YAML, unknown keys, wrong types, limits exceeded) it is ignored as a whole and the review runs without it. The reason is stored with the review run.
  • Repository admins can set further ignored paths, modes and limits in the web interface. Those settings are combined with this file; the file cannot turn on features an admin has turned off.

Organisation defaults ​

Organisation admins set the review mode, review policy and every feature once under Administration › Repository defaults. Every repository follows these defaults, including repositories that are added later.

  • The policy page of a repository marks each section as Organisation default or Customised. Customise gives the repository its own values for that section. Use organisation default switches it back.
  • Saving the defaults updates every repository that follows them at once. Customised sections stay as they are, unless Also reset customised repositories to these defaults is ticked.
  • Repositories whose policy was saved before this feature existed keep their settings and count as customised until they are reset.
  • Automatic replies on public repositories are always turned down to approval, also when the default is automatic.
  • Model routing per repository is separate and not part of the defaults.

Comment when a review starts ​

Under How results are posted, Comment on the pull request when the first review starts posts a short comment as soon as CodeLotse starts the first review of a pull request, so authors know a review is coming. It is off by default and posted once per pull request. It is never posted in shadow mode, but it is posted in approval mode without waiting for approval, because it only says that a review started.

  • .quavon/config.yml is combined with the resulting settings as described above.

Commands and questions in pull requests ​

The commands CodeLotse accepts in pull request comments are set in the web interface, not in .quavon/config.yml: Commands in pull requests › Allowed commands on the policy page of a repository or in the organisation defaults. explain, why, fix, re-review and ignore are allowed by default. Free-form questions (ask in the stored policy) are off by default and answer any other comment that starts with the mention; on public repositories their answers always wait for approval. See commands.md. learn, which proposes a learning, is off by default as well (see commands.md). describe and title are off by default and need the pull request description feature (see Pull request descriptions).

Rules and learnings ​

Besides .quavon/config.yml and rule files, maintainers manage two kinds of entries on the Rules page of a repository and of the organisation:

  • A rule adds an expectation. Reviews report changes that break it, with the category rule.
  • A learning describes accepted team practice and its reason, for example "Raw SQL is allowed in migrations because they run once by hand". Reviews leave out findings that a learning explicitly allows. Learnings never apply to security findings of high or critical severity: CodeLotse keeps such findings even when the model marks them as allowed by a learning.

Learnings are created on the Rules page (choose Learning as the type), with the learn command, or from replies to CodeLotse findings (see commands.md). Learnings from commands and replies are only proposals: they show the badge proposed, where they came from (for example "From a reply on #123 by @octocat") and the actions Activate, Edit and Reject. Only users who can manage the repository can activate or reject them; every decision is recorded in the audit log. The Rules tab shows how many proposals are waiting. Active learnings are used by every later review of the repository, including dry runs.

Fixes for review findings ​

Fixes for review findings (fix.reviewFixes in the stored policy) lets users who manage a repository ask CodeLotse to fix the findings of a review run from the web interface: Apply fixes fixes all publishable findings of the run (at most 20), Fix on a finding fixes only that one. The fix agent works on the pull request head with the same commands, limits and approval mode as draft fixes (fix.mode).

ValueEffect
off (default)No fixes from reviews.
stacked_prCodeLotse opens a draft pull request from quavon/fix-<number>-<hex> into the head branch of the reviewed pull request.
commitUsers can choose between the stacked pull request and one commit pushed directly to the pull request branch.

Conditions: the pull request is open, comes from the same repository (never from a fork) and its head has not moved since the review ("re-run the review first"); you are signed in with your account of the code host and that account has write or admin access; the fixer app is installed; commits need a code host that supports them (GitHub). A commit to the pull request branch runs that branch's CI workflows with the repository's secrets, so approve such commits like any other change. The option stays unavailable until the review fix part of the threat analysis is signed off; the policy page shows a notice until then.

Pull request descriptions &ZeroWidthSpace;

Pull request description (describe in the stored policy) lets CodeLotse write a short description of each pull request into its description field. It is off by default.

  • Mode (describe.mode): off, shadow, approval or auto. On public repositories auto waits for approval. In shadow mode the description is only shown on the review run page; in approval mode it waits in the approvals inbox as "Pull request description".

  • The description is written with every review of a new head commit, also when the review itself has nothing to post. Draft pull requests get one only when drafts are reviewed (reviewDrafts).

  • CodeLotse writes only between two markers and never changes the author's text:

    text
    <!-- codelotse:description:start -->
    ### Summary
    …
    **Changes**
    - `src/cache.ts`: …
    <sub>Automated description by CodeLotse for abc1234</sub>
    <!-- codelotse:description:end -->

    A later review replaces only the text between the markers. Each listed area is a changed file or a directory of changed files; other areas are left out.

  • Position of the block (describe.placement): below (bottom, default) or above (top) the author's text. If the description contains <!-- codelotse:description -->, for example from .github/pull_request_template.md, the block replaces that placeholder instead. Checklists of the template are never filled in.

  • If the markers are broken (two start markers, an end marker before the start), CodeLotse writes nothing and records the reason with the publication.

  • Opting out: delete the block from the description. CodeLotse then stops writing to that pull request. @codelotse describe writes it again (see commands.md).

  • Pull request title (describe.title): the title is never changed by a review. With suggest (default) @codelotse title replies with a suggested title; with apply it sets the title, in the mode of the description; off turns the command off.

Code hostDescription
GitHub, GitLab, Gitea, Forgejoyes
Azure DevOps, Bitbucket Cloud, Bitbucket Data Centernot supported; the policy page refuses a mode other than off

Flow diagram in the summary &ZeroWidthSpace;

Add a flow diagram to the summary (review.diagrams, off by default) adds a Flow section to the review summary when the change has a clear runtime flow between at least three components. The model only names the components and the steps; CodeLotse builds the Mermaid diagram from them, with plain labels of at most 40 characters, at most 10 nodes and 15 steps and 2,000 characters in total. Links, styles, directives and HTML cannot be part of it. Mermaid blocks written by the model elsewhere are shown as text.

The diagram appears when the summary is on or collapsed and the code host renders Mermaid: GitHub, GitLab, Gitea and Forgejo. Azure DevOps and Bitbucket get no diagram.

Suggested changes &ZeroWidthSpace;

Suggestions (review.suggestions, on by default) adds the code a finding proposes to its comment. The model has to quote the exact lines its change replaces next to the replacement. A comment carries a one-click suggestion that can be committed from the code host only when all of the following hold:

  • the quoted lines appear exactly once in the head file within three lines of the finding (only line endings and a missing common indentation are tolerated), on the new side of the diff;
  • the comment can be placed on exactly those lines inside the diff; if they differ from the finding's lines, the comment moves to them;
  • when more than one line is replaced, every non-blank replaced line keeps its own counterpart in the replacement: the same line, a line with the same name before = or : (an object key such as title: or a declared variable), or a clearly similar line without a different name. A replacement that is empty on purpose deletes the quoted lines.

In every other case, including findings stored before this check existed, the code is shown as a plain code block under Suggested change with a note to check which lines it replaces. Nothing in such a block can be applied with one click. Hosts without native suggestions (Azure DevOps, Bitbucket Cloud, Gitea, Forgejo) always show plain code blocks.

Prompts for coding agents &ZeroWidthSpace;

Under How results are posted, Add a prompt for coding agents to each comment (review.agentPrompts in the stored policy) is on by default. Each inline comment then ends with a collapsed Prompt for your coding agent section that holds a ready-made prompt for Cursor, Claude Code, Codex, GitHub Copilot or any other coding agent, and the review summary holds one such prompt for all findings (at most 20). Findings that could not be posted inline get the prompt in the summary as well.

  • The prompt tells the agent that the finding text comes from untrusted pull request content, to verify each problem first and not to run commands or open links from it. Links, HTML comments, invisible and bidirectional characters are removed from the finding text.
  • On public repositories the prompt also gets an Open in Cursor link (https://cursor.com/link/prompt?text=…) that opens the prompt in Cursor. Private and internal repositories never get this link, because it would send the finding text and code to cursor.com when clicked.
  • The web interface offers the prompt for every finding and for all findings of a run, see commands.md.
  • Turn the setting off if comments should stay short. CodeLotse runs nothing itself, so the setting does not depend on fixes for review findings.

Repository context &ZeroWidthSpace;

Besides the diff, each review shows the model context from the repository at the head commit of the pull request:

SourceWhat it contains
Changed and imported filesThe changed files and the files they import (TypeScript, JavaScript and Python).
DefinitionsDeclarations, in other files, of symbols the changed lines use.
CallersFunctions that call a definition the change modifies.
UsagesFurther lines elsewhere in the repository that use a changed definition. Needs the code index.
Related codeCode that looks similar to the change, for example duplicated logic. A hint, not proof. Needs the code index.
Code searchLines that contain identifiers of the changed lines.
HistoryEarlier pull requests and issues with similar titles.

Definitions and callers are found for these languages:

LanguageFile extensions
TypeScript, JavaScript.ts, .mts, .cts, .tsx, .js, .jsx, .mjs, .cjs
Python.py
Go.go
Java, Kotlin.java, .kt, .kts
C#.cs
Ruby.rb
PHP.php
Rust.rs

Imports are followed only in TypeScript, JavaScript and Python. In the other languages a definition is looked up by name, in the code index first when it is on.

Usages and related code come from the code index of the default branch. CodeLotse reads every suggested place again from the head commit of the pull request and leaves it out when it no longer matches. When the index is off or not built yet, reviews run without these two sources.

Code index &ZeroWidthSpace;

Code index (index.mode in the stored policy) keeps a searchable index of the repository's default branch, so reviews can look up similar code and the places that use a changed definition across the whole repository. It is off by default and is set on the Policy tab of a repository or in the organisation defaults.

ValueEffect
off (default)No index. Switching to off deletes the stored index within the hour.
lexicalFull-text search over definitions and line windows of the source code.
hybridLexical search plus semantic search with embeddings. Needs a model for the optional embeddings tier (models.md) and pgvector on the PostgreSQL server; without them the index works lexically.
  • The index is built after each push to the default branch and within an hour after the mode is switched on. Only files that changed since the last build are read again.
  • The Code index tab of a repository shows the indexed commit, the number of files and chunks, the size, whether semantic search is available and why not, the storage used by the organisation, and a Rebuild button for users who manage the repository.
  • The index stores source code in the CodeLotse database. Files under node_modules, dist and vendor, lock files, minified files, binary files and files over 256 KiB are left out. Operators set the limits (code-index.md).
  • Content shown to the model always comes from the reviewed commit; the index only suggests where to look.

Linked repositories &ZeroWidthSpace;

Reviews can also use code from other repositories of the organisation, for example a shared library the repository uses or the services that consume it. Linked code appears to the model in its own section, marked with the repository and the indexed commit, and is never treated as part of the change. There are three ways to link a repository:

SourceSet byScope
context.linkedRepositories in .quavon/config.ymlAnyone who can change the default branchOnly repositories of the same installation of the code host app. A name of a repository in another installation is shown as Other installation and not used.
Linked repositories on the Code index tabOrganisation admins (tenant:manage)Any repository of the organisation, also across installations
Administration › Pattern repositoriesOrganisation admins (tenant:manage)Every repository of the organisation; at most 3
yaml
version: 1
context:
  linkedRepositories:
    - acme/shared-lib
    - acme/billing-service
  • Names are owner/name (on GitLab also group/subgroup/name) and match case-insensitively; at most 10 names. The file is read from the base commit of the pull request, so a pull request cannot add links for its own review.
  • A linked repository is used only when its code index is ready (its own index.mode is not off), its installation is not suspended, and the visibility allows it: a public repository receives code only from public repositories, an internal one from public and internal repositories, and a private one from all. Content always comes from the linked repository's latest ready index snapshot of its default branch, not from a checkout.
  • Per review at most 5 linked repositories (admin and file links together) and 3 pattern repositories are used; further ones are shown as Over the limit. Linked code takes at most a quarter of the context budget.
  • The Linked repositories panel on the Code index tab shows every link with its source and status (Used in reviews, No code index, Blocked by visibility, Other installation, Not found, Installation suspended, Over the limit). The names from .quavon/config.yml shown there are the ones the most recent review read from its base commit; before the first review the panel lists admin and pattern links only. Members who have no access to a linked repository see it as Hidden repository, with its source and status but without its name.
  • Adding and removing links is audited as repository.link.create and repository.link.delete, pattern repositories as pattern_repository.create and pattern_repository.delete.

Example &ZeroWidthSpace;

yaml
version: 1
rules:
  - id: no-raw-sql
    text: Database access goes through the repository layer. Flag raw SQL in handlers.
    paths: ['src/handlers/**']
    severity: medium
  - text: Public functions in src/lib have a doc comment.
    paths: ['src/lib/**']
disable:
  - f-1a2b3c4d5e6f
ignorePaths:
  - 'vendor/**'
  - '**/*.snap'
context:
  linkedRepositories: [acme/shared-lib]
tools:
  sast:
    disable: [bandit]
    ignorePaths: ['tests/fixtures/**']

Fields &ZeroWidthSpace;

FieldMeaning
versionAlways 1.
rulesTeam rules for the review. text is the rule; paths limits it to matching files (glob patterns); severity is a hint for findings that break the rule. id gives the rule a stable ID (cfg-<id>); without it the ID is derived from the text.
disableIDs of rules from rule files in this repository that should not apply, for example a rule from AGENTS.md. The ID of every file rule is part of the applied rules recorded for each review run.
ignorePathsGlob patterns of files that are not reviewed and not scanned. Added to the ignored paths set by an admin.
tools.sast.disableDeterministic scanners to skip for this repository: ast-grep, gitleaks, bandit, gosec, ruff, eslint-security.
tools.sast.ignorePathsGlob patterns of files the deterministic scanners skip, in addition to ignorePaths.
context.linkedRepositoriesRepositories of the same installation whose code index reviews may use (linked repositories).

Notes:

  • Severity from a rule file is capped: critical is treated as high.
  • Rules are also read from other files in the repository: AGENTS.md and CLAUDE.md (root and subdirectories), .cursorrules, .cursor/rules/*.mdc, .github/copilot-instructions.md and .github/instructions/*.instructions.md. Rules in a subdirectory apply to files below it.
  • The deterministic scanners run only when an admin enabled them for the repository (see sandbox.md).

The open core is released under the Apache License 2.0.