Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 20 additions & 1 deletion .claude/rules/copier-template.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,10 @@ the next `copier update` either reverts them or turns them into a merge
conflict.

Add project specific build steps to `TaskfileCustom.yaml` instead - note the
`.yaml` spelling, since only that one is included. Project specific agent
`.yaml` spelling, since only that one is included. A GitLab pipeline takes
project specific jobs from `.gitlab-ci-custom.yml` the same way, included when
that file exists; it can add to a templated job but not redefine one, and
`.github/workflows/` has no equivalent hook. Project specific agent
instructions belong in `CLAUDE.md`, which the template never writes and which
is read alongside these rules. Personal tool permissions belong in
`.claude/settings.local.json`, which is git-ignored.
Expand Down Expand Up @@ -49,6 +52,22 @@ silence the rule for code nobody has looked at. Report it with the
`template-feedback` skill too, since a rule that is wrong here is usually wrong
in other projects as well.

One class of that is already settled and needs neither a human nor a report:
`PLR0913` and `PLR0917` on a signature whose arity a framework fixes rather
than the author - a plugin constructor with one argument per `PluginParameter`,
a Click command with one per option. Suppress both on the `def`, with the
reason above it. Neither escape ruff suggests is available, since keyword-only
arguments answer `PLR0917` but not `PLR0913`, and folding the arguments into
one object breaks the one-argument-per-option mapping the framework relies on.

`ARG002` is settled on the same grounds, one argument further in: a method the
framework calls has the signature the framework declares, so an argument the
implementation does not need cannot be dropped - a workflow task with no input
ports never reads `inputs`. Suppress it on the argument, again with the reason
above it. Renaming it to `_inputs` silences ruff as well, and is wrong here:
the name belongs to an API the caller may use by keyword, as this project's own
tests do.

## Every user visible change gets a changelog entry

`CHANGELOG.md` follows [Keep a Changelog](https://keepachangelog.com/). Add an
Expand Down
38 changes: 38 additions & 0 deletions .claude/skills/copier-update/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,44 @@ the template actually changed, such as a bumped dependency constraint.
Example files that were deleted after generation can reappear when the template
changes them. Delete them again.

## What the merge will not tell you

A conflict is raised only where copier could not decide. The cases that cost
the most time are the silent ones, and both directions have happened:

- **The template's new value is not applied.** The template set
`cmem-cmemc` to `^25.3.0` in v7.3.0 and lowered it again to `>=24.2.0` in
v8.0.0. Four repositories updated straight through that release and on to
v9.6.1, and every one still carried the caret afterwards. No commit in them
re-introduced it and no conflict was ever raised. It stayed harmless for a
year, until click 8.5 began rejecting an empty colour that cmemc 25 passes
through - and then several test suites failed at once with
`Unknown color ''`.
- **This project's value is replaced by the template's.** A project carrying its
own `[tool.ruff.lint] ignore` and `per-file-ignores` entries lost them
wholesale to the template's shorter lists, and the update appeared to add 409
lint findings. They were not debt; the configuration that had silenced them
was gone.

So do not read "no conflicts" as "nothing to check". After updating, look at
`pyproject.toml` deliberately - at dependency constraints, and at every
list-valued setting, because a list is replaced whole rather than merged
entry by entry.

The reliable check is to render a throwaway project from the same answers and
diff against it, which shows both what should have arrived and what should not
have:

```bash
copier copy --trust --defaults --vcs-ref <the tag you updated to> \
-d project_slug=<slug> -d project_type=<plugin|generic> \
gh:eccenca/cmem-plugin-template /tmp/reference
diff /tmp/reference/pyproject.toml pyproject.toml
```

Treat a sudden jump in lint findings as suspected configuration loss rather
than real debt, and check that first.

## After updating

```bash
Expand Down
16 changes: 14 additions & 2 deletions .claude/skills/plugin-documentation/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ This governs the text a user reads inside eccenca Corporate Memory: the `label`,
Python docstrings, error messages or identifiers. Those are read by developers
and follow the ordinary code conventions.

`documentation` is rendered as Markdown, so backticks, `**bold**` and links all
work. `description` is a single line shown next to the task in the task list.
`documentation` is rendered as Markdown, so backticks, `**bold**`, links, `##`
headings and lists all work. `description` is a single line shown next to the task in the task list.

## Ground every claim in the code

Expand Down Expand Up @@ -66,6 +66,18 @@ lines. Do not pad a simple task to match a complex one, and do not cut a
complex one down to match a simple one. A task with three mutually exclusive
modes genuinely needs more words than one with a single input port.

Mark the beats by length, not by taste. While the block is short - which for
most tasks it is - write it as one run of paragraphs and let the beats follow
each other unannounced. Once it passes roughly twenty lines, give each beat a
`##` heading named after it, so a reader scans for the beat they need instead of
reading until they find it. The caveats beat is the one that stops working as
prose first, and reads best as a list with the claim in bold at the front of
each item.

Letting the length decide is what keeps sibling tasks in one package looking
like one product. A user meets several of them in a workspace, and two
documentation styles there read as two different things.

## Parameters

The first sentence says what the parameter controls. Add further sentences only
Expand Down
Loading
Loading