spec-lite

Par chorus-aidlc · chorus

Spécifications locales légères, natives Chorus, pour les workflows Chorus PM — un fichier de spec local durable `.chorus/specs/<slug>/spec.md` (un par fonctionnalité/capacité) édité sur place et JAMAIS synchronisé (l'historique git en est la trace), plus un dossier daté par effort de modification `.chorus/specs/<slug>/<YYYY-MM-DD>-<change-slug>/` contenant des documents typés Chorus (prd.md, tech_design.md, …) qui SONT mis en miroir 1:1 dans des Documents Chorus persistants via `--arg-file`. Solution de repli quand OpenSpec n'est pas utilisé ; une alternative légère en tokens au chemin plus lourd compatible openspec. Consulté depuis proposal / develop / yolo lorsque le mode spec est résolu à `lite`.

npx skills add https://github.com/chorus-aidlc/chorus --skill spec-lite

spec-lite — spec local durable + docs synchés par changement

Une sous-procédure partagée pour les skills de l'étape Chorus (proposal, develop, yolo) — le mode spec léger, modelé sur superpowers (une spec durable qui persiste, plus des artefacts par effort) : une spec locale durable par capacité (<slug>/spec.md, éditée sur place, jamais synchée — l'historique git en est la trace), plus un dossier daté par effort de changement (<slug>/<YYYY-MM-DD>-<change-slug>/ contenant des docs typés Chorus — prd.md, … — qui sont mirrorés 1:1 dans les Documents Chorus persistants). Aucune nouvelle CLI, aucun outil MCP, backend ou schéma — le mirroring réutilise les outils de document existants.

Mode (comment tu es arrivé ici)

Le mode spec est calculé par le hook SessionStart (hooks/resolve-spec-mode.sh), pas par toi — la section ## Spec Mode de ton contexte indique le CHORUS_SPEC_MODE résolu. Tu es ici parce qu'il a résolu à lite ; s'il est autre chose, ce skill est un no-op — reviens à l'appelant. (Pour la forme, la règle du hook : un CHORUS_SPEC_MODE explicite l'emporte, sinon OpenSpec si utilisable, sinon lite.)

La spec locale durable — <slug>/spec.md

.chorus/specs/<slug>/spec.md<slug> (kebab-case) désigne une capacité/feature, pas un seul changement. C'est la source unique, cumulative, lisible par humain de la capacité : éditée sur place par chaque changement, jamais mirrorée vers Chorus, sans IDs Chorus. Frontmatter minimal uniquement (slug, title, status: draft|active|done, created), puis prose — ## Intent, ## Requirements (prose + points d'acceptation en - [ ], pas de grammaire SHALL/scenario), ## Non-goals. Pars du template durable spec.md en ligne ci-dessous. Son historique git est l'enregistrement complet — pas de section changelog, pas d'aller-retour Chorus. Ce fichier N'ENTRE JAMAIS dans la boucle de mirror.

status décrit la capacité, pas un seul changement : active tant qu'un changement est en cours, done quand le changement actuel est livré et aucun n'est ouvert. Un nouveau changement contre une capacité done la rouvre à active, revient à done à la livraison.

Template — 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/), par ex. .chorus/specs/<slug>/2026-09-08-add-export/. La 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 synchés — chacun mappe à un Document Chorus persistent de son type. Leur frontmatter porte les IDs de sync proposalUuid et documentUuid (le type est implicite dans le nom de fichier). Pars du template de document pour dossier daté en ligne ci-dessous. Un changement différent de la même capacité est un dossier daté différent. Le dossier du changement actuel est édité et re-mirroré tout au long de son effort (jusqu'à la livraison) ; seuls les dossiers datés précédemment livrés restent gelés — tu n'édites pas en arrière un changement passé.

Deux fichiers nommés spec.md, rôles différents. Le <slug>/spec.md durable (local uniquement, sans IDs) n'est PAS le même qu'un doc de type spec par changement, qui vivrait à <slug>/<date>-<slug>/spec.md (synchéé, porte les IDs). Préfère prd.md comme doc principal par changement pour éviter la confusion.

Template — un document du dossier daté

Le type du document est implicite dans le nom de fichier (prd.mdprd, tech_design.mdtech_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>

Flow (un changement)

  1. Confirme que mode = lite (sinon no-op).
  2. Crée le dossier daté <slug>/<YYYY-MM-DD>-<change-slug>/ et écris ses docs synchésprd.md (requis), tech_design.md etc. seulement si justifié (utilise le template de document pour dossier daté ci-dessus).
  3. Met à jour <slug>/spec.md sur place à la nouvelle vérité cumulative (Requirements, points d'acceptation, status) — local uniquement, pas de sync.
  4. Crée le conteneur de proposal avec une ligne locator littérale dans description (sa propre ligne, sans ponctuation de fin) pour que develop trouve le changement : Spec-lite: .chorus/specs/<slug>/<YYYY-MM-DD>-<change-slug>/
  5. Mirror les docs du dossier daté vers Chorus (ci-dessous). Ajoute des tâches via chorus_pm_add_task_draftpas de tasks.md, pas de CLI / validate / archive, pas de grammaire delta. Les tâches vivent dans Chorus.
  6. Develop → continue à éditer spec.md + les docs du changement, re-mirrorant les docs du changement au fur et à mesure que le travail arrive et en cochant les points d'acceptation. À la livraison, mets le status: done du spec.md durable.

Mirror — uniquement les docs du dossier daté (jamais spec.md)

Chaque <type>.md du dossier daté mappe à un Document Chorus persistent de ce type, tracé par documentUuid dans le frontmatter du fichier. Remplis content à partir des bytes du fichier avec --arg-file — ne retape jamais le corps (dérive, brûle ~20k tokens). Un appel par fichier ; résout l'identité par documentUuid / (proposalUuid, type), jamais par title seul (une lookup trouvant zéro ou >1 DOIT halter). Garde chaque appel avec le helper chorus_check_response halt-on-error (openspec-aware §6). Pas de chorus sur PATH ? Reviens à chorus-mcp-call.sh + json_encode_file (openspec-aware §3.6). <slug>/spec.md n'est JAMAIS dans cette boucle.

  • Première fois qu'un doc est écrit (son dossier daté est nouveau) : écris proposalUuid dans frontmatter, mirror dans un draft 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". Édite le draft via chorus_pm_update_document_draft (draftUuid retourné) avant approbation. À l'approbation, il se matérialise en Document persistant — résout par (proposalUuid, type) via chorus_get_documents, enregistre documentUuid dans frontmatter, re-mirror une fois pour que local == Chorus.
  • Éditions ultérieures (un doc qui a déjà un documentUuid) : édite le fichier, puis chorus mcp call chorus_pm_update_document "{\"documentUuid\":\"$D\"}" --arg-file content=".chorus/specs/$SLUG/$DATED/<type>.md". Chaque update auto-incrémente la version du Document — cet historique de versions est l'enregistrement du doc du changement dans Chorus, aux côtés de git.

留痕 : historique git + versions de Document

git log -- .chorus/specs/$SLUG/ est la piste d'audit — les diffs sur place du spec.md durable plus les docs du changement de chaque dossier daté ; les versions auto-incrémentées des Documents mirrorés sont l'enregistrement parallèle dans Chorus. Aucune section changelog à maintenir. Seul .chorus/specs/ est versionné (.chorus/* + !.chorus/specs/).

Single-writer : le dossier est partagé — dans une vague multi-tâche seul l'orchestrateur / agent principal édite + re-mirror ; les workers parallèles signalent via chorus_report_work uniquement, relisant avant toute écriture. L'état des tâches vit dans Chorus, pas dans les docs — les points - [ ] sont l'intention d'acceptation, pas un tracker.

Skills similaires