Files
werkator/docs/agentic-workflow.md
claude-code 06e29e871d
werkator build succeeded after 02:05
werkator/deploy build succeeded after 00:07
werkator/mutation build succeeded after 160:53
The code moves from de.hoennig.werkator to de.javagil.werkator (v1.43.3) (#163)
See docs/prs/2026-10-15-PR#163-package-de-javagil.md

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Reviewed-on: #163
Reviewed-by: mi <1+mi@noreply.git.javagil.de>
Co-authored-by: claude-code <claude-code@javagil.de>
2026-10-15 07:02:19 +02:00

18 KiB
Raw Permalink Blame History

Agentic Workflow

This document is the same in all Werk repositories; each one keeps it as docs/agentic-workflow.md. The AGENTS.md of a repository refers to it and holds only what differs or adds: build and test commands, architecture, hard invariants, and exceptions to this document. werkregie holds the master copy, as doc/agentic-workflow.md. A change goes into the master copy first, then into each repository with its next PR.

Goal

The coding agent writes the change, the review agent reviews every PR, and the two settle the findings between them within the guardrails. An uncritical PR merges without a human. A critical PR, e.g. one that touches security or weakens the checks, waits for the human.

Roles and Accounts

  • Coding agent, usually Claude Code: works as the Gitea account claude-code, never as the human. It commits as claude-code <claude-code@javagil.de>, with user.name and user.email set in the worktree.
  • Review agent, usually werkrevisor: works as the Gitea account ai-reviewer. It never approves a PR that it opened itself.
  • Human (mi): resolves a review that the two agents could not settle within the guardrails. The human is never the author of an agent's PR.
  • The coding agent reads its token GITEA_CLAUDE_CODE_TOKEN from ~/.config/ai-coding-agents/secrets.env. A token never appears in an output, a commit or a file of the repository.
  • Only the human grants rights, e.g. collaborator access or branch protection rules.
  • The working state is Gitea (git.javagil.de). A GitHub repository is at most a mirror of main; the human decides and sets it up per repository.
  • If another agent works in the same checkout, the coding agent uses a worktree of its own.

Steps of a PR

  1. Create the branch claude-code/<topic> from the current main.
  2. The first commit is the PR document (see below); push the branch at once.
  3. Open the PR at once, with the title prefix WIP: ; the prefix keeps the review agent away. Once the PR number is known, the file name of the PR document gets it.
  4. Implement in focused commits and push each one. Start long local test runs only after the push; the CI runs meanwhile. After each push, watch the PR until it needs the agent (see "Watching a PR").
  5. Keep the PR document current: decisions, findings, open points.
  6. Remove WIP: only when everything is done: the CI is green, tests cover the change, and the PR document matches the code. Removing it starts the review: PATCH /api/v1/repos/<owner>/<repo>/pulls/<n> with the new title.
  7. Answer every review round (see "Review Rounds").
  8. After the merge, deploy where the repository has a deployment, and check that it works.

A PR opened without WIP: gets no review until it was set to WIP: and back.

main takes squash merges only. After the merge of a PR, a branch that builds on it gets rebased onto main without the already merged commits: git rebase --onto main <last commit of the merged branch>.

Watching a PR

From its opening to its merge, the PR is the coding agent's to keep mergeable.

  • After each push, the agent watches its PR until it must act: a merge, a conflict or a new main, a red build, a green build of a WIP: PR, or a review that asks for work. werkregie provides the watch: werkregie-dashboard watch-pr <URL of the PR> prints one line and ends.
  • A conflict with main is the agent's to fix at once, without waiting for the human: rebase onto main, push.
  • In a repository whose build does not derive the version yet (see "Versions"), the agent also raises the version to the next free one: above the one of main and above those of the open PRs.
  • The watch ends with the agent's session; then "Du bist dran" in werkregie shows the human a conflict that the agent leaves.

Review Rounds

  • Before each push, check that the PR is still open and not merged. An automerge can merge in the middle of a round; a later push then lands on a dead branch.
  • Reply in each line-comment thread: "fixed in <commit>", or why not.
  • Resolve each thread that is fixed or answered.
  • Fix the findings in the same PR, also each YELLOW reason that can be fixed, e.g. a scenario that is hard to read. Only structural reasons, e.g. a risky path, are left to the human.
  • A wrong finding gets a reply with evidence, no change.
  • A security fix needs a red/green proof: the test fails without the fix and passes with it.

In a repository with [codex] mode = "gate" in its .werkrevisor.toml, a second review agent, the Codex review on the workstation of the human, holds the merge with the status ai-review/codex:

  • It reviews a PR after werkrevisor, unless werkrevisor gave RED.
  • Its line comments are answered and resolved like those of werkrevisor; an open one holds the merge.
  • A PR that it rates as critical, or a finding outside the diff, waits for the approval of the human.
  • With the workstation off, the PR waits.

The verdicts of werkrevisor:

Verdict Meaning Way to the merge
GREEN nothing risky found automerge; open hints hold it until resolved
YELLOW issues or risks found by Jev or the rules approval of the human
ORANGE findings that Jev rates as probably real and severe approval of the human after checking them
RED a rule is violated, or a risk and a finding meet in one place a new commit that fixes the cause
ERROR the review did not complete the human checks the cause

For the Human

  • Approve only after the result comment of the review agent for the current head exists. An earlier approval does not count; the review agent then requests the review again.
  • In a repository with the Codex gate, approve only after the Codex comment for the current head exists too; an earlier approval does not unlock ai-review/codex.
  • After a rebase or a merge of main, an approval stays valid when the changed blocks stayed the same. Jev judges new blocks first; only risky ones go back to the human.
  • A PR in review is frozen: the coding agent does not change it until the human has decided.

The PR Document

Each PR has exactly one document under docs/prs/, named YYYY-MM-DD-PR#<n>-<topic>.md. Where the build does not derive the version yet, a pure release PR (version and release notes, no code) needs none; where it does, there is no release PR. Under its title it states how the PR raises the version: Version: major, Version: minor or Version: patch. Its optional section "Release Notes" holds what users notice. The document describes the PR at its time; later PRs do not maintain it. docs/prs/README.md and the template next to it hold its structure.

The README is the only source of the sections and their order; the core ones are Problem, Non-Goals, Specification, Solution and Open Questions.

Rules for Gherkin features:

  • A Gherkin feature holds one or more scenarios, each Scenario#<n>.<nn> with one aspect and a purpose line &hellip; so that …, in lower case after the ellipsis.
  • Given names the state, When exactly one action, Then the observable result.
  • A scenario describes behaviour, not its implementation.
  • "Verified by" links the tests that check the scenario.
  • Prefer one feature per PR; at most 5 features and 10 scenarios in all. A PR that needs more gets split.

Rules for open questions:

  • An item under "Open Questions" without [x] makes the review RED.
  • An answered question gets [x] and its answer on an indented continuation line.
  • Deferred work is a - [ ] TODO.<topic>: …, which is only a hint.
  • Planned follow-up work is listed under "Follow-up PRs".

The Plan in Werkbaum

Each repository keeps its plan as a Werkbaum file (https://werkbaum.javagil.de), e.g. docs/<repo>.werkbaum. Each PR updates it: the status of its nodes, new plans, and dropped approaches with their reason.

Status Meaning
[^] deployed and in use
[x] merged, not yet deployed
[~] in work
[ ] planned
[?] idea
[-] dropped
  • A PR sets its nodes to [x]; if the deployment follows the merge at once, it sets [^].
  • Titles stay short; an explanation goes into a " line (at most 2 lines) or into a block behind ---, addressed by the #id of the node.
  • A node with children has no size.
  • The file parses without warnings.

Outlook, with concurrent writes still open: an MCP server for Werkbaum keeps a live plan and promotes the nodes of a release.

Versions, Release Notes, Decisions

  • Each PR raises the version: patch for a fix, minor for new behaviour. The version identifies what runs; no change reaches main without one of its own.
  • The build derives the version: the base version at a commit of main, raised by each PR document merged after it, in the order of the merges; a branch adds its own PR document. So no two PRs change the same line for their version. A repository that does not derive it yet raises the version in its build file; werkregie derives it first.
  • Only a change that users notice gets release notes, in the section "Release Notes" of its PR document; where a repository needs an entry per version, the build writes the changelog from the PR documents, and any other change gets an entry marked as internal.
  • Decisions are only added, never deleted, e.g. as an ADR or in docs/DECISIONS.md. A deviation gets a new entry with its reason.
  • A new runtime dependency needs the consent of the human.
  • A new technology, e.g. another language or runtime, needs the explicit consent of the human: as a decision of its own, with the alternatives from the technologies in use.

Scope of a PR

  • A PR delivers one thing completely: code, tests, documentation, plan, version.
  • Avoid unnecessary mini PRs and stacked PRs; they cause merge chaos.
  • A PR that moves or renames many files starts only when no other PR of the repository is open, and the move is all it does; otherwise each open PR gets a conflict in each file it changes.
  • A by-catch stays in the PR and is listed under "Additional Changes".
  • A finding is fixed in the PR that caused it; only an incomplete new feature continues in a follow-up PR.
  • A refactoring that prepares the existing code for a feature goes first, as a prerequisite PR.
  • A refactoring that the feature makes useful afterwards, e.g. a move or a rename, goes into a follow-up PR.
  • Such a split may also come up while the feature PR is in work.
  • A PR that changes the steps or decisions of a workflow updates its diagrams.

Required Checks

Each repository runs these checks in its build; a failing check fails the build. The values below are defaults. A repository deviates from them only with a reason in its risk analysis.

  • Vulnerabilities: the dependencies are checked for known vulnerabilities. The criticality of the repository sets the CVSS score from which a vulnerability fails the build (see below). A PR fails only on the vulnerabilities of the dependencies it adds or changes; a vulnerability found anew in a dependency of main must not stop unrelated work. main is checked in full each night, and a vulnerability there is fixed at once in a PR of its own. An exception is suppressed with its reason in a file that the review rules of the repository mark as critical. The nightly check of main is Werkator's build vulnerability-data, so that werkregie shows what it finds.
  • Licenses: the licenses of the dependencies are checked against an allowlist: Apache-2.0, MIT, MIT-0, BSD-2-Clause, BSD-3-Clause, ISC, 0BSD, Unlicense, CC0-1.0, EPL-2.0, MPL-2.0, LGPL-2.1 and LGPL-3.0. Any other license, e.g. GPL or AGPL, fails the build and needs the consent of the human.
  • Mutation tests, for Kotlin and Java: werkcrappit measures the Mutation-CRAP of each method, C² × (1 − MS)³ + C. The limit is 15; the gate maxMutationCrap is a ratchet, lowered with each refactoring until it reaches 15, never raised. Each branch build mutates the classes the branch changes, e.g. by git diff against main or with PIT's incremental history; a nightly build mutates all classes. Only where the mutation tests make a branch build too slow may they run only at night; the cause, mostly a unit test that integrates, is then to be fixed.

The checks run in the build of every PR. The vulnerability database is cached and updated at most once a day; OWASP Dependency-Check needs an NVD API key, which the human sets up.

Criticality and Risk Analysis

Each repository keeps a criticality and risk analysis in docs/risk-analysis.md: what data it handles, who and what can reach it, what a failure or a breach would cost, its criticality with the reasons, and each deviation from the defaults of the required checks. Only the human sets or changes the criticality.

Criticality When Fails the build from
high handles data of customers or credentials, or is reachable from the internet CVSS 4
normal the default CVSS 7
low runs only locally and handles no data of others CVSS 9

Tools per Ecosystem

Ecosystem Vulnerabilities Licenses
Gradle (Kotlin, Java) OWASP Dependency-Check plugin com.github.jk1.dependency-license-report
Python pip-audit, proposed pip-licenses, proposed
npm (JavaScript) npm audit, proposed license-checker, proposed
Go govulncheck, proposed go-licenses, proposed

For Gradle, OWASP Dependency-Check is the plugin org.owasp.dependencycheck; the license report gives the task checkLicense. A proposed tool becomes binding with the first PR that sets it up in a repository of its ecosystem. The AGENTS.md of each repository names the commands of its checks.

Review Rules of the Repository

.werkrevisor.toml holds the repository part of the review configuration, e.g. the risk template and its categories. werkrevisor reads it at the head of main, never from the PR. A PR that changes it always waits for the approval of the human.

Code and Comments

  • A comment explains why, never what or how; when in doubt, no comment.
  • New code follows the surrounding code: naming, comment density, idiom.
  • Names follow javagil.de in the way of their ecosystem: on the JVM, packages, Maven groups and Gradle plugin IDs start with de.javagil.<repo>; a Go module that others import is git.javagil.de/<owner>/<repo>; an npm package takes the scope @javagil.

Writing Style

These rules apply to documentation, PR documents, commit messages and replies in Gitea:

  • Be terse; omit obvious details, implementation narration, and summaries.
  • Remove all mannered prose; use literal language.
  • Use ASD-STE100 as guidance: simple words, active voice, consistent terminology.
  • Preserve code identifiers and established technical terms.
  • Write at most one sentence per line.
  • Wrap sentences longer than 128 characters at sensible points, preferably after commas, colons or semicolons, or before "and" or "or".
  • Paragraphs comprise at most 5 sentences; add blank lines between paragraphs.
  • Format enumerations as such instead of clunky lists.
  • Each repository states the language of its documents; German documents avoid anglicisms in the prose.

Working with the Human

  • The coding agent asks one question at a time, as multiple choice, with the recommended answer first.
  • After each settled topic it proposes the next step, also as multiple choice.
  • It reports outcomes faithfully: failed tests with their output, skipped steps as skipped.
  • It gives instructions for manual steps one step at a time and waits for feedback after each.

Equipment of a Repository

File Content
AGENTS.md reference to this document; build, architecture, invariants, checks
CLAUDE.md @AGENTS.md, @docs/agentic-workflow.md, Claude Code rules
docs/agentic-workflow.md this document
docs/prs/README.md and a template structure and template of the PR documents
docs/<repo>.werkbaum the plan
.werkrevisor.toml repository part of the review configuration
docs/risk-analysis.md criticality and risk analysis (see "Required Checks")

Optional, where it helps the repository:

  • Skills under .claude/skills/: detailed guides that an agent loads when needed.
  • Release notes or a CHANGELOG.md for users.
  • A map from acceptance IDs to the tests that verify them.