spec-lite — spec local durable + docs synchronisés par changement (plugin dsh)
Une sous-procédure partagée pour les skills de l'étape Chorus (proposal-chorus, develop-chorus, yolo-chorus) — le mode spec léger, inspiré des superpowers (un spec durable qui perdure, plus des artefacts par effort) :
un spec local durable unique par capacité (<slug>/spec.md, édité sur place, jamais synchronisé — l'historique git est sa trace), plus un dossier daté par effort de changement (<slug>/<YYYY-MM-DD>-<change-slug>/
de docs typés Chorus — prd.md, … — synchronisés 1:1 dans les Documents Chorus persistants).
Pas de nouveau CLI, outil MCP, backend ou schéma — la synchronisation réutilise les outils de document existants.
Espace de noms des outils : les outils Chorus MCP sont exposés sous le préfixe
mcp__chorus__sur dsh — prépendez-le lors de l'invocation directe des outils MCP (voirchorus). Les appels de synchronisation de document NE passent PAS par le harnais MCP — ils passent par le CLIchorus(chorus mcp call, préféré) ou le wrapper local du packagechorus-mcp-call.mjsrésolu dans$CHORUS_MCP_CALL(fallback), qui dialoguent avec l'endpoint Chorus MCP via HTTP avec votre clé API. Voiropenspec-aware-chorus§2 / §3.6 pour le contrat exact (même transport, même helper halt-on-error).
Mode (comment vous êtes arrivé ici)
Le mode spec est calculé par le bundle chorus-dsh au chargement du plugin (resolveSpecMode, le miroir TS du résolveur bash canonique), pas par vous — le bundle le publie comme variable d'environnement CHORUS_SPEC_MODE et injecte une section ## Spec Mode dans le contexte de votre première étape énonçant la valeur résolue. Vous êtes ici parce qu'elle s'est résolue en lite ; si ## Spec Mode (ou CHORUS_SPEC_MODE) dit autre chose, ce skill est un no-op — retournez à l'appelant. (Pour le record, la règle : un CHORUS_SPEC_MODE explicite l'emporte, sinon OpenSpec si utilisable, sinon lite.)
Le spec local durable — <slug>/spec.md
.chorus/specs/<slug>/spec.md — <slug> (kebab-case) nomme une capacité/feature, pas un seul changement.
C'est l'unique, cumulatif, et lisible « vérité actuelle » de la capacité : édité sur place
par chaque changement, jamais mirrorisé vers Chorus, ne porte aucun id Chorus. Frontmatter minimal uniquement
(slug, title, status: draft|active|done, created), puis prose simple — ## Intent,
## Requirements (prose + points d'acceptation - [ ], pas de grammaire SHALL/scénario), ## Non-goals.
Partez du modèle spec.md durable inline ci-dessous. Son historique git est l'enregistrement complet — pas de section changelog, pas de round-trip Chorus. Ce fichier NE rentre JAMAIS dans la boucle de synchronisation.
status décrit la capacité, pas un seul changement : active tant qu'un changement est en cours,
done quand le changement courant est livré et aucun n'est ouvert. Un changement nouveau sur une capacité done la réouvre en active, retour à done à la livraison.
Modèle — le spec.md durable
---
slug: <kebab-case-capability>
title: <Capability title>
status: draft # draft | active | done
created: <YYYY-MM-DD>
---
## Intent
<what this capability is for, in prose>
## Requirements
<prose, no SHALL/scenario grammar>
- [ ] <acceptance point>
## Non-goals
- <explicitly out of scope>
Dossiers datés par changement — <slug>/<YYYY-MM-DD>-<change-slug>/
Chaque effort de changement est un dossier daté directement sous <slug>/ (pas de wrapper changes/), ex.
.chorus/specs/<slug>/2026-09-08-add-export/. Date + slug pour éviter les collisions de changements le même jour et
trier les dossiers par date. Il contient les docs typés Chorus pour CE changement — un fichier par type de Document :
| Fichier | Document.type |
Requis ? |
|---|---|---|
prd.md |
prd |
oui — le doc principal par changement |
tech_design.md |
tech_design |
optionnel — le « comment » |
adr.md / guide.md / spec.md |
adr / guide / spec |
optionnel |
Ces fichiers SONT synchronisés — chacun correspond à un Document Chorus persistant unique de son type. Leur
frontmatter porte les ids de synchronisation proposalUuid et documentUuid (le type est implicite dans le
nom du fichier). Partez du modèle de document de dossier daté ci-dessous. Un changement différent vers la même
capacité est un dossier daté différent. Le dossier du changement courant est édité et re-mirrorisé
tout au long de son effort (jusqu'à la livraison) ; seuls les dossiers datés précédemment livrés restent figés —
vous ne réécrivez pas un changement passé.
Deux fichiers nommés
spec.md, rôles différents. Le<slug>/spec.mddurable (local uniquement, pas d'ids) n'est PAS la même chose qu'un doc de typespecpar changement, qui vivrait à<slug>/<date>-<slug>/spec.md(synchronisé, porte des ids). Préférezprd.mdcomme doc principal par changement pour éviter la confusion.
Modèle — un document de dossier daté
Le type de document est implicite dans le nom du fichier (prd.md → prd, tech_design.md → tech_design, …),
PAS une clé frontmatter.
---
title: <Document title as it appears in Chorus>
proposalUuid: <uuid> # written on first mirror
documentUuid: # empty until the draft materializes on approval
---
# <Document title>
<body — this file's bytes are the source of truth for the Chorus Document>
Flux (un changement)
- Confirmez mode =
lite(sinon no-op). - Créez le dossier daté
<slug>/<YYYY-MM-DD>-<change-slug>/et écrivez ses docs de changement synchronisés —prd.md(requis),tech_design.mdetc. uniquement si justifié (utilisez le modèle de document de dossier daté ci-dessus). - Mettez à jour
<slug>/spec.mdsur place vers la nouvelle vérité cumulative (Requirements, points d'acceptation,status) — local uniquement, pas de synchronisation. - Créez le conteneur de proposal avec une ligne de localisateur littéral dans
description(sa propre ligne, pas de ponctuation finale) pour que develop trouve le changement :Spec-lite: .chorus/specs/<slug>/<YYYY-MM-DD>-<change-slug>/ - Mirrorisez les docs du dossier daté vers Chorus (ci-dessous). Ajoutez des tasks via
chorus_pm_add_task_draft— pas detasks.md, pas de CLI / validate / archive, pas de grammaire delta. Les tasks vivent dans Chorus. - Develop → continuez à éditer
spec.md+ les docs du changement, re-mirrorisant les docs du changement à mesure que le travail avance et cochant les points d'acceptation. À la livraison, réglez lestatus: doneduspec.mddurable.
Synchronisation — uniquement les docs du dossier daté (jamais spec.md)
Chaque <type>.md du dossier daté correspond à un Document Chorus persistant unique de ce type, suivi par
documentUuid dans le frontmatter du fichier. Remplissez content à partir des bytes du fichier avec --arg-file —
ne retapez jamais le corps (dérive, brûle ~20k tokens). Un appel par fichier ; résolvez l'identité par
documentUuid / (proposalUuid, type), jamais par title seul (une recherche trouvant zéro ou >1 DOIT
s'arrêter). Protégez chaque appel avec le helper halt-on-error chorus_check_response (openspec-aware-chorus
§6). Pas de chorus sur PATH ? Retombez sur le wrapper local du package chorus-mcp-call.mjs (résolu dans
$CHORUS_MCP_CALL au chargement du plugin) + json_encode_file (openspec-aware-chorus §3.6). <slug>/spec.md
ne rentre JAMAIS dans cette boucle.
- Première fois qu'un doc est écrit (son dossier daté est nouveau) : écrivez
proposalUuiddans le frontmatter, mirrorisez dans un brouillon de proposal —chorus mcp call chorus_pm_add_document_draft "{\"proposalUuid\":\"$P\",\"type\":\"prd\",\"title\":\"PRD: $TITLE\"}" --arg-file content=".chorus/specs/$SLUG/$DATED/prd.md". Éditez le brouillon viachorus_pm_update_document_draft(retournédraftUuid) avant approbation. À l'approbation, il matérialise en Document persistant — résolvez par(proposalUuid, type)viachorus_get_documents, enregistrezdocumentUuiddans le frontmatter, re-mirrorisez une fois pour que local == Chorus. - Éditions ultérieures (un doc qui a déjà un
documentUuid) : éditez le fichier, puischorus mcp call chorus_pm_update_document "{\"documentUuid\":\"$D\"}" --arg-file content=".chorus/specs/$SLUG/$DATED/<type>.md". Chaque mise à jour auto-incrémente la version du Document — cet historique de versions est le record du doc du changement dans Chorus, aux côtés de git.
Forme fallback (pas de chorus sur PATH) — construisez $PAYLOAD avec json_encode_file et appelez
"$CHORUS_MCP_CALL" chorus_pm_update_document "$PAYLOAD", puis chorus_check_response (voir
openspec-aware-chorus §3.6–§3.8 pour les blocs fallback exacts).
留痕: historique git + versions de Document
git log -- .chorus/specs/$SLUG/ est la piste d'audit — les diffs sur place du spec.md durable plus chaque
doc de changement du dossier daté ; les versions auto-incrémentées des Documents mirrorisés sont le record parallèle
dans Chorus. Pas de section changelog à maintenir. Seul .chorus/specs/ est versionnalisé (.chorus/* +
!.chorus/specs/).
Écrivain unique : le dossier est partagé — dans une vague multi-tâche seul l'orchestrateur / agent principal
édite + re-mirrorise ; les travailleurs parallèles rapportent via chorus_report_work uniquement, relisant avant toute écriture.
L'état des tasks vit dans Chorus, pas dans les docs — les points - [ ] sont l'intention d'acceptation, pas un tracker.