tour 0001 (claude, implementer) : fondation — README, PROTOCOL v0, config, backlog B-1..B-13
Disput-Turn: 0001 Disput-Participant: claude Disput-Role: implementer Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,50 @@
|
||||
# Backlog — disput
|
||||
|
||||
Une tâche par ligne : `- [ ] B-<n> : …`. On coche à la fin du tour qui
|
||||
la termine, en citant ce tour. `[USER]` = décision humaine, jamais prise
|
||||
par un implémenteur. Numéros uniques, jamais réutilisés.
|
||||
|
||||
## v0 — amorçage (le relais remplace la navette manuelle)
|
||||
|
||||
- [ ] B-1 : squelette du paquet Python (`pyproject.toml`, `src/disput/`,
|
||||
point d'entrée `disput`, `argparse` + `tomllib`, aucune dépendance
|
||||
externe en v0), `tests/` en `unittest`
|
||||
- [ ] B-2 : parseur de fichiers de tour (en-tête `+++` TOML, sections
|
||||
Réponses/Items, identifiants, destinataires) + `disput lint`
|
||||
- [ ] B-3 : déduction de l'état des items à partir des tours (§5) +
|
||||
`disput status`
|
||||
- [ ] B-4 : ordonnanceur (§7) en **fonction pure** :
|
||||
(config, tours, diff du dernier tour) → (participant, rôle) | USER
|
||||
| DONE. Tests exhaustifs, y compris l'anti ping-pong
|
||||
- [ ] B-5 : vérification des invariants après un tour (§8), git
|
||||
uniquement
|
||||
- [ ] B-6 : adaptateurs `claude` et `vibe` (lancement non interactif,
|
||||
env forcé, budget/max-turns, log local) + adaptateur `stub` pour
|
||||
les tests
|
||||
- [ ] B-7 : `disput run` (verrou, boucle, arrêt, `.disput/last-run.md`,
|
||||
notification) + scénarios stub « tricheurs » : pas de commit,
|
||||
réécriture, modification d'un tour existant, réviseur qui touche
|
||||
au code, `status=USER`
|
||||
- [ ] B-8 : `disput decide "…"` (écrit et commite le tour `user`)
|
||||
- [ ] B-9 : garde-fous appliqués par adaptateur, à partir de `[guards]`
|
||||
(deny et hook Claude, agent et hook `pre_tool` Vibe), avec preuve
|
||||
qu'un `git push` est refusé dans chaque adaptateur
|
||||
- [ ] B-10 : `disput init` (crée `.disput/` dans un projet existant)
|
||||
- [ ] B-11 : premier `disput run --max-turns 2` sur disput lui-même,
|
||||
sous surveillance de l'humain
|
||||
- [ ] B-12 : adoption par qbt-manager (`disput init`, `disput.toml`
|
||||
avec les checks preflight/tests et les garde-fous dry-run, rôle
|
||||
`security` sur ses chemins sensibles)
|
||||
|
||||
## Décisions humaines
|
||||
|
||||
- [ ] B-13 [USER] : licence, et dépôt public ou privé (remote)
|
||||
|
||||
## Plus tard (seulement sur besoin observé)
|
||||
|
||||
- ACP comme transport unifié des adaptateurs, avec des garde-fous
|
||||
centralisés
|
||||
- reviewers en parallèle (worktrees)
|
||||
- interface en terminal (affichage des tours en direct, décisions à
|
||||
l'écran)
|
||||
- adaptateurs supplémentaires (codex, gemini, opencode…)
|
||||
@@ -0,0 +1,53 @@
|
||||
# Configuration disput pour le développement de disput lui-même.
|
||||
|
||||
[project]
|
||||
name = "disput"
|
||||
instructions = "PROTOCOL.md"
|
||||
|
||||
[[participants]]
|
||||
name = "claude"
|
||||
adapter = "claude"
|
||||
roles = ["implementer", "reviewer", "security"]
|
||||
|
||||
[[participants]]
|
||||
name = "vibe"
|
||||
adapter = "vibe"
|
||||
roles = ["implementer", "reviewer", "security"]
|
||||
|
||||
[[participants]]
|
||||
name = "user"
|
||||
adapter = "human"
|
||||
roles = ["decider"]
|
||||
|
||||
[[roles]]
|
||||
name = "implementer"
|
||||
writes_code = true
|
||||
triggers = ["backlog"]
|
||||
brief = "Prendre la tâche ouverte la plus haute du backlog, l'implémenter, la tester réellement, commiter."
|
||||
|
||||
[[roles]]
|
||||
name = "reviewer"
|
||||
writes_code = false
|
||||
triggers = ["code_changed"]
|
||||
brief = "Review sévère du diff depuis la base du tour : bugs, sécurité, hypothèses non validées, écart entre code et tours. Ré-exécuter, ne pas croire."
|
||||
|
||||
[[roles]]
|
||||
name = "security"
|
||||
writes_code = false
|
||||
triggers = ["paths:src/disput/guards*,src/disput/adapters/**,.disput/disput.toml"]
|
||||
brief = "Audit des garde-fous : un agent peut-il contourner un deny, échapper à l'env forcé, pousser, réécrire l'historique ?"
|
||||
|
||||
[[roles]]
|
||||
name = "decider"
|
||||
writes_code = false
|
||||
triggers = []
|
||||
brief = "L'humain. Tranche les décisions [USER]."
|
||||
|
||||
[[checks]]
|
||||
name = "tests"
|
||||
command = "python -m unittest discover -s tests"
|
||||
policy = "no_regression" # passera à must_pass dès qu'il y aura des tests
|
||||
|
||||
[guards]
|
||||
env = {}
|
||||
deny = ["git push", "git filter-branch", "git filter-repo", "git rebase", "git reset --hard", "git commit --amend", "git update-ref", "git reflog expire"]
|
||||
@@ -0,0 +1,98 @@
|
||||
+++
|
||||
turn = 1
|
||||
participant = "claude"
|
||||
role = "implementer"
|
||||
base = "" # premier tour, pas de HEAD antérieur
|
||||
status = "CONTINUE"
|
||||
+++
|
||||
|
||||
# Tour 1 — claude, implementer : fondation du dépôt
|
||||
|
||||
## Réponses
|
||||
|
||||
Aucune : premier tour.
|
||||
|
||||
## Travail
|
||||
|
||||
Décision `user` à l'origine du dépôt, prise hors tour et consignée ici
|
||||
(règle 5) :
|
||||
|
||||
- créer un outil d'orchestration multi-agents, nommé **disput**, dans
|
||||
son propre dépôt ;
|
||||
- ouvrir dès le départ le protocole à **N participants et à des rôles
|
||||
configurables**, pas seulement à un dialogue à deux ;
|
||||
- développer l'outil **en parallèle de son expérimentation**, avec son
|
||||
propre protocole (dogfooding) ;
|
||||
- objectif premier : supprimer la navette manuelle (« à toi ») de
|
||||
l'humain.
|
||||
|
||||
Ce tour pose :
|
||||
|
||||
- `README.md` : raison d'être, principes, usage visé ;
|
||||
- `PROTOCOL.md` : spec normative v0 (concepts, fichiers de tour
|
||||
immuables, cycle de vie des items, rôles et déclencheurs,
|
||||
ordonnancement, invariants, garde-fous, place de l'humain, pratique
|
||||
manuelle) ;
|
||||
- `.disput/disput.toml` : configuration du projet lui-même (claude et
|
||||
vibe éligibles aux trois rôles, user décideur) ;
|
||||
- `.disput/backlog.md` : B-1 à B-13 ;
|
||||
- `AGENTS.md` / `CLAUDE.md` minces, qui renvoient à `PROTOCOL.md`.
|
||||
|
||||
Origine : ce protocole généralise celui pratiqué sur 16 tours dans un
|
||||
autre projet du même utilisateur (dialogue Claude/Vibe en
|
||||
implémenteur/reviewer alternés via un DEVLOG unique). Ce qui est repris :
|
||||
- la réponse point par point ;
|
||||
- l'interdiction de modifier les entrées de l'autre ;
|
||||
- l'obligation de vérifier soi-même.
|
||||
|
||||
Ce qui change :
|
||||
- un fichier par tour plutôt qu'un DEVLOG unique ;
|
||||
- l'état des items déduit des tours ;
|
||||
- un ordonnanceur à règles au lieu d'une simple alternance ;
|
||||
- des invariants vérifiables par machine.
|
||||
|
||||
## Vérifications
|
||||
|
||||
Aucun code ce tour, donc rien à exécuter. Relecture de cohérence :
|
||||
l'en-tête de ce fichier suit le §4, et les identifiants d'items le §4
|
||||
également.
|
||||
|
||||
## Items
|
||||
|
||||
- [I-0001-1] → role:reviewer : en-tête de tour en **TOML entre `+++`**
|
||||
plutôt qu'en YAML `---`, pour rester sans dépendance (`tomllib` est
|
||||
dans la stdlib depuis 3.11). C'est moins répandu que YAML chez les
|
||||
agents. Risque-t-il de mal formater des en-têtes ? Le coût d'une
|
||||
dépendance YAML est-il préférable ?
|
||||
- [I-0001-2] → role:reviewer : l'état des items est **déduit** des
|
||||
tours, sans fichier d'état. C'est robuste à la falsification, mais
|
||||
dépendant d'un parsing strict des lignes `- [I-…]` dans du markdown
|
||||
libre. Faut-il un bloc structuré (TOML) pour les réponses et les items
|
||||
plutôt que des puces ?
|
||||
- [I-0001-3] → role:reviewer : **trou dans le §7** que je signale
|
||||
moi-même. Un item adressé à `@participant`, sans rôle, ne dit pas dans
|
||||
quel rôle ce participant doit jouer. Ma proposition : il joue dans le
|
||||
rôle qu'il tenait au tour visé par l'item, et à défaut `implementer`.
|
||||
D'accord, ou faut-il interdire l'adressage `@participant` nu ?
|
||||
- [I-0001-4] → role:reviewer : « un tour = un rôle ». Si `reviewer` et
|
||||
`security` sont déclenchés par le même diff et qu'un seul participant
|
||||
est éligible (≠ auteur), il joue deux tours d'affilée. Est-ce
|
||||
acceptable, ou faut-il autoriser un tour multi-rôles (un fichier, deux
|
||||
sections) ?
|
||||
- [I-0001-5] → role:security : le §9 promet trop. Des `deny` par motif
|
||||
de chaîne se contournent facilement : `git -c … push`, des alias, un
|
||||
`sh -c`, un `subprocess` en Python… L'invariant §8.3 (refs distantes)
|
||||
ne détecte le push qu'**après coup**. Piste de défense en amont :
|
||||
forcer dans `[guards].env` des variables qui rendent le transport
|
||||
inopérant pendant un tour, par exemple une commande SSH qui échoue
|
||||
toujours, ou un `pushurl` invalide via la config git d'environnement.
|
||||
Est-ce suffisant, contournable, ou à combiner avec autre chose ?
|
||||
- [I-0001-6] → role:reviewer : v0 **sans aucune dépendance externe**
|
||||
(`argparse`, `unittest`, `tomllib`). Est-ce tenable jusqu'à B-7 ? Ou
|
||||
vaut-il mieux assumer tout de suite une CLI (Typer/Click) et pytest ?
|
||||
|
||||
**Prochain tour, d'après le §7 :** ce tour modifie des fichiers hors de
|
||||
`.disput/` (`code_changed`), donc c'est au **reviewer**, tenu par
|
||||
**vibe** (≠ auteur). `.disput/disput.toml` correspond aussi au
|
||||
déclencheur `paths:` de `security`, donc vibe joue ensuite **security**,
|
||||
sauf si I-0001-4 est tranché autrement entre-temps.
|
||||
Reference in New Issue
Block a user