Kiln's code conventions and per-area gotchas, plus a diff gate that enforces the mechanical ones. Invoke before writing or changing any Python, TypeScript or Svelte code in the Kiln repo (libs/core, libs/server, app/desktop, app/web_ui), and when reviewing such a change. Covers comments, startup and entry points, globals and module state, config reads, module layering, library-vs-app rules and async I/O.
77
96%
Does it follow best practices?
Run evals on this skill
Adds up to 20 points to the overall score
View guide
Passed
No findings from the security scan
One set of rules for how code is written in Kiln, the facts about the current code that are easy to get wrong, and a cheap check on the lines you add. Existing code is grandfathered: the rules apply to what your change adds or modifies.
Docs-only and spec-only changes don't need this skill.
Read references/rules.md in full. It is short, and every rule has a ❌/✅ example.
Pick the references from the paths you are editing. Read only those.
| Paths | Reference |
|---|---|
libs/core/** | references/core.md |
libs/server/**, app/desktop/** | references/server_desktop.md |
app/web_ui/** | references/web_ui.md |
UI changes (anything under app/web_ui that renders) also need the kiln-ui skill (.agents/skills/kiln-ui/SKILL.md) for visual design and house controls. This skill covers code structure only.
Follow the rules even where the surrounding code doesn't (rules.md H24). Don't copy a nearby pattern that breaks a rule, and don't rewrite neighbouring code to comply unless your change already touches it.
From the repo root:
uv run python .agents/skills/kiln-conventions/scripts/conventions_gate.py --worktree # uncommitted changes + untracked files
uv run python .agents/skills/kiln-conventions/scripts/conventions_gate.py --range origin/main...HEAD # a branch or PR
uv run python .agents/skills/kiln-conventions/scripts/conventions_gate.py --files <path>... # whole files or directories (audits)It prints one line per hit, SEV<TAB>RULE<TAB>path:line<TAB>snippet, then a summary. Exit 1 means at least one FAIL.
scripts/gate_allow.txt with a # reason line above it. Don't allowlist a real violation.path:line, and the refactor it waits on. The gate isn't in CI, so a FAIL reported this way blocks nothing.app.command(...)(...) in cli/cli.py: Typer command registration at the CLI's composition root").Only added lines are checked in --worktree and --range mode, so a hit is always on a line you wrote. --files reports existing code too; it's for audits, not for gating.
The gate catches history comments, global, bool(os.getenv…), env reads outside the allowed paths, new Config.shared() in libs/core, lib/ → routes/ imports, and module-level calls, constructions and subscriptions. Before you finish, check the review-only rules yourself against your diff:
lifespan, not in an app factory or a module.global).default_factory are pure; no branching on the environment name to pick an implementation.HTTPException in services, no catch-all modules, no test helpers in production packages, no near-copies.async def; every outbound call has a timeout.If a rule couldn't be followed without a refactor, say so in your summary (H24); for a gate FAIL, report it as in step 4.
Apply references/rules.md and the area references for the changed paths. Run the gate with --range <base>...<head> on the PR and report every FAIL and every WARN that the author didn't justify. Accept a FAIL the author reported with its rule id, path:line and the refactor it waits on (rules.md H24); an allowlist entry for a real violation is a finding. Rule violations in added code are findings, not nits.
Files in this skill:
references/rules.md, scripts/conventions_gate.py and scripts/test_conventions_gate.py: each repo keeps its own copy, and kiln_server's started from Kiln's.scripts/gate_config.json (skipped paths, which checks run where, allowed env-access paths, module-level patterns) and scripts/gate_allow.txt are Kiln-only. The gate reads both from its own directory.Run the gate's tests (stdlib + pytest only; the default repo test run doesn't collect dot-directories):
uv run python -m pytest .agents/skills/kiln-conventions/scripts/test_conventions_gate.pyConfig notes: a check missing from checks is disabled; an unknown check id or an invalid regex exits 2. Globs support * and ? (within one path segment) and **/ (zero or more directories); brackets are literal, so routes/[project_id]/** works. Allowlist lines are Python regexes searched in path<TAB>stripped line, optionally prefixed rule-id:.
Known limitations:
# comments are./* */ or <!-- --> block is scanned only on its first line and on lines that start with *.<p>Don't</p> <!-- … -->, or a ' in a regex literal) hides a comment that follows it.module-level-* checks are heuristics, which is why they are WARN. A module-level call written as an assignment is caught only when the right-hand side matches module_level_construct_patterns.history-comment phrase list skips common runtime-state phrasings ("no longer matches", "previously selected"), so some history phrased that way slips through. Review still applies rules.md A1.1042c3c
If you maintain this skill, you can claim it as your own. Once claimed, you can manage eval scenarios, bundle related skills, attach documentation or rules, and ensure cross-agent compatibility.