6 Workflow
Claude Agent edited this page 2026-09-23 22:41:19 +01:00
This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

Workflow — how work is tracked

Written in English per the language rule in AGENTS.md. The issue template below is quoted in French because that is the language issues are written in.

The forward plan lives in the issue tracker and the design documents live in this wiki. Neither is in the repository any more. There used to be a docs/roadmap.md holding phases and per-task status; it was deleted once the tracker took over, because a plan in a file and a plan in a tracker disagree within a week and the file is the one nobody updates.

The rest of docs/ followed it here. The cost is real and accepted: the wiki is a separate git repository, so a design decision can no longer land in the same commit as the code it describes. Nothing enforces the correspondence any more — see Keeping this wiki honest at the bottom.

Where

https://git.lozach.eu/maxime/OrganisateurFamilial — Forgejo, same host as the git remote. Issues are readable without authentication:

curl -s "https://git.lozach.eu/api/v1/repos/maxime/OrganisateurFamilial/issues?state=all"

Labels

Every issue carries three labels.

Its nature:

Label Meaning
bug A functional or technical regression in the application
enhancement A new feature, or a technical improvement

Its priority — priority/high, priority/medium or priority/low. Priority orders the work inside the backlog; it says nothing about which version ships it, which is what the milestone says.

Its step — see below.

The priority/… and step/… families are declared exclusive in Forgejo, so setting one clears the other of the same family. bug and enhancement are not: nothing stops both being set, and nothing should.

The body of an issue

Four sections, always in this order:

## Description
Le besoin, ou le bug et sa reproduction. Fait office de spécification : doit contenir
tout ce qu'il faut pour comprendre le ticket sans autre contexte.

## Plan d'action
- [ ] Tâches macro. Une tâche peut renvoyer à un commentaire du ticket qui la détaille.

## Recette
- [ ] Tâches de vérification à faire en fin de développement.
- [ ] Mise à jour du wiki (décision, schéma, interface, périmètre).
- [ ] « Corriger les retours fonctionnels » quand un commentaire porte des retours.

## Plan de MEP
- [ ] Livraisons et migrations à prévoir pour mettre ce ticket en production.
Ou, s'il n'y a rien à livrer, une phrase sans case à cocher.

Only Description is filled when the issue is created. The other three are written during the design phase, when the issue is actually picked up — planning the delivery of something nobody has looked at yet produces a plan that is wrong by the time it is read. Until then they hold a - [ ] TODO.

Description is the one section that must be complete from the start. It is what makes an issue pickable months later: a bug needs the reproduction, an enhancement needs the need it answers and what it touches. "See the roadmap" is exactly what this replaced.

Recette carries the wiki line, always. It is the only place in the process where anything checks that the documentation followed the code — the repository cannot, since the wiki is a different git repository. Leaving the line ticked without having opened the wiki is how these pages start lying. See Keeping this wiki honest below.

Detail belongs in comments, not in a longer body. A macro task in Plan d'action that needs breaking down points at a comment carrying its sub-tasks. The body stays the map; comments hold the terrain, including functional feedback, which becomes a « Corriger les retours fonctionnels » line in Recette.

A checkbox is an action someone will perform, nothing else. An issue is done when every box is ticked, so a box that holds a statement — "nothing to migrate", "depends on the runner staying up", "unblocks #11" — can never honestly be ticked, and leaves a finished issue looking unfinished (#6's Plan de MEP did exactly this). Context, dependencies and consequences are prose or plain - bullets. A section with nothing to do says so in one sentence, without a box: Plan de MEP is often that section, since most issues ship with the next image and need no step of their own.

Steps

An issue's step is a label, not a project column:

Label Means
step/backlog Where every issue lands. Not scheduled, no milestone
step/todo Picked for the next version. Gets a milestone at this point
step/in-progress Being worked on, on its own branch
step/done Merged and validated, waiting for the version to ship
step/delivered The milestone shipped. Archived after a while

It is a label because Forgejo 16 / Gitea 1.22 has no projects endpoint at all. Labels, milestones, bodies and comments are writable over the REST API; a project board's columns are only reachable from the web interface, which would put half the workflow out of reach of any automation. The board was dropped for that reason.

A milestone is one upcoming version (1.0.x today). An issue gets one when it moves to step/todo, never before — the backlog is not a version. When the version ships, every issue of its milestone moves to step/delivered together, and the milestone closes.

How an issue becomes a commit

  1. It moves to step/todo and receives its milestone.
  2. Design. Plan d'action, Recette and Plan de MEP get written, with comments for anything a macro task cannot hold. It moves to step/in-progress.
  3. Build, on a branch (feat/…, fix/…) — AGENTS.md has the commit rules.
  4. Recette. This is where review happens, not at integration time. Run the mechanical gates, then /code-review; feedback goes into a comment on the issue, and the comment becomes a « Corriger les retours fonctionnels » line in Recette.
  5. Update this wiki, in the same session — before the rebase, while what changed and why is still in front of you. It is a line of Recette because nothing else will catch it: the wiki is a separate git repository, and no test, lint rule or review step spans both. The table below says which page takes what.
  6. Rebase onto main, which only ever fast-forwards. The issue moves to step/done.
  7. The version ships; its milestone's issues move to step/delivered.

Commits and branches do not have to name the issue, but a commit body that explains a symptom is worth more when it names the issue that reported it.

The mechanical gates

Run during Recette, before /code-review — there is no point reading code that does not pass its own tests. CI runs the first block on every push and the third on main only, and never the second (see What CI runs below) — so the list stays here in full: the gates are what you owe the change, not what a runner happens to be configured to do.

make lint typecheck test
make build-frontend
grep -m1 -E '^\s*(import|export)' ex_app/src/dist/js/main.js && echo "BUNDLE NOT IIFE" || echo "bundle ok"
cd e2e && npm test

Two traps this list exists to avoid:

  • The e2e suite needs a frontend that was actually rebuilt. Forgetting make build-frontend makes the suite run against the previous bundle — silently, and it may well pass.
  • If the suite fails, establish the baseline before reading a line of the diff. Stash the work and run the same suite twice on main. Two runs that disagree mean the measurement is broken, not the code. An afternoon once went into blaming a feature for failures that were instance state.

The backend npm test includes routes.test.ts, which compares the Fastify routes against the <route> entries in appinfo/info.xml. An undeclared route fails there; do not check it by hand.

What CI runs, and what it does not

Two workflows, both in .github/workflows/ — Forgejo reads that directory as well as .forgejo/workflows/, so the GitHub layout is kept and a mirror would work unchanged.

ci.yml e2e.yml
Job checks e2e
Trigger every push, every branch push on main, or workflow_dispatch
Runs one make install, then lint, typecheck, test, build make up, the Playwright suite, make down
Takes about 2 min 30 about 20 minutes

checks watches every branch, main included — the point is the branches. main only ever fast-forwards and there are no pull requests, so a workflow watching main alone would validate what is already in. The branch, before the rebase, is the only moment a failure prevents something.

The end-to-end suite does not run on branches. 96 tests, one worker, in series behind a full Nextcloud install, on a runner that does one thing at a time — every branch would put twenty minutes between two pushes. Dispatch it by hand from the Actions tab when a branch needs it, which is what workflow_dispatch is for. It is blocking, and a failed run uploads playwright-report/ and test-results/ as an artefact — traces and screenshots included, which is the only way a failure that happened on another machine is readable at all.

Blocking does not mean trustworthy on the first reading: the runner is not a reliable machine, and Dev environment says how it fails. Check a red end-to-end run against a second one before believing it.

CI is not an integration barrier. There is no pull request to block and main takes whatever fast-forwards onto it. CI reports; Recette is still where review happens, and the discipline is still the author's.

One consequence worth naming: what passes locally must pass in CI, which is why the lint gate is npm run lint unchanged, warnings and all, and why the vitest worker cap lives in vitest.config.ts rather than in a workflow flag. A CI that enforces rules nobody can reproduce at home becomes a second, unarguable referee.

Keeping this wiki honest

The repository can no longer keep itself in sync with these pages — they are a different git repository, and no test, no lint rule and no review step spans both. Updating the wiki is therefore part of finishing an issue, in the same session as the code, not a tidy-up for later.

What the work changes What must move
A feature, a decision Architecture (+ Scope if the scope moves)
The interface model, navigation UX
A table or a column the schema section of Architecture
The local stack Dev environment
A rule the code follows Code guidelines
An undocumented AppAPI behaviour .claude/skills/nextcloud-exapp-dev/references/ in the repo
A piece of work finished or replanned its issue on the tracker

Code comments cite decisions by number — D33, D36 — and those numbers resolve here. A decision that gets renumbered or dropped leaves those comments pointing at nothing, and nothing will tell you.