# Code Guardian — Getting-started guide and technical documentation

Describes Code Guardian v17.17.
Retrieved on 2026-11-13 from https://www.provimedia.de/en/code-guardian/guide.

---

# Ready in ten minutes

Code Guardian is not a program you start. It is a set of rules that
Claude Code reads in at the next session start — plus a series of gates
that stop an operation before it runs: from then on they catch the dangerous
commands they were built for, such as deleting, deployment and
migration. In these ten minutes you set up both.

Would you rather have it installed for you? In the [customer portal](/code-guardian/portal) there
is a ready-made prompt for Claude Code and one for Codex:
"Copy to install". For Claude Code it walks through the same steps as this chapter,
for Codex those from the `ANLEITUNG-CODEX.md` of the Codex package, and
backs every step with a command.

## First: check two programs

```bash
python3 --version
which jq
```

**If `python3` is missing or older than 3.9, the installer aborts** and
touches nothing. That is the friendly variant. On Windows,
use Python from python.org or via `winget`, not the placeholder from the
Microsoft Store.

**If `jq` is missing, everything is installed anyway** — and the installer ends with
a warning and the return value 3. Without `jq`, only the four command
gates that run in Python still check: delete, deployment, migration and commit secret. Without `jq`, the write protection for unattended runs
and the halt for decision questions in autopilot no longer stop anything. That
remains the one silent failure state: you see the files lying there and
believe you are fully protected. If you remember one sentence from this guide,
make it this one.

On macOS: `brew install jq`. On Debian or Ubuntu: `sudo apt install jq`.

## 1. Unpack and install

```bash
unzip code-guardian-v17.17-update.zip -d code-guardian
cd code-guardian
./install.sh
```

The installer writes to `~/.claude/` — globally, not into your project. Your
projects are left untouched by the installation; files only appear there once you
actually start working. The installer does not touch your `.gitignore` —
which files you should add there is described in the technical documentation
under "Files".

The installer no longer sets up a status line. If Code
Guardian entered one earlier, it removes it; a status line of your own is left
untouched.

## 2. Restart Claude Code completely

Not `/clear`. Quit and reopen.

Claude Code reads hooks and agent definitions **only at startup**. Anyone who
skips this has installed the package and still works without a single
gate — until the next start, and until then they do not notice.

## 3. Check that it is really there

In the new session:

| Command | Expected output |
|---|---|
| `/hooks` | the entries of the gates |
| `/agents` | the review agents |
| `/help` | `code-guardian` in the skill list |

How many hook registrations actually exist, you do not read
from this table; you query it:

```bash
python3 -c "import json;d=json.load(open('$HOME/.claude/settings.json'));print(sum(len(v) for v in d.get('hooks',{}).values()),'Registrierungen')"
```

## 4. Test a gate

The test is described in detail in the `UPDATE-ANLEITUNG.md` of the package: send a prepared
JSON to `decision-gate-check.sh` and to `deploy-gate-check.sh`.
`deploy-gate-check.sh` must answer with a `deny` line,
`decision-gate-check.sh` outside autopilot only with a note without
`deny`. If this note does not appear, `jq` is missing, see above. If
`deploy-gate-check.sh` only asks instead of refusing, Python is missing or it
does not respond.

## 5. Read a file that is in the package

`README_IMPORTANT.md`, 181 lines. It explains how much context the package costs you
per request and when it is worth thinning out your own `~/.claude/CLAUDE.md`. It is the only file in the package that you should really read from start to
finish; in the `UPDATE-ANLEITUNG.md` from step 4 you
only look things up.

## In one sentence

Install, **restart Claude Code completely**, check `/hooks` — and if
the installer ends with return value 3, `jq` is missing, and without `jq` only
the four command gates in Python still check.

## Prompt für Claude Code

```
Check my Code Guardian installation and tell me what is missing.

Show me concretely:
- whether python3 and jq are present on this machine
- how many hook registrations are in ~/.claude/settings.json
- whether code-guardian shows up in the skill list

Measure this instead of guessing, and for each point name the command
you used to determine it.

At the end, give me a list of what I still have to do. Change nothing
without my approval.
```

---

# Why it works

A language model forgets a rule that exists only in a text. That is why
Code Guardian consists of three layers, and only one of them is text. The other
two run outside the model.

## Layer 1 — Skills: what the model reads

A skill is an instruction that Claude loads into its context on the appropriate occasion. It changes **how** work is done: classify first, then check, then
build, then provide evidence.

This is the weakest layer, and the package treats it as such. A skill
can be overlooked. That is why layer 2 exists.

## Layer 2 — Gates: what never runs in the first place

A gate is a hook: a small program that asks before
Claude Code calls a tool. If it answers with `deny`, the command is
not executed. Not warned about, not commented on — not executed. If
one of the command gates cannot check by itself, for example because Python is missing, it
asks you instead.

That is the difference between advice and a gate:

| Without a gate | With a gate |
|---|---|
| "Please check before the deploy which files go along." | `rsync` to the production server is rejected until the classification is available. |
| "Migrations should be reversible." | `artisan migrate` does not run until reversibility, lock profile and backfill have been assessed. |
| "Watch out for secrets in the commit." | `git commit` aborts if a key is in the diff. |

The gates take effect **regardless of whether a skill is loaded**. They hang
on the command, not on good intentions.

At the end of every answer, since v17.3 nothing blocks by itself any more. Whether a
claim is backed by evidence, an item is still open, or a change to sensitive code
has received an independent review (a review without knowledge of the author's plan),
is checked by the skill as a working instruction. Two checks can be switched on as a gate at the end: legal review and data analysis.

## Layer 3 — Review agents: they do not know what you want to hear

A model that rereads its own work finds confirmation. That
is not a character flaw but mechanics: it has the same assumptions as when
it wrote.

The package's review agents therefore do **not** get the author's verdict.
They get the artifact and the task of finding errors. None of them
has a tool for editing files — they read, measure and report, and
they file their evidence as a separate file under `.code-guardian-evidence/`. Most
of them run commands for this; that they change nothing in the process is governed by their
task.

That is why a finding from a review agent is worth something: it
is not the second opinion of the same head.

## What follows from this — for you

**Evidence beats assertion.** "I read it, it looks right" does not count
as a check anywhere in the package. What counts is an executed command with
its output or a reviewer from outside.

And the limit is stated in the license agreement, section 7.3, verbatim:

> Code Guardian checks and reports; every decision about a change, a
> release or a deployment is made by the licensee.

The package demands evidence and stops dangerous commands. It does not take the
decision off your hands, and it does not want to.

## In one sentence

Skills change how work is done; gates prevent what must not run;
review agents contradict — and the decision stays with you.

## Prompt für Claude Code

```
Show me which Code Guardian gates are currently armed in this project.

For each one:
- when it fires
- what exactly it rejects
- what I have to provide for it to open

Name them by file name, not just by purpose.

And finally, tell me which of them is likely to trigger on my next task
<describe briefly>.
```

---

# The first task

The most common disappointment after installation: you type something, and
Claude does not start coding right away. That is not a bug, that is the
product. This chapter shows what happens in the first minutes — so that you
recognize it instead of working against it.

## Start small

Take a real, small undertaking from a real project. Not
"write me an app". For example:

> The contact page is missing the phone number in the legal-notice block. Build it in.

## What you then see — four stations

**1. The classification card.** Claude classifies the task before touching
anything: how big, which path, and what will prove that it is done. It
appears as a small box in the answer.

**2. The airlock — plan mode.** For anything that touches more than one file,
Claude goes there first: read, measure, write a plan —
and **change nothing**. This is the station that costs the most patience and
saves the most.

**3. The questions.** Every open decision is put to you one at a time,
with a recommendation in first place and a line saying what the choice
means in concrete terms. Answer briefly. If no option suits you, say so —
then a better question comes.

**4. The approval.** Only once you approve the plan is anything written. That is
how the skill works, not a lock of Code Guardian.

## When the first lock strikes

Sooner or later a command is rejected. Usually with a migration, a deploy,
or a `git commit` whose diff contains a key. The message names the lock and says
what is missing.

**Then do not do three things:** switch the lock off, rephrase the command
until it slips through, or ask Claude to "just do it anyway". All three work technically, and all three take away exactly
what you paid for.

**Do this instead:** read what is missing, and supply it. Almost always
it is a minute of work — a classification, a check, a proof. The
lock then opens by itself.

## Three sentences that make a difference

| Instead of | Say |
|---|---|
| "Do it quickly." | "What would you want to check beforehand?" |
| "That's fine." | "Please back that up with an executed command." |
| "That's too small for the whole process." | Nothing. In the package, exactly this sentence is a trigger. |

## In one sentence

The first task is a small one — and when a lock strikes, you supply what it
demands instead of bypassing it.

## Prompt für Claude Code

```
Take on this task:

<a small, real task from your project — one file, one text,
one missing field>

Work it through the way you normally do. But change nothing
until I have approved the plan.

Show me beforehand:
- how you classify the task and why
- what you want to check before you touch anything
- how we will recognize at the end that it is really done

If a decision is open along the way, put it to me individually instead of
making it yourself.
```

---

# The tools that should be installed

Code Guardian does not perform the static analysis of your code itself. It makes sure that the
established review tools of your language **actually run** and that their
result is not ignored. If they are missing, the package lacks a layer — and
you do not notice, because everything still looks green.

## The installer installs none of them

That is intentional and is also stated in its closing message: which tool goes into
your project is your decision, not that of someone else's script.

Instead, the gaps are reported to you at session start, together with
the matching setup skill.

## What is expected per language

| Language | Required | Recommended | Optional |
|---|---|---|---|
| **PHP** | `phpstan` (with Larastan) | `phpunit`, `pest` | `infection`, `pint`, `rector` |
| **JavaScript, TypeScript, Vue** | `eslint` | `tsc`, `vue-tsc`, `vitest` | `stryker`, `prettier`, `knip` |
| **Python** | `ruff` | `mypy`, `pytest` | `mutmut`, `hypothesis` |
| **Blade (Laravel), HTML** | — | `html-validate` | — |

"Required" means: without this tool the detector reports a gap and the
static gate for this language does not take effect.

## Have it set up, do not piece it together yourself

Four skills do exactly that — configuration, a sensible default setting
and a baseline —, so that a legacy codebase does not bury you on the first day under 4,000
findings:

```
/phpqa-onboard      PHP: PHPStan/Larastan, Rector, Baseline, composer-Skripte
/jsqa-onboard       JS/Vue: ESLint, vue-tsc, Vitest, fast-check, Stryker, knip
/pyqa-onboard       Python: ruff, mypy, pytest, Hypothesis, mutmut, Baseline
/htmlqa-onboard     Blade/HTML: html-validate mit Blade-sicherer Konfiguration
```

Once per project. After that, your tools are known at the next session
start.

## The limit you should know about

There is a static gate for PHP, JavaScript, Python and markup, a blocking
mutation gate only for PHP and JavaScript/TypeScript — for Python the mutation
check only gives advice. Outside these languages there is **no
static and no mutation gate**. Locks, the sluice, reflexes and the slop scanner
keep working there — the language-specific review layer does not.

If you mostly write Go, Rust or Java, this is the honest
information before the purchase, not after.

## One tool per language that is often missing and expensive

`infection` (PHP) and `stryker` (JS) respectively are listed as optional and
still deserve a sentence: Without them it remains **unproven whether your tests
check anything at all**. A green test that also stays green when you break
the logic proves nothing — and only a mutation probe finds that.

## In one sentence

PHP needs `phpstan`, JavaScript `eslint`, Python `ruff` — set that up
once per project with the matching `*qa-onboard` skill, because the
installer deliberately does not.

## Prompt für Claude Code

```
Check which static analysis tools are missing in this project.

Measure this instead of guessing: look in composer.json, package.json and
in the existing configuration files, and tell me for each tool
how you know whether it is there.

Then tell me:
- what is missing and which review layer drops out as a result
- what it costs to add them

Once I approve, set up the missing ones with the matching
qa-onboard skill and create a baseline, so that the legacy codebase
does not bury me on the first day.
```

---

# Which skill when

The package ships **31 skills** (as of v17.17). The most important distinction
is one you will not find anywhere else: some of them run on their own. The rest
you call.

## The eight you never have to call

These take effect as soon as their trigger occurs. You do not have to do anything — it only helps
to know who is working at the moment.

| Skill | Trigger |
|---|---|
| `senior-dev` | every request. Classifies it, plans the proof, holds the course until completion |
| `code-guardian` | every code change, every bug report. Chooses the mode and the matching review steps |
| `todo` | as soon as work arises. Keeps the list; “done” only counts when nothing is open any more (working instruction, not a lock) |
| `entscheidungs-klartext` | before every option question. Translates it into everyday language |
| `grill-me` | in the plan sluice (plan mode). Puts open decisions to you one at a time |
| `kernanalyse` | during troubleshooting. Checks whether a measure touches the cause or only the symptom |
| `llm-council` | after the second failure in troubleshooting, automatically |
| `session-retro` | at the end of every task, as a step of the procedure (working instruction, not a lock). Collects the friction of the session |

## The ones you call — keeping the overview

| Skill | What for |
|---|---|
| `clistatus` | “Where do we stand?” A dashboard made of measured facts, never from memory |
| `whatsnext` | “What next?” The project-management view: what blocks the start |
| `session-observe` | a retrospective, strictly read-only look back at a session |
| `protokoll-durchsicht` | go through what the locks have logged — and find false alarms |
| `auto-self-improve` | evaluates at the end of the session what could run better and implements the lasting solution. On its own only with `auto_self_improve = true` in `code-guardian.conf`, the default is to call it |

## The ones you call — more throughput

| Skill | What for |
|---|---|
| `multitask` | several tasks at once, each in its own working copy |
| `session-orchestrator` | distribute work to other open Claude sessions on the same machine |
| `autopilot` | carry an assignment through without questions when you are not at the computer |
| `autorun` | you are away: your own session stays on target in `autopilot`, the other sessions learn the goal and deadline, and a fixed cycle checks that none is stuck |
| `llm-council` | have an expensive decision examined by five advisors — after the second failure in troubleshooting it also takes effect on its own (see above) |

## The ones you call — goals and observation

| Skill | What for |
|---|---|
| `goalengine` | turn a goal intention into a goal contract with fixed versions. Only clarifies, plans and builds nothing (chapter “Setting and accepting goals”) |
| `leitstand` | all Claude Code sessions of this machine at a glance in the browser, with consumption, goals and task lists |
| `codeguard-master` | an observer over the projects you name for it (without a list: those with `goalengine` goals), which collects and reports the situation on a cycle. Does not act on its own, and every model run costs tokens |

## The ones you call — checking

| Skill | What for |
|---|---|
| `test-architect` | experienced second opinion on your PHP tests. Advises, does not block |
| `frontend-test-architect` | the same for the frontend |
| `slop-audit` | full-repo audit against AI sprawl. Report only, deletes nothing |
| `design-beweis` | measures contrast in **every** state and proves the measurable criteria of WCAG 2.2 |
| `rechts-beleg` | obtains documented legal bases with source and retrieval date |

## The ones you call once per project

| Skill | What for |
|---|---|
| `phpqa-onboard` | PHPStan, Rector, baseline, composer scripts |
| `jsqa-onboard` | ESLint, vue-tsc, Vitest, Stryker, knip |
| `pyqa-onboard` | ruff, mypy, pytest, Hypothesis, mutmut |
| `htmlqa-onboard` | html-validate, configured to be Blade-safe |
| `ritual-lernen` | turns an experienced delay into one line of your project checklist |
| `senior-marketing` | SEO and online marketing with a bundled, source-documented knowledge base |

## How you call a skill

With a slash and the name: `/clistatus`, `/whatsnext`, `/multitask 3`. Or
simply by saying what you want — “where do we stand right now”, “distribute this
to the other sessions”. The triggers are designed for normal sentences, not
for commands. Exceptions are `goalengine` and `codeguard-master`: they start only
with a slash (`/goalengine …`, `/codeguard-master …`), never through a normal sentence.

## What you add yourself

Whatever you place in `~/.claude/skills/` as your own skills stays there next to the
31 and is not touched by updates. The package does not replace your own
tools, it complements them.

## In one sentence

Eight skills work unasked, the rest you call — and the four
`*qa-onboard` exactly once per project.

## Prompt für Claude Code

```
Here is what I plan to do: <briefly describe what you plan to do>

Tell me, before you start:
- which Code Guardian skills take effect on their own here
- which ones I should additionally call, and what each of them contributes
- which ones bring nothing here and why

Justify each assignment with the trigger of the respective skill, not
with your impression.

Then get started.
```

---

# Setting and accepting goals

A job rarely fails because of the technology. More often it fails because nobody said exactly when it is done. This chapter shows two aids that start right there: the skill `goalengine`, which turns a vague intention into a written goal contract, and acceptance with acceptance criteria, which only lets a task close once every mandatory criterion is documented.

## The skill `goalengine`: an intention becomes a contract

`goalengine` clarifies what you want to achieve and records the result as a goal contract with fixed versions. It asks targeted questions without prescribing a solution. It does not ask “Which database do you want?”. It asks: “What waiting time is acceptable from the users’ point of view?”

It only clarifies. It does not plan and does not implement anything: no code change, no build, no deploy, no installation. Task lists and technical routes do not belong in its contract either, but in the planning that follows.

### How to call it

With a slash and your goal description:

```
/goalengine <Zielbeschreibung>
```

It also knows three further forms:

| Call | Effect |
|---|---|
| `/goalengine status` | shows which goals exist and where they stand |
| `/goalengine review` | checks a draft for gaps before you approve it |
| `/goalengine revise <Goal-ID>` | starts a new version of an existing goal |

It starts **only on your call**. Claude never calls it on its own.

### What comes out of it

In the conversation it asks in rounds of one to three questions. Every statement in the draft carries an origin: said by you, confirmed by you, found in the project, given from outside, proposed by the AI, or unknown. What the AI merely proposes does not count as your requirement. A mandatory criterion that is marked as an AI proposal cannot be approved.

The conversation produces a contract made of outcome, beneficiary, boundaries and success criteria. Milestones and sub-goals only group success criteria into visible interim results (“The search returns matching posts”). They are never work steps.

### Approval and freezing

A contract only applies once you **expressly approve a named version**. The skill is instructed never to approve on its own and never to pass on a draft as finished. At approval, the tool `goal.py` checks schema and version, but not who approves: the name behind `--durch` is entered freely. With the approval, this version is frozen and never overwritten. A change starts a new version, which you have to approve again. Unchanged criteria keep their state and evidence.

A criterion only counts as met once evidence is attached: a commit, a test log with `exit=0`, a URL or a named manual check. The goal only counts as reached if every mandatory criterion has evidence.

### The `/goal` prompt at the end

With the approval, the skill outputs a ready, copyable prompt for the Claude Code command `/goal`. It begins with “`/goal Der freigegebene Vertrag .goals/<ID>-<slug>/vertrag-vNNN.json (Ziel <ID>, Version vNNN) muss erfüllt sein.`” and names the identifiers of all mandatory criteria. You give this prompt to a working session. Only it makes the contract the termination condition of that session. Without it, the contract remains a filing place. The prompt is saved with the contract and can be output again later.

### Where everything lives and where you see it

The goals live in the project in the folder `.goals/`. There is one separate subfolder per goal with the goal file, a readable version (`GOAL.md`), the history and the frozen contract files. Writing is done only through the bundled program `goal.py`, which checks every change against the rules. You should not change the files by hand.

In the directory `~/.claude/goals/` the tool keeps a list of the projects that have goals. If you remove Code Guardian, `~/.claude/goals/` and the `.goals/` folders of your projects stay in place. An uninstall script is currently not included in the package; how to remove it by hand is described in the package’s README.

In the control room (Leitstand), the “Goal Engineering” tab shows the goals of all projects: status, approved version, criteria with state and evidence, and the criterion currently being worked on. Every goal card with an approved contract also carries the `/goal` prompt to expand and copy.

## Acceptance with acceptance criteria

Since v17.15, new task folders (`aufgabe.py neu`) carry acceptance criteria. This is acceptance on a small scale, directly at the individual task:

- The criteria are **frozen and sealed before the first own commit**.
- `aufgabe.py abschliessen` only closes the task once **every mandatory criterion is documented**.
- A criterion that is added later appears only as a **visible addendum** with a new review. Nothing can be added silently.
- Anyone who deliberately works without criteria says so with `--kriterien-entfaellt "<Grund>"`. The reason is then recorded there in readable form.
- A single mandatory criterion can only be dropped with a reason and visibly (`aufgabe.py beleg … --kriterium K<n> --entfaellt "<Grund>"`). It then no longer holds up the closing.
- Anyone who only freezes after the code says so with `--trotz-code "<Grund>"`. The reason goes into the seal of the criteria.
- Optional criteria (`--optional-kriterium`) never hold up the closing.
- A review verdict `REVIEW: CHANGES` without a critical finding counts as evidence. “NOT CHECKED” does not count as evidence in any spelling.
- For a repository without a first commit there is `--ohne-basis`.

Existing task folders are not affected.

## Sealed test logs

A pasted test run proves little. The tool `beleg-lauf.py` therefore seals a test log with the content state of your working tree. It follows that:

- **Outdated:** If the tree changes during the run, the evidence counts as outdated. The log then no longer belongs to the state it is supposed to prove.
- **Skipped proves nothing:** Tests that were skipped with SKIP do not count as passed.
- **New commit:** If HEAD now points to a different commit, for example after a rebase, the rejection names exactly this case.

## Hidden acceptance cases

A criterion of the kind `review · holdout` only counts through cases that a fresh subagent writes after freezing and that are not visible while building. Each of these cases needs a sealed log.

## Limits – honestly

- **No hook enforces the contract.** No gate reads `.goals/` and stops a session that does not fulfil a contract. The tool checks schema, approval and evidence, but only at the moment you call `goal.py`. In between, nothing happens.
- **Goal clarity is not feasibility.** An approved contract says what should apply. It does not say that it can be built, that the work is right or that the evidence is correct. The goal is then written down and verifiable, nothing more.
- **It starts only on call.** Whoever does not call `/goalengine` gets no contract.
- **Claude Code only.** The `/goal` prompt has no counterpart in the Codex package.
- **Acceptance applies to new task folders.** Old folders stay as they are.

## In one sentence

`goalengine` turns your intention into a frozen, verifiable goal contract, and acceptance only closes a task once every mandatory criterion stands there with evidence.

## Prompt für Claude Code

```
/goalengine I would like to set the following goal:

<briefly describe: what should be different in the end, and for whom?>

Ask me before you write anything down, and do not propose a solution.
Ask at most three questions per round and say for each one why it
could change the definition of success.

Mark what I said and what is only your proposal.
Before approval, show me the whole contract with mandatory criteria,
non-goals and the verification method for each criterion.

Do not approve anything on your own. I will name the version that should apply.
After that, give me the copyable /goal prompt.
```

---

# Several tasks at once

`multitask` takes several tasks and gives each its own working copy:
its own `git worktree`, its own branch, its own complete Guardian run.
At the end you have several finished branches, not one task that has
already been merged.

## Calling it

```
/multitask 3
```

Or in words: “start the next three tasks in parallel”.

At most five at a time. The limit is not technical, but a question of
what a person can still review afterwards.

## The basic rule of this skill

> A cell (the working copy of one task) works autonomously up to the green
> branch — and not one step further.

No tool of the skill knows `git merge`, `git push` or `git update-ref`.
This is not a precaution that could be switched off; the capability is
simply not there. **Merging remains your decision.**

## When it pays off

When the tasks touch **different files**. Three tickets in three
modules: ideal.

Before the start, a pre-check examines which files are involved in each task
and rejects overlapping pairs. That is not overzealousness: in an
analysis of 33,596 agent pull requests from 2,807 repositories,
**19.8 percent of the concurrently active pairs** in the same
repository collided textually with each other.

## When it does not pay off

- **Coupled work.** Two tasks on the same file do not get faster,
  they turn into a conflict.
- **A single task.** `multitask` does not make any task faster. It
  does several at once — and costs correspondingly more.
- **When you want to watch.** Nobody can keep five cells running at the same time
  in view. That is what the board is for.

## The board

At the end there is an overview: what each cell did, what is green, and
which decisions were made in your absence. This board is the
real reason why a parallel run can still be answered for afterwards.

## The step afterwards

Each branch is looked at individually and taken over individually. Order by
risk: the smallest branch first, so that a conflict shows up early and not
only at the fifth.

## In one sentence

`multitask` delivers up to five green branches in their own working copies — it
cannot merge them, and that is exactly the intention.

## Prompt für Claude Code

```
Start the next three tasks in parallel, each in its own
working copy.

Check beforehand whether they share files. If so, tell me which ones and
chain them one after another instead of running them at the same time.

Do not merge anything — no merge, no push.

At the end I want to see the board: what each cell did, what is green,
and which decisions were made in my absence.
```

---

# Several sessions

`session-orchestrator` distributes work to the **other Claude Code sessions
that are already open on your machine**. It starts nothing new — it finds
out who is currently free and sends an assignment there.

## The difference from `multitask` in one sentence

`multitask` **creates** work in new working copies. `session-orchestrator`
**distributes** work to windows that are already running.

If you are sitting with three terminals on one project, this skill is the one meant.
If you have one terminal and five tickets, `multitask` is meant.

## Calling it

```
/session-orchestrator board
```

Or: “who is free right now?”, “distribute this”.

## What the board shows

One line per session: identifier, project, state. And below it a
summary — how many sessions are running, how many of them in this
project, how many are free, how many already hold an assignment.

The sessions get stable identifiers (A, B, C). These are tied to the
session ID, not to the name — names change in the course of a session, and an
assignment that goes to an outdated name never arrives.

## The one rule that counts

**A waiting session is not free.**

`waiting` means: a question is pending there, and a person has to answer. Whoever
distributes there puts an assignment behind a closed door. The orchestrator therefore
never counts such a session as available — and if you distribute by hand,
the same applies.

## What it expressly does not do

The skill's **tool** does not send anything itself. It determines the matching
session and records the result; the assignment is delivered by your
Claude session as a visible message.
So you can look up at any time who got what — there is no
silent channel.

## When several sessions work in the same project

Then they share one working tree — the same files on disk —,
and that is the most common source of ghost errors: one session changes a
file, another checks exactly this file at the same moment and reports a
defect that never existed.

Two habits protect against this:

- **Respect the task list.** An item in the state `läuft` with a foreign
  identifier belongs to another session. Do not touch it.
- **Measure against commits, not against the disk.** `git show <sha>:<pfad>`
  delivers a state that nobody pulls out from under your feet.

## In one sentence

`session-orchestrator` distributes to open windows on the same machine — and a
waiting session is never free.

## Prompt für Claude Code

```
Show me the board of the open Claude Code sessions on this machine.

Tell me which of them are really free — waiting ones do not count, there
a question to a person is pending.

Then distribute <task> to the first free session in this project
and tell me which one it went to.

If none is free, tell me that instead of occupying one.
```

---

# When being wrong is expensive

`llm-council` sends a question through a council of five advisors. Each one
analyzes independently, then they review each other **anonymously**, and
a chair merges the result into a verdict.

The idea comes from Andrej Karpathy's LLM Council. Here it is implemented not
with five different models but with five different viewpoints on the same
model — the gain comes from independence, not from the vendor.

## Why anonymous

If an advisor knows whose proposal he is reviewing, he reviews the person
too. Anonymously, only the argument is left. For the same reason, the
review agents do not know the author's verdict either.

## When you call it

When being wrong is expensive and there is a real conflict of goals:

- Two architecture paths, both defensible
- A migration that is hard to roll back
- A pricing or contract question with consequences for existing customers
- A decision you will have to explain in six months

## When expressly not

| Not for this | Instead |
|---|---|
| Factual questions ("what is the option called?") | look it up |
| Creation tasks ("write me the text") | commission directly |
| Summaries | commission directly |
| A question that a measurement answers | measure |

The mistake behind the last point is the most expensive one. A council that
deliberates over a number you could measure in thirty seconds produces five
well-reasoned opinions about an unknown fact.

## It also comes uncalled

In troubleshooting, Code Guardian calls in the council unconditionally **after
the second failure**. That is the moment when the third variant of the same
wrong idea would otherwise arise.

And in autopilot, **every** question goes to it — there it is the substitute
for you.

## What comes back

Not a yes or no, but: where the advisors agree, where they collide,
and what follows from that. The places where they disagree are the most
valuable — that is where the real risk of your decision lies.

## In one sentence

You call the council for real, consequential conflicts of goals — not for
questions that a measurement answers.

## Prompt für Claude Code

```
Run the llm-council on this decision:

<the decision, with both paths and what depends on each>

But FIRST check whether a measurement already answers the question. If so,
measure instead of deliberating — five opinions about an unknown fact
are expensive and worthless.

At the end, tell me not only the result but also where the advisors
disagreed. That is where my real risk lies.
```

---

# Autopilot

Autopilot carries a task through to the result **without asking you**. Every
question that would otherwise go to you goes to the `llm-council`, and every
decision made this way is recorded verbatim in the log.

Its basic rule is stated in the skill itself:

> Autopilot takes the waiting off the human, not the accountability.

## When it is the right choice

- You are leaving the house and the task is clearly defined
- A long, mechanical stretch: many files of the same kind, the migration of
  similar text passages, a rollback
- You explicitly say "without questions" or "just push it through"

## When it is the wrong choice

**When the task touches the package's `skills/` or `hooks/` folders or the
installer.** In that case the run stays interactive — an autopilot does not
tamper with the locks that limit it.

And it is wrong for anything where you actually want to make the decision
yourself. The council decides well, but it does not decide the way you do.

## What it expressly does not solve

This is the part you need to know before you activate it: **The locks stay
active.** All of them — the mode switches none of them off. The four that
are tied to the command keep working unchanged:

| Lock | Stays |
|---|---|
| Deploy | active |
| Migration | active |
| Secret in a commit | active |
| Destructive commands | active |

They are tied to the command, not to the mode — an unattended run therefore
cannot knock them out.

In addition, the mode activates a lock **of its own**, built for exactly this
case: write access to especially sensitive files — credentials, the lock
scripts themselves and the settings files that hold the permissions — is
rejected as long as nobody is there who could approve it.

## It stops on its own

Five stop conditions end the run, among them **every red result**. An
autopilot that runs past a red test would not be an autopilot but a
bulldozer.

## Switching on and off

Activating belongs explicitly in the task — a mere mention does not amount to
approval. Switch it off with one sentence: "/autopilot aus".

## The log is the whole point

Afterwards you read `.code-guardian-autopilot.md`: every question that came
up, every decision of the council, every justification. If you disagree with
a decision, you see there exactly what it was based on — and can reverse it.

An unattended run without this log would not be defensible. With it, it is.

## In one sentence

Autopilot replaces your presence, not your responsibility — the locks stay
active, and every decision is on record in the log.

## Prompt für Claude Code

```
Arm the autopilot for this task:

<clearly defined task with a named result by which you can tell
that it is done>

Do not ask me in between. Every decision you make yourself instead goes
into the log with its justification BEFORE you act.

Stop as soon as something is red or a gate refuses — and tell me
when you stop exactly what is missing.

Check beforehand whether the task touches skills/, hooks/ or the installer.
If so, stay interactive and tell me why.
```

---

# Status, Next, Limits

Three skills answer three different questions that are easily confused —
and at the end comes what the package does not do.

## "Where do we stand?" — `clistatus`

A dashboard: what is done, what is running, what is open, how the checks
stand.

The decisive thing about it is the rule by which it is built: **It is never
generated from memory.** Before even a single box appears, the truth is
collected — task list, running background jobs, `git log`,
`git status`, the ledger. That is why
creating the dashboard is itself already the check.

It is good after a longer break, or when the context has just been
summarized.

## "What next?" — `whatsnext`

Not the developer's view but that of project management: What brings the
project closer to the goal, what blocks the launch?

Two properties that make it usable:

- It **writes exclusively** under `docs/manager/`. It does not touch your code.
  A red build is a finding to it, not a work order.
- Without a confirmed problem statement it gives no recommendation: Who has the
  problem, what does it cost today, how will you recognize the solution. Without an answer to
  these three questions there is no prioritization, only an opinion.

## "What is still open?" — `todo`

The list of the run. It has an
intake rule, and that is the reason it stays readable: Only what carries an
impact goes on the list.

| | Impact |
|---|---|
| **S** | Security or data loss |
| **K** | a customer notices it in normal use |
| **R** | a release is blocked or distorted |
| **V** | you commissioned it |

Everything else is mentioned once in the report and **not** noted down. Being
true is not enough — in a large system a reviewer always finds something
true, and a list that takes in every true finding grows faster
than work can empty it.

Items are ticked off only with proof. "Actually done" is not proof.

## What Code Guardian does not do

So that you hear these limits from us and do not discover them on a
disappointing afternoon:

- **It does not decide.** License agreement 7.3: change, approval, and
  delivery are decided by you.
- **It does not find every error.** It ensures that claims are backed up
  and dangerous commands do not run unexamined. That is something different
  from freedom from errors.
- **A static gate exists only for PHP, JavaScript, Python and markup, a blocking mutation gate only for PHP and JavaScript/TypeScript.** Locks
  and reflexes also work in other languages, the language-specific
  review layer does not.
- **It does not prevent intent.** The locks — safeguards that each
  halt one operation — are built against accidents. Anyone who wants to bypass them
  can — they will then simply have done it knowingly.
- **It sends nothing to us.** No telemetry, no call to a Provimedia server.
  Network access exists only to your own repo and, if
  configured, your own server, as well as optionally to the package sources of
  the dependency tools — details in the "Network" chapter of the technical documentation.

## If something is wrong

Write to `dev@provimedia.de`. A finding with the command that
produced it is preferable to us over a polite hint — that is exactly what the
package demands of itself, after all.

## In one sentence

`clistatus` says where you stand, `whatsnext` what comes next, `todo`
what is open — and none of it is decided without you.

## Prompt für Claude Code

```
Give me the status of this project in one go:

1. Where do we stand right now? From measured facts — git, tests, running
   jobs —, not from memory.
2. What is still open, and which of it does a customer notice in normal use?
3. What would be worth the most next, and why exactly that?

For each point, also say how you know it. Leave out a number without its
command.
```

---

# Prerequisites

Code Guardian runs as a skill and hook package inside Claude Code, and for the Codex output also inside the OpenAI Codex CLI. This page lists what must be present before the installer runs.

## Required tools

| Tool | Requirement |
|---|---|
| Claude Code | baseline requirement |
| OpenAI Codex CLI | only for the Codex output |
| Python | version 3.9 or newer, standard library only, no additional packages |
| Bash and git | both required |
| jq | if missing, the installer runs anyway and then exits with code 3. Without jq, only the four command guards in the Claude edition (deletion, deployment, migration, commit secrets) keep checking, because they run in Python; without jq, the write guard for unattended runs and the autopilot stop for option questions block nothing. In the Codex edition, the dispatcher stops every command without jq. |
| shasum or sha256sum | for checksums, either one is enough |

Recommended, not required: the obra/superpowers package.

## Platforms

- macOS
- Linux
- Windows, natively via Git Bash (Git for Windows)
- Windows, fully inside WSL 2

The mixed form is not supported: Claude Code running on Windows while the checks run through WSL.

## Windows

- `C:\Windows\System32\bash.exe` is the WSL launcher, not Git Bash. Code Guardian deliberately never calls it.
- Inside WSL, keep the project in the Linux filesystem, under `~/`, not under `/mnt/c`. The guard scripts read files on every command, and `/mnt/c` costs noticeably more time.
- Install Python via `winget install Python.Python.3.12` or the python.org installer, not the Microsoft Store stub. The stub passes every existence check but cannot actually run. The result: every guard script asks before every command.
- Install jq on Windows via `winget install jqlang.jq`.
- If Python is still missing, the guard scripts do not stay silent: they ask before every command, and a line is written to `~/.claude/code-guardian-failopen.log`.
- Checking takes noticeably longer on Windows than on macOS or Linux, because every program start costs more there. Measured on GitHub `windows-latest`: a median of about 1700 ms before a Bash command and 600 ms after it, and the median total per call is about 2400 ms.
- At session start on Windows, Code Guardian measures what a program start costs on your machine and warns you if the guards' time limit is too tight for it.
- The tool detection recognises the Microsoft Store `python3` placeholder for what it is and does not count it as an installed Python.

## In one sentence

Python 3.9 or newer, Bash, git and jq are all it needs; on Windows add Git Bash or a complete WSL 2, never a mix of both.

## Prompt für Claude Code

```text
Check whether this machine meets all prerequisites for Code Guardian (Python version, Bash, git, jq, shasum or sha256sum), and tell me briefly what is missing or misconfigured.
```

---

# Architecture

Code Guardian consists of skills, hook registrations, review agents and Python-backed guard scripts that work together on every call. This page describes the building blocks and the flow.

## Building blocks

| Block | Scope |
|---|---|
| Skills | 31, code-guardian itself plus companions |
| Hook scripts | 15 plus 3 libraries; their rules live in 28 Python modules. Four of them block outright, two only in narrow cases, two only once switched on; the rest give hints or are deregistered |
| Hook registrations | 15 in total: PreToolUse 6, Stop 1, PostToolUse 4, one each for UserPromptSubmit, SessionStart, SessionEnd and SubagentStop (without switched-on gates; each one adds a Stop registration) |
| Review agents | 15, none of them carries an Edit or Write tool |
| Gates | 7: finding, decision, deploy, data, migration, dependency, legal |
| Modes | 5: plan, build, debug, cleanup, data analytics |
| Tools | 82 detectors and helpers |

Review agents judge, they do not change code or files. Their evidence is written as a fragment to `.code-guardian-evidence/`.

## Flow of a call

1. A prompt arrives, the UserPromptSubmit hook runs the intake.
2. A skill picks the matching mode.
3. Review agents judge.
4. Commands pass through the PreToolUse guard scripts: deny, ask or allow. Edits to credentials or to the guards themselves are stopped only in unattended runs and in autopilot, option questions only in autopilot.
5. PostToolUse hints add context.
6. At the end of the response, the Stop hook runs. It can only block there through the legal and data analysis checks, and only once they are switched on (off by default). Cold review, finding check, task list, retrospective, evidence and mandate are working instructions in the skill and do not stop anything.

The command guard scripts also apply to MCP calls, not only to Claude Code's built-in tools.

## Diagram

**Flow:** request → intake (UserPromptSubmit) → skill and mode → review agents judge, evidence to .code-guardian-evidence/ → commands, file changes and decision questions through the PreToolUse hooks (deny, ask, allow) → PostToolUse hints → Stop hook at the end of the answer (blocking only with switched-on gates).

## In one sentence

Commands pass through hook registrations that deny, ask or allow, while skills and review agents judge without changing anything themselves.

## Prompt für Claude Code

```text
Using the installed Code Guardian files in this project, explain which mode applies to my current task and which gates come into play.
```

---

# Network

Code Guardian sends no telemetry and calls no Provimedia server. Two exceptions still apply: a freshness check of its own repository, and optional registry lookups by the dependency tools. If you set up the companion skill `codeguard-master`, its model call through your own Claude account and, if present, its chat tool come on top (see below).

## What does not happen

- No telemetry.
- No call to a Provimedia server.

## Freshness check

On every prompt, at most every 10 minutes, a `git fetch` runs in the background against the upstream of the project's own repository. Its only purpose is to detect whether the local state is behind the remote one.

If `.code-guardian-deploy.yml` sets `live_ssh` (or, as a fallback, `ssh`) together with `live_path`, an additional SSH call `git rev-parse HEAD` follows against the customer's own server.

This version has no off switch, only throttling through the `CG_FRISCHE_TTL` environment variable, in seconds.

## Dependency audits

`composer audit` and `npm audit` query their respective package registries, but only when the dependency tool actually runs.

## Companion skill codeguard-master (only when set up)

The observer `codeguard-master` runs only if you set it up yourself. It then collects the state of the projects you register with it at the configured interval without a model, from local files and git. Network access during collection happens only through tools that are present on your machine. The template of its configuration already names a session-chat tool (`~/.claude/bin/cg-chat`): if it exists on your machine, the observer uses it on every run to ask who is in the chat and how many messages are waiting, and announces itself there at most every six hours. Without a configured channel, the channel is named after the first project you register. If you configure a channel, it sends its actions to your sessions through the same tool. A GitLab tool is added only if you name it in the configuration. When a fixed trigger fires anew, it calls the Claude Code command line without tools and hands it that state. This is a model call through your own Claude account and costs tokens. The observer itself sends nothing to a Provimedia server; where an existing chat or GitLab tool connects to is up to that tool.

## Update check

Whether a new version is available is something the customer checks deliberately, through the update API (its own chapter). Code Guardian does not reconcile this automatically in the background.

## In one sentence

Code Guardian does not phone home, but it does fetch the freshness state of its own repository in the background, and of the customer's own server when configured.

## Prompt für Claude Code

```text
Show me whether .code-guardian-deploy.yml in this project sets live_ssh or ssh together with live_path, and explain which network calls Code Guardian triggers on every prompt as a result.
```

---

# Files

Code Guardian creates files in the project, in the `.git` directory and in the home directory. This page lists them.

## In the project

- `.audit-log.md`
- `.task-journal.md`
- `.code-guardian-propagation.md`
- `.code-guardian-todo.md` (plus `-archiv`)
- `.code-guardian-evidence/<trace-id>/`
- `.code-guardian-deploy-report.md`, `.code-guardian-migration-report.md`, `.code-guardian-dependency-report.md`
- `.code-guardian-autopilot.md`
- `.code-guardian-scope`
- `.code-guardian-zelle/`
- `.code-guardian-rechtsbelege.md`
- `.code-guardian-narben.tsv`
- `.goals/` (goal contracts of the `goalengine` skill, only if you use it)

## Optional configuration

- `.code-guardian-deploy.yml`
- `.code-guardian-slop.yml`
- `.code-guardian-redundancy.yml`
- `.code-guardian-migration.yml`

## In the git directory

- `.git/cg-frische`
- `.git/cg-live`

## In the home directory (~/.claude)

- `code-guardian.conf`
- `code-guardian-failopen.log`
- `code-guardian-stopcrash.log`
- `code-guardian-incidents/`
- `skill-backups/`
- `goals/` (project list of the `goalengine` skill; stays when you remove the package)
- `codeguardmaster/` (data and reports of the `codeguard-master` skill, only if you set it up)

The installer edits `settings.json` and creates a backup first.

## Under Codex

There, the configuration lives at `~/.codex/code-guardian.conf`.

## In one sentence

Project state, guard configuration and defaults live in clearly named, separate files in the project, in the `.git` directory and in the home directory.

## Prompt für Claude Code

```text
List every Code Guardian file in this project and in ~/.claude, and tell me which of them I have accidentally committed.
```

---

# Configuration

Code Guardian creates `code-guardian.conf` on its first run, only if it is missing, and never overwrites it afterwards. This page lists the switches.

## code-guardian.conf

| Switch | Default | Effect |
|---|---|---|
| `plan_modus` | true | Only the literal `false` switches this off: then there is no one-click approval, instead the plan carries stated assumptions and a cold plan review runs alongside it |
| `orchestrator_takt` | true | Enables the orchestrator's pacing |
| `orchestrator_takt_min` | 20 | allows values from 1 to 1440 |
| `task_orchestrator_takt` | true | The session holding the task orchestrator role compares the open items of the task list with git at a fixed interval |
| `task_orchestrator_takt_min` | 20 | that interval in minutes, allows values from 1 to 1440 |
| `rueckfrage` | not set | Only the value `sperre` has an effect: every question from the command guards then becomes a refusal with a hint on what to do instead, for runs where nobody can answer a question. The installer does not add this line |
| `riegel_zusatz` | not set | Switches on two extra latches, comma-separated: `rechts` (legal gate) and `data-analytics` (data analysis gate). It takes effect only after running `bash install.sh` again, because the installer registers the hooks. Without this line neither of them blocks |

The installer does not extend an existing file. Anyone who wants the newer switches adds them by hand; without them, the default applies.

## Environment variables

| Variable | Meaning |
|---|---|
| `CG_STOP_AUFSCHUB` | currently has no effect: the end-of-answer gates that read it are deregistered |
| `CG_FRISCHE_TTL` | throttles the freshness check, in seconds, default 600 (see the Network chapter) |
| `CLAUDE_CONFIG_DIR` | respected, moves where configuration files are read from |

## In one sentence

The configuration file is created once and never changed automatically afterwards, anyone who wants a different setting edits it themselves.

## Prompt für Claude Code

```text
Show me the contents of ~/.claude/code-guardian.conf for this project and explain what plan_modus and orchestrator_takt_min mean in my current setup.
```

---

# Update API

Code Guardian does not check on its own, during normal operation, whether a new version exists. Anyone who wants the latest entitled version uses the publicly documented update API on provimedia.de, authenticated with a licence key.

## Authentication

Every call carries the licence key in a header, either as `Authorization: Bearer <key>` or as `X-Licence-Key: <key>`. Case, whitespace and missing hyphens are tolerated. The key never goes in the URL, or it would end up in server logs and shell history.

## Endpoints

| Endpoint | Purpose |
|---|---|
| `GET /api/code-guardian/status` | Licence, update period and subscription state, states separately the latest entitled version and the latest version that exists at all |
| `GET /api/code-guardian/latest` | Only the latest entitled version, directly |
| `GET /api/code-guardian/download/{version}` | Downloads the zip, without a version the latest entitled one, with a version also an older one for a rollback |

## Flow

1. Read the installed version from the heading of `SKILL.md`.
2. Query the entitled version via `/latest`.
3. Compare. If both match, there is nothing to do.
4. If the entitled version is newer, download it via the `download_url` field from the response.
5. Verify the checksum (`sha256` from the response) against the downloaded file, do not install on a mismatch.
6. Run `install.sh` from the package and read `UPDATE-ANLEITUNG.md`.
7. Remove the zip and the extracted directory again.

## Error codes

| HTTP | Error | Meaning |
|---|---|---|
| 401 | `missing_licence_key` | No header set |
| 401 | `invalid_licence_key` | Unknown key, do not retry |
| 402 | `payment_returned` | A direct debit was returned, downloads are locked until payment arrives |
| 403 | `licence_not_paid` | Payment not yet recorded |
| 403 | `subscription_required` | The requested version was published after the update period ended |
| 404 | `no_entitled_release` | No version is currently entitled for this licence |
| 404 | `release_not_found` | This version number does not exist |
| 404 | `release_file_missing` | Server-side problem |
| 429 | no field | Too many requests, wait once instead of retrying in a loop |

## Limits

- Delivers Code Guardian packages only.
- A licence key belongs to exactly one company and may be used there as often as needed, but never beyond it.
- Access is logged (time of last use per licence), but not which project or machine asked.
- The licence itself never expires: versions published during a paid period stay permanently downloadable, even after cancelling the update subscription.

## In one sentence

Three endpoints, one licence key in a header and one checksum are enough to query status, the latest entitled version and the download.

## Prompt für Claude Code

```text
Ask the Code Guardian update API for the latest entitled version, compare it against the version installed in this project, and only install the update after checking back with me.
```

---

# Limits and test record

This page sums up what Code Guardian does not do, and what the test record in the package covers.

## Limits of the product

- Code Guardian protects against a careless agent, not against one that deliberately tries to bypass it.
- Under PowerShell, only part of the command guard scripts see the commands, Git Bash is the supported path.
- Full tool depth, meaning static analysis and mutation testing, exists only for PHP/Laravel and for JS/TS/Vue. Other languages get gates, reflexes and the slop scanner.
- No legal advice.

## PRUEFNACHWEIS.md

The package includes `PRUEFNACHWEIS.md`. It is generated when the package is built and describes the package's own test layers. It proves nothing about your project.

## In one sentence

Code Guardian protects against a careless agent, not against deliberate bypassing, and `PRUEFNACHWEIS.md` covers the package's own test layers, not your project.

## Prompt für Claude Code

```text
Explain where the limits of Code Guardian are and what PRUEFNACHWEIS.md actually proves, before I rely on it in a decision.
```

---

