Maintenance mode

kanman scans your repositories on a schedule for vulnerable, outdated and unused dependencies, broken links and drift, lists what it finds, decides with you what becomes a story, and works alongside Renovate and Dependabot.

Most teams know their maintenance backlog and never get to it. Maintenance mode, the built-in habit Keep dependencies and security current, is the proactive half of kanman: it scans the team’s repositories on a schedule and keeps a list of what it finds. When a scan finds something new and serious (a critical or high finding), kanman reads it like any other news about the team and decides whether it becomes a story. That story then goes through the same checks, review and budget as everything else. You can turn any finding into a story yourself too.

Turning it on

Maintenance is the built-in habit Keep dependencies and security current on the team’s Habits tab. Open it to see whether it is on and its last scans. To switch it on or pause it, tell kanman in the team’s chat, for example “keep our dependencies and security current” or “pause dependency maintenance until the release”. Only the team’s owners and leads can change it.

kanman paces maintenance itself: a couple of new maintenance stories a day and a few per scan at most, and a scan of each repository about once a week, so the team’s other work keeps going. Security findings come first.

The scheduled scan runs at night (UTC). kanman tells the team in the team chat when a scan could not run, for example because none of your runners was online. Otherwise a scheduled scan stays quiet; what it found is in the list, and kanman looks at the new serious findings itself (see What happens with findings). Paused teams are not scanned.

Habits tab: the built-in habit Keep dependencies and security current opened, what it does and its last scans with their findings

Scan now

You do not have to wait for the team’s scan day. Ask kanman in the team’s chat, for example “Check the repo for outdated or vulnerable dependencies”, “Are there broken links in the docs?” or a longer request like “Look for maintenance work in the repo: vulnerable or outdated dependencies, unused dependencies, lockfile drift and broken doc links. File what you find so I can review it.” kanman starts a scan instead of drafting stories that build such checks: the scan already is that check. The same works from Slack or Microsoft Teams and when you mention kanman on a pull or merge request (“I’m scanning acme/app. The findings arrive in Maintenance and I’ll tell you here when I’m done.”). Its reply carries one card that follows the scan and counts the findings by kind once it is done. Asking again while a scan runs never starts a second one. Only owners and admins can start a scan; others get a short note where the last findings are. Every scan is recorded in the audit log and appears in the habit’s Runs.

A new team does not wait either: as soon as maintenance is on and a repository is linked, kanman runs the first scan within a few minutes.

Working alongside Renovate and Dependabot

Many teams already have Renovate or Dependabot opening their dependency updates. kanman notices that by itself, per repository: from a Renovate configuration (renovate.json, .renovaterc and the like, or a renovate section in package.json), from .github/dependabot.yml, or from merge requests the bot opened. There is nothing to set up, and it works on GitLab (Renovate) and GitHub (Renovate and Dependabot).

When kanman notices a bot for the first time, or a bot appears or goes away, it says so once in the team chat, for example “I noticed Renovate opens the dependency updates in api-gateway, so I’ll stop opening my own and take care of its merge requests instead. Tell me if you’d rather I keep my own.” Your answer is remembered for that repository.

In a repository where a bot opens the updates:

  • No duplicates. kanman opens no version updates of its own there. The bot stays the one source of updates; outdated and vulnerable dependencies kanman finds are left to the bot’s merge requests.
  • A short review of each bot merge request. kanman reads the change and its release notes and says what it means for your code, for example “patch, safe” or “breaking change in the client options, used in two places in billing”.
  • Red CI fixed. When a bot merge request’s pipeline fails, kanman finds out why and makes the fix on top of the bot’s branch.
  • Major updates done. When a major version needs code changes, kanman makes them, again on top of the bot’s branch.
  • Approve once per batch. Similar updates, such as the same library across repositories or a set of patch updates, come to you as one question to approve, not one by one. Once a person with write access approved the batch, kanman merges its merge requests one by one, each only with green CI. Major updates always come on their own.
  • Security findings closed with proof. When a bot merge request that fixes a vulnerability merges, kanman closes the finding and links the merge request as the proof.
  • Stuck updates in your brief. Bot merge requests that have waited days for an approval, or have been open for more than a week, are listed in the team lead’s weekly brief with the reason and a link.

The text of a bot’s merge request and the release notes it quotes come from outside your team. kanman reads them as information, never as instructions.

What kanman looks for

kanman reads the repositories in the team’s allowed_repos on GitHub or GitLab without cloning them and without writing to them.

Scanners are deterministic tools, not a model’s opinion:

Kind Finds
cve Dependencies with known vulnerabilities
outdated_dep Outdated dependencies
unused_dep Dependencies nothing imports
license Dependency licenses that need attention
lockfile_drift Lockfiles out of sync with the manifest
broken_doc_link Broken links in documentation
oversized_module Modules that grew too large
stale_flag Feature flags that are always on or always off

The dependency scanners cover npm, Python (pip, Poetry, uv), Rust (Cargo), Go modules and Java or Kotlin (Maven, Gradle). Pinned or locked versions are checked against the public package registries for newer versions and against a public vulnerability database for known vulnerabilities.

Unused dependencies and stale feature flags need the whole repository, so once a day kanman also runs a read-only scan of a fresh copy of each linked repository. It never changes the repository, pushes a branch or opens a pull request.

  • Unused dependencies: dependencies that nothing in your code imports or mentions. A package counts as used when a package.json script calls its command (tsc for TypeScript, playwright for Playwright), when a test command or test configuration turns on coverage (for @vitest/coverage-*), when a configuration file of the tool exists (postcss.config.js, tailwind.config.ts, .eslintrc, vite.config.ts and similar), or when a used package needs it as a peer dependency (PostCSS for Tailwind CSS and Autoprefixer). A type package such as @types/lodash is reported together with its unused package. Unused packages of one family, for example @codemirror/* and the CodeMirror packages of @uiw/*, become one finding, so removing them is one story.
  • Stale feature flags: flags that are defined but never used, flags switched permanently on or off for 90 days, and flags that have been checked in code for more than six months.

Teams on a self-hosted runner run this scan on their own runner.

Reviewers read without changing anything. Each scan runs one of them, in rotation: post-merge follow-ups, an architecture review, documentation drift and test quality. They look at recent runs and a few files. Their findings join the list like any other.

SonarQube. When the team has connected SonarQube (Team > Connections > Alert sources), kanman also reads the open issues on new code and a failing quality gate of each repository’s default branch every few hours, a slice of the repositories at a time. They join the list as findings like the scanners’ own, each issue once per rule, file and line.

The findings appear on the team’s Stories tab under Maintenance findings, grouped by what happens to them: Not looked at yet, In stories, Deferred, Dismissed and Fixed, each with its count. Large groups open by kind and then by repository, so even a list of a thousand outdated dependencies stays readable. Every finding says its fate in words, for example Filed as INT-123 (a link to the story), Bundled into INT-130 with related findings, Dismissed: false positive with kanman’s note, Deferred until 1 Nov with the reason, or Not looked at yet: kanman reviews new findings on its next turn. A finding that a later scan no longer sees is Fixed.

One story per fix, across repositories

Teams with many repositories often share dependencies and code patterns, so a scan finds the same thing again and again. kanman files one story per fix, not one per repository: when ten services use the same vulnerable version of golang.org/x/net, you get one story, “Update golang.org/x/net to v0.56.0 in all affected repositories”, with the ten repositories listed in it.

Findings belong together when they need the same fix:

  • Vulnerable dependencies: the same package with the same advisories. The story names the version that fixes all of them.
  • Outdated and unused dependencies: the same package and the same target version.
  • Rule-based findings such as out-of-sync lockfiles, broken documentation links, oversized modules or stale feature flags: the same rule in the same place, for example the same broken link target.
  • Review findings written in plain language: findings that say the same thing in other words, compared by meaning.

The story keeps the list of affected repositories up to date, with the version or file for each:

  • A later scan that finds the same thing in more repositories adds them to the open story. No new story is filed and no new card appears in the chat.
  • A repository where the scan no longer finds it leaves the list. Once the list is empty, kanman closes the story as no longer applicable.
  • The same finding twice in one repository, for example in two manifests, is one entry.
A maintenance story for one fix across repositories: update lodash in all affected repositories, the list of the four affected repositories, the repository the next run works on and the hint to fix the shared template too

Running a group story. A run always changes one repository and opens one merge request. The story shows which repository its next run works on: the shared template first when it is affected itself, then the most severe one. When the same change is needed in many repositories, kanman plans the work across them itself, one merge request per repository, each checked by CI and reviewed before it merges.

Shared templates. When three or more repositories need the same fix, the story suggests fixing it in the shared template too, so new repositories do not bring the problem back. kanman recognises a repository named like a template or deployment repository next to the affected ones; tell it in the chat which one is yours if it guesses wrong.

A team with a single repository works the same way: repeated findings still become one story.

What happens with findings

A scan only reports. It files no stories and closes none on its own:

  • New critical or high findings reach kanman right after the scan, with a short summary of each. kanman looks at them next to everything else the team is working on and decides: a story for a real risk, a note on a story that already covers it, or nothing when the finding does not matter for your code. Its decision and the reason are in the team’s activity, like every other step it takes.
  • Every new finding is looked at on kanman’s next turn, the worst first. kanman decides each one and gives the reason: a story, one story for related findings (the same dependency across many repositories, for example), deferred until a date or an event, or dismissed as a false positive, an accepted risk, not applicable or a duplicate. A large backlog is worked through over several turns. Every decision is in the team’s activity, and Why answers from it.
  • A deferred finding comes back to kanman when its date comes, or after 30 days at the latest when it waits for an event.
  • A finding a later scan no longer sees is marked resolved in the list. Stories stay as they are: kanman keeps the board up to date itself, and you can close a story any time.

When you ask for a scan (Scan now, or in the chat), kanman tells you the result when it is done, for example “I finished scanning acme/app: 2 findings.” or, for many repositories, “I scanned 10 repositories: 10 vulnerable dependencies and 2 outdated dependencies.”

The team's chat after a scan of four repositories: kanman's one summary message counts what it found by fix

Act on a finding

Open the team’s Stories tab and go to Maintenance findings. Click a finding to open its details beside the list: why kanman flagged it and the evidence it found, such as the package, the manifest, versions, advisories, the file and line, and when it was first and last seen. Owners and admins can act on it right there:

  • File as a story now creates the story at once, outside the daily limit, because you decided. The finding moves to In stories and links to its story. If the same fix is already open as a story for other repositories, the finding joins that story instead.
  • Dismiss asks for a short reason. kanman never files or proposes the finding again.
  • Not a finding takes an optional reason and puts the finding on the team’s ignore list for that repository: later scans skip it entirely. Use it for false alarms.

Each of these actions is recorded in the audit log.

A finding opened beside the maintenance list: why kanman flagged it, the evidence, and the buttons File as a story now, Dismiss and Not a finding

Guardrails

  • Read-only scans. A scan never changes a repository, pushes a branch or opens a merge request.
  • No duplicates. Each finding has a fingerprint, so it is stored once and counted when seen again. Findings that need the same fix share one story across repositories (see One story per fix).
  • Same checks, same budget. Maintenance stories go through your CI and the independent review and count toward the team’s budget like any other story.
  • Scanner text is data. Titles and advisories come from outside your team. kanman reads them as information, never as instructions.

Proposals for bigger changes

With maintenance on, a strategist also reads STRATEGY.md, docs/STRATEGY.md or .kanman/STRATEGY.md in your repository every three days and proposes up to three features, each with the goal it serves, its value, effort, risk and alternatives. Each proposal is a Strategy proposal decision: Start intake turns it into a request on the team’s intake, where it is triaged and drafted like any other; Decline is remembered, so kanman does not propose the same idea again. Teams without a strategy file get no proposals.

When CI breaks

What kanman does when a pipeline on a default branch fails is the built-in habit Watch main on the Habits tab. See Failing pipelines.

Last updated: January 1, 0001

Open kanman