Overview
Business Logic Validation checks that a pull request delivers what its task asks for. Kody finds the task the PR references, reads it from your task tracker, and lists every requirement with where it stands in the code. The result is one comment on the PR, kept up to date, the same on GitHub, GitLab, Bitbucket, Azure Repos and Forgejo. What the comment looks like on a PR that delivers part of its task:Kody · Business Logic #291 · Ticket SLA badge — To fix: 2 missing requirementsAfter the fix, the same comment reads “All requirements met · ✅ 3 of 3 met”, with the earlier check kept below it.
Prerequisites
- A task tracker connected in Plugins: Linear, Jira (Atlassian Rovo), Notion, Git Issues, or a custom plugin.
- Kody only reads tasks by their id, and what they link to (a parent, sub-tasks, attached documents). It never searches for a task or writes to your tracker.
- Without a tracker, you can still paste the task text in the command (see below).
Turning it on
Business Logic is on by default. Turn it on or off in Code review → What to review, on the Business Logic row, or inkodus-config.yml:
How Kody finds the task
Kody looks for task references in the PR title, branch name and description, in that order:- Keys like
PROJ-123(Jira, Linear and most trackers) #123andowner/repo#123(Git issues; a number that is a pull request is ignored)AB#123(Azure Boards)- Links to Linear, Jira, Notion, GitHub/GitLab issues and Azure work items
UTF-8 or gpt-5 in a title are never mistaken for tasks. A lower-case key in the title (feat(kod-10)) counts when your tracker has that team or project; a Linear project id (P-KOD-1) never does.
Kody also reads what the task links to:
- A parent (a Linear sub-issue, a Jira sub-task, a ClickUp subtask): the PR is checked against the parent’s requirements this task’s title covers. A sub-issue that says “see the parent” is still checked.
- Sub-tasks: a requirement one of them delivers shows as CHECK MANUALLY (“Delivered by KOD-20”), never as missing.
- Documents attached to the task (Linear docs): read as part of the task, criteria included.
How the PR names the task
- “Closes PROJ-1” or a key in the title or branch: the PR is checked against the whole task.
- “Part of PROJ-1”: the PR delivers a slice. What’s missing is listed, but not as something to merge.
- “Refs PROJ-1”, “see PROJ-1” or “related to PROJ-1” in the description: a mention. It is checked only when the PR names no other task, and then as the PR’s own.
- Up to three tasks are checked per PR, one section each. A PR that states more (a release or a merge) is skipped.
The five states
Every row cites the file and line it is based on, and says what to change.
Before a gap is shown
A gap tells the author to redo work, so Kody holds each one to the code:- The requirement as the task writes it. An input or edge case the task never names (negative amounts, another code path, a format it doesn’t mention) never makes a row PARTIAL, and neither does what happens after the change (that an existing job sends the message the PR queues, that a route uses the serializer the PR fills in).
- The code the PR calls, not only the diff. When a rule lives in code the PR calls but didn’t change (a validator, a helper, the mapper that builds a response), Kody reads it in the repository at the PR’s head before anything is shown, and does the same for every MISSING, PARTIAL and CHECK MANUALLY row. A row turns MET only on a file and line Kody read, and says it is already in the code, outside the diff. A row turns MISSING only when Kody read the code the PR relies on and cites the line that lacks the rule. Whatever the repository doesn’t settle stays as it was.
- Work that belongs elsewhere. A requirement a sub-task delivers, or one your team guidance says isn’t checked here, stays CHECK MANUALLY and is never re-judged as missing.
On the pull request
- Kody checks the PR on its first review. After that it re-checks when someone comments
@kody -v business-logicor runs@kody review --force. Re-check can also be set to each push while something is missing, so a fix updates the comment without anyone asking, or to every push; each is one more validation per push. - Re-check any time with
@kody -v business-logic. The same comment is edited; Kody never posts a second one. - A PR that meets its task gets a one-line comment (”✅ 4 of 4 met”), plus anything to check by hand, so the author knows it was checked. Turn off Comment when every requirement is met to stay quiet on those.
- The comment is the signal on every platform: Kody doesn’t write a check or a status, so it never blocks a merge by itself. Its header says what is left to fix.
Replying to the comment
Reply to the Business Logic comment and mention@kody. Kody reads a comment as a reply when it is posted in that comment’s thread (GitLab, Bitbucket, Azure Repos), quotes it, or names the requirement, its state as the comment writes it (MISSING, PARTIAL) or the task id; any other comment goes to the chat.
- Disagree: “It’s covered in
useDrag.ts”. Kody re-checks what you pointed at and either marks it MET or says what it looked at and keeps it. - Accept a finding (someone other than the PR’s author: on GitHub, with write access to the repository; on GitLab, Developer or above on the repository; on Bitbucket, Azure Repos and Forgejo, a member of the organization the platform lists): “Keyboard reordering is out of scope, moved to SAA-102”. Kody confirms SAA-102 exists, marks the row ACCEPTED with who accepted it, and it is no longer left to fix. The decision stays on later re-checks, even when Kody words the requirement a little differently, as long as the task’s text is unchanged; once the task is edited, the requirement has to be accepted again.
When Kody stays quiet
Kody comments only when the author can do something about it:
The reason for every skip is recorded and shown on the Business Logic settings page.
Running on demand
Comment on the PR (not on a line of code):@kody -v business-logic: re-check the tasks the PR references@kody -v business-logic PROJ-123or a task link: check against that task@kody -v business-logicfollowed by the requirements as text: check against what you wrote, no tracker needed
Settings
Open Code review → What to review and click Business Logic (or ⋯ → Edit). Every setting can be set globally and overridden per repository or directory.- Task source: every connected tracker (custom task plugins like ClickUp included), or one plugin. For a custom plugin, pick the tool that reads one task by its id; only read-only tools are offered. Use Try it, pinned on the right of the page (it needs permission to edit these settings): a task alone shows what Kody reads from it, and a pull request runs the whole check without posting, with the settings on screen, saved or not. Post to the pull request posts the result shown, without running it again, once per test; it refuses when the pull request got a commit after the test, so run the test again first.
-
Custom task id format (optional): a regular expression for ids Kody doesn’t find on its own:
T(\d{4})readsT1234as task 1234. Keys likeSAA-96,#12,AB#8,CU-…and tracker links are found without it, and so is a lower-case key likesc-123in a branch name. In a title or description a lower-case key counts only when Linear or Jira has that team or project; for another tracker, set the format. A number the format captures is read as a Git issue only when Git Issues is the task source; with every connected tracker,T1234is never issue #1234 of the repository. -
Where acceptance criteria live: detected automatically (a criteria field, a checklist, or a list in the description), under a heading in the description, or in a custom field; a task without the field is read from its description. With Under a heading set to
Acceptance criteria, this task is checked against its three bullets, and the paragraph above them is context: - Comment when every requirement is met (on by default): a PR that meets its task gets a one-line comment. Off, it gets none; gaps are still posted.
- Ask for a task when the PR references none: Kody comments asking which task the PR is for (or pointing at the typo), instead of skipping it. PRs opened by bots, like Dependabot or Renovate, are left alone. A tracker that is down never counts.
- Re-check: only on request (default), each push while something is missing, or every push. Each check runs on your organization’s model like a review does, so every push costs one validation per push.
-
Skipped pull requests: the ones code review skips are skipped here too: titles with an ignored keyword (
ignoredTitleKeywords, likewip) and drafts whenrunOnDraftis off. A@kody -v business-logiccomment always runs. - Team guidance: notes Kody follows when it judges, for example “Feature flags count as implemented when the flag exists and defaults to off”. It can’t change the verdict format or make Kody invent requirements.
Common setups
The same settings in
kodus-config.yml:
From the CLI
A coding agent can check its work before opening the PR:--format json (or --agent) it prints the same verdict structured, for an agent to act on. Nothing is posted to a pull request.
Cockpit
Cockpit → Delivered as asked shows the share of PRs that met their task, changes not in the task, how often developers agreed with Kody, and the split by who wrote the code (people or coding agents, from commit authors andCo-Authored-By trailers) and by team. It follows the Cockpit’s repository picker, and can be hidden in Organization → Cockpit like the other tabs.