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
- It moves to
step/todoand receives its milestone. - Design.
Plan d'action,RecetteandPlan de MEPget written, with comments for anything a macro task cannot hold. It moves tostep/in-progress. - Build, on a branch (
feat/…,fix/…) —AGENTS.mdhas the commit rules. - 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 inRecette. - 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
Recettebecause 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. - Rebase onto
main, which only ever fast-forwards. The issue moves tostep/done. - 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-frontendmakes 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.