spec-lite

Par chorus-aidlc · chorus

Spécifications locales légères, natives Chorus, pour les workflows Chorus PM sur OpenClaw — un fichier de spec local durable `.chorus/specs/<slug>/spec.md` (un par fonctionnalité/capacité), modifié 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 de type Chorus (prd.md, tech_design.md, …) qui sont eux mirrorés 1:1 dans des Chorus Documents persistants via `--arg-file`. Solution de repli lorsqu'OpenSpec n'est pas utilisé ; alternative légère en tokens au chemin plus lourd prenant en charge openspec. Utilisé par proposal / develop / yolo lorsque le mode spec se résout à `lite`.

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

spec-lite — spec local durable + docs synchros par changement (plugin OpenClaw)

Une sous-procédure partagée pour les compétences de l'étape Chorus (proposal, develop, yolo) — le mode spec léger, inspiré des superpowers (un spec durable qui persiste, plus des artefacts par effort) : un spec local durable par capacité (.chorus/specs/<slug>/spec.md, édité sur place, jamais synchro — l'historique git est son 留痕), plus un dossier daté par effort de changement (<slug>/<YYYY-MM-DD>-<change-slug>/ de docs typés Chorus — prd.md, … — qui sont mirrorés 1:1 dans les Documents Chorus persistants). Aucun nouveau CLI, outil MCP, backend ou schéma — le mirroring réutilise les outils de document existants.

Espace de noms des outils : Les outils Chorus MCP sont exposés sous un préfixe chorus__ sur OpenClaw (ex. chorus__chorus_pm_add_document_draft). Les noms nus sont utilisés en prose pour lisibilité — préfixez chorus__ lors de l'invocation directe des outils MCP. Les appels de document-mirror ne passent PAS par le harnais MCP — ils utilisent le CLI chorus (chorus mcp call, préféré) ou le wrapper chorus-api.sh (secours), indépendamment du nommage chorus__ (voir Mirror ci-dessous).

Mode (comment tu es arrivé ici)

OpenClaw n'a pas de hook SessionStart et aucune valeur ## Spec Mode injectée — contrairement aux ports Claude Code / Codex / Pi, rien ne précalcule le mode dans ton contexte. Le mode est résolu en sourçant le resolver que le plugin embarque (bin/resolve-spec-mode.sh, byte-identique à la copie Claude Code), au moment où une compétence d'étape atteint son étape spec-mode — voir openspec-aware §1 pour le bloc locate-and-source. Ne redérive jamais la règle à partir de la prose. Tu peux aussi imprimer le mode résolu n'importe quand avec /chorus spec (ou le bloc ## /chorus status). Tu es ici parce que cette résolution a retourné lite ; si elle retournait autre chose, cette compétence est un no-op — retour à l'appelant. (Pour info, la règle : un explicit CHORUS_SPEC_MODE gagne, sinon OpenSpec si utilisable, sinon lite.)

Le spec local durable — <slug>/spec.md

.chorus/specs/<slug>/spec.md<slug> (kebab-case) désigne une capacité/fonctionnalité, pas un changement. C'est le single, cumulatif, humainement lisible « état de vérité courant » de la capacité : édité sur place par chaque changement, jamais mirroré vers Chorus, ne porte aucun id Chorus. Frontmatter minimal seulement (slug, title, status: draft|active|done, created), puis prose nature — ## Intent, ## Requirements (prose + points d'acceptation - [ ], pas de grammaire SHALL/scénario), ## Non-goals. Démarre du template spec.md durable embarqué ci-dessous. Son historique git est le dossier complet — pas de section changelog, pas de aller-retour Chorus. Ce fichier n'entre JAMAIS dans la boucle mirror.

status décrit la capacité, pas un changement isolé : active tant qu'un changement est en vol, done quand le changement courant livre et aucun n'est ouvert. Un changement nouveau contre une capacité done la réouvre à active, retour à 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/), ex. .chorus/specs/<slug>/2026-09-08-add-export/. Date + slug pour que les changements du même jour ne se heurtent pas et les dossiers se trient 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 synchros — chacun se mappe à un Document Chorus persistant de son type. Leur frontmatter porte les ids sync proposalUuid et documentUuid (le type est implicite par le nom de fichier). Démarre du template dated-folder document embarqué ci-dessous. Un changement différent à la même capacité est un dossier daté différent. Le dossier du changement courant est édité et re-mirroré tout au long de son effort (jusqu'à livraison) ; seuls les dossiers datés précédemment livrés sont laissés gelés — tu ne reviens pas en arrière et tu ne rédige pas un changement passé.

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

Template — un document dated-folder

Le type de document est implicite par le nom de fichier (prd.mdprd, tech_design.mdtech_design, …), NON 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 mode = lite (résolu par le resolver embarqué, openspec-aware §1 ; sinon no-op).
  2. Crée le dossier daté <slug>/<YYYY-MM-DD>-<change-slug>/ et écris ses docs de changement synchrosprd.md (requis), tech_design.md etc. seulement si justifié (utilise le template dated-folder document ci-dessus).
  3. Mets à jour <slug>/spec.md sur place à la nouvelle vérité cumulative (Requirements, points d'acceptation, status) — local seulement, pas de sync.
  4. Crée le conteneur proposal avec une ligne localisatrice littérale dans description (propre ligne, pas de ponctuation finale) 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 les 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-mirrorer les docs du changement au fur et à mesure que le travail avance et cocher les points d'acceptation. À la livraison, mets le status: done du spec.md durable.

Mirror — seulement les docs dated-folder (jamais spec.md)

Chaque <type>.md dated-folder se mappe à un Document Chorus persistant 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, consomme ~20k tokens). Un appel par fichier ; résous l'identité par documentUuid / (proposalUuid, type), jamais par title seul (une recherche trouvant zéro ou >1 DOIT halter). Protège chaque appel avec le helper chorus_check_response halt-on-error (openspec-aware §6). Pas de chorus sur PATH ? Retombe sur le wrapper chorus-api.sh + json_encode_file (openspec-aware §3.6 ; le wrapper OpenClaw est invoqué comme chorus-api.sh mcp-tool <tool> "$PAYLOAD"). <slug>/spec.md n'est JAMAIS dans cette boucle.

  • Première fois qu'un doc est rédigé (son dossier daté est nouveau) : écris proposalUuid dans le frontmatter, mirrorе dans un proposal draftchorus mpc 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ésous par (proposalUuid, type) via chorus_get_documents, enregistre documentUuid dans le 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 mpc 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 version est l'enregistrement du doc du changement dans Chorus, aux côtés de git.

留痕 : historique git + versions Document

git log -- .chorus/specs/$SLUG/ est la piste d'audit — les diffs du spec.md durable sur place plus les docs de 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/).

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

Skills similaires