proposal

Par chorus-aidlc · chorus

Workflow de proposition Chorus sur Hermes — créez des propositions avec des brouillons de documents et de tâches, gérez le DAG de dépendances, validez, soumettez, et exécutez le réviseur de propositions en lecture seule via delegate_task.

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

Skill Proposal

Ce skill couvre l'étape Planning du workflow AI-DLC : créer des Proposals contenant des brouillons de documents (PRD, tech design) et des brouillons de tâches avec des DAGs de dépendances, puis les soumettre pour révision par l'Admin.


Vue d'ensemble

Après résolution de l'élaboration d'une Idea (voir le skill idea, skill_view("chorus:idea")), l'Agent PM crée une Proposal — un conteneur qui contient des brouillons de documents et des brouillons de tâches. À l'approbation de l'Admin, ces brouillons se matérialisent en vrais Documents et Tâches.

Elaboration resolved --> Create Proposal --> Add drafts --> Validate --> Submit --> Reviewer --> Admin review

Outils

Gestion des Proposals :

Outil Objectif
chorus_pm_create_proposal Créer un conteneur de proposal vide
chorus_pm_validate_proposal Valider la complétude de la proposal (retourne erreurs, avertissements, info)
chorus_pm_submit_proposal Soumettre la proposal pour approbation Admin (draft -> pending)

Brouillons de documents :

Outil Objectif
chorus_pm_add_document_draft Ajouter un brouillon de document à la proposal
chorus_pm_update_document_draft Mettre à jour le contenu du brouillon de document
chorus_pm_remove_document_draft Retirer un brouillon de document de la proposal

Brouillons de tâches :

Outil Objectif
chorus_pm_add_task_draft Ajouter un brouillon de tâche (retourne draftUuid pour chaînage de dépendances)
chorus_pm_update_task_draft Mettre à jour le brouillon de tâche
chorus_pm_remove_task_draft Retirer un brouillon de tâche de la proposal

Post-approbation (les tâches existent) :

Outil Objectif
chorus_create_tasks Créer des tâches en batch (supporte les dépendances intra-batch via draftUuid)
chorus_pm_assign_task Assigner une tâche à un Agent Développeur
chorus_pm_create_document Créer un document autonome
chorus_pm_update_document Mettre à jour le contenu du document (incrémente la version)
chorus_update_task (avec addDependsOn / removeDependsOn) Ajouter ou retirer les dépendances de tâche (avec détection de cycles)

Outils partagés (checkin, query, comment, search, notifications) : voir le skill overview (skill_view("chorus:chorus"))


Workflow

Étape 0 : Réutiliser les preuves et vérifier les nouvelles lacunes factuelles

Lisez la ou les Idea(s) d'entrée confirmée(s) ou les Documents, les spécifications actuelles, les Références et le contexte récent avant de rédiger. Réutilisez d'abord les résultats existants ; invoquez le skill research (skill_view("chorus:research"), règles partagées) uniquement pour une nouvelle lacune de conception factuelle ou une demande explicite de l'utilisateur, sauf skip explicite. Fournissez l'étape Proposal, la question focalisée, les preuves existantes et le budget. Ne répétez pas automatiquement la recherche d'Idea, y compris lors d'une reprise de planning ; cet itinéraire s'applique aussi aux entrées créées par formulaire/MCP sans flag de recherche.

Si la Proposal n'existe pas encore, conservez les URL/titres/types de source candidates dans le contexte courant, puis incluez-les dans references[] lors de l'appel Step 1 chorus_pm_create_proposal si possible. Lisez chorus_get_proposal après pour obtenir les vrais references[].uuid ; la création inline retourne l'UUID du conteneur, pas les UUIDs de preuves individuelles. Si elle existe déjà, réutilisez ses preuves ou attachez de nouvelles sources via chorus_add_reference et prenez l'UUID de référence retourné. Écrivez ensuite des citations comme [1](ref:<uuid-de-référence-réel>) à côté des déclarations soutenues dans la conception/les spécifications. Ne fabriquez jamais d'UUIDs ni ne substituez l'UUID Proposal.

En modes OpenSpec/spec-lite, résolvez le mode de spec existant et le localisateur comme ci-dessous, mettez à jour les fichiers locaux autoritaires avec les résultats et des citations réelles, puis miroir les octets de fichier en utilisant chorus mcp call … --arg-file content=<fichier> via terminal (ou, quand chorus n'est pas sur PATH, l'outil MCP natif avec content défini aux octets exacts du fichier lus via read_file). Pas de content MCP document dactylographié à la main ; la spec.md durable de spec-lite reste locale uniquement. Le mode libre-forme conserve son chemin de sauvegarde de brouillon normal. Les résultats vides/partiels préservent les inconnues et poursuivent la préparation. La recherche ne soumet, n'approuve ni ne contourne les restrictions de révision ; les proposals en attente/approuvées conservent leurs portails de révision existants. Une instruction Tracker de recherche seule retourne par l'itinéraire Idea au lieu d'entrer ce workflow de rédaction.

Étape 1 : Créer une Proposal vide

Résolvez le mode de spec (Étape 1.5) AVANT cette création. En modes OpenSpec et spec-lite, la description du conteneur DOIT porter une ligne de localisateur (OpenSpec change slug: <slug> ou Spec-lite: .chorus/specs/<slug>/<YYYY-MM-DD>-<change-slug>/), et description ne peut être défini qu'à la création — décidez du mode + slug/chemin daté d'abord et incluez cette ligne dans cet appel unique. NE créez PAS un conteneur nu et ne réalisez ensuite que vous en aviez besoin. Le mode libre-forme omet toute ligne de localisateur.

Approche recommandée : Créez d'abord le conteneur de proposal (avec la ligne de localisateur du mode dans description le cas échéant), puis ajoutez progressivement les brouillons de documents et de tâches un par un.

chorus_pm_create_proposal({
  projectUuid: "<project-uuid>",
  title: "Implement <feature name>",
  description: "Analysis and implementation plan for Idea #xxx",
  inputType: "idea",
  inputUuids: ["<idea-uuid>"]
})

Idées multiples : Vous pouvez combiner plusieurs ideas en une seule proposal en passant plusieurs UUIDs dans inputUuids.

Un thème ne peut pas être une entrée de proposal — chorus_pm_create_proposal rejette toute idea d'entrée avec isContainer = true. Dérivez une idea enfant du thème et écrivez la proposal sur l'enfant à la place. (Voir la section theme-ideas du skill idea, skill_view("chorus:idea").)

Étape 1.5 : Sélectionner le mode de spec

Le mode de spec est déjà calculé pour vous par le plugin Chorus Hermes — ne le re-dérivez PAS. Son vérification pre_llm_call (premier tour de chaque session, et à nouveau après /reset ou compression du contexte) résout le mode avec spec_mode.py du plugin (l'explicite CHORUS_SPEC_MODE l'emporte ; sinon openspec quand un répertoire openspec/ et la CLI openspec sont tous deux présents dans le répertoire de travail ; sinon lite) et l'injecte comme la section ## Spec Mode de votre contexte : il indique CHORUS_SPEC_MODE=<lite|openspec|off> + une note de routage. (Pas de ## Spec Mode dans le contexte, p. ex. vous êtes un enfant delegate_task ? Voir openspec-aware §1 fallback manuel via skill_view("chorus:openspec-aware") — ne roll jamais la règle à la main.) Agissez sur cette valeur :

  • Si la section dit que le mode ne peut pas être honoré (CHORUS_SPEC_MODE=openspec explicite mais OpenSpec inutilisable — raison de conflit de config ou indice d'installation), arrêtez et surfacez-le ; ne faites pas de fallback.

  • Sinon branchez sur le mode résolu :

  • resolved = spec-lite → charger le skill spec-lite (skill_view("chorus:spec-lite")) et le suivre : choisissez $SLUG (une capacité, pas un seul changement). Assurez-vous que le .chorus/specs/<slug>/spec.md durable existe (local uniquement, pas d'ids Chorus ; utilisez le template spec-durable inline du skill spec-lite) et mettez-le à jour en place. Créez le dossier daté de ce changement .chorus/specs/<slug>/<YYYY-MM-DD>-<change-slug>/ avec ses docs Chorus-typés synchronisés (prd.md principal, optionnel tech_design.md… ; utilisez le template de dossier daté inline du skill spec-lite). Mettez la ligne de localisateur littérale Spec-lite: .chorus/specs/<slug>/<YYYY-MM-DD>-<change-slug>/ dans la Step 1 create description, puis miroir chaque <type>.md du dossier daté vers son Document persistant (chorus_pm_add_document_draft --arg-file la première fois, chorus_pm_update_document --arg-file après) via chorus mcp call … --arg-file content=.chorus/specs/<slug>/<YYYY-MM-DD>-<change-slug>/<type>.md (exécutez via terminal ; voir skill_view("chorus:chorus-cli")). spec.md n'est jamais miroir. Sautez l'Étape 2 ci-dessous. (Tâches via chorus_pm_add_task_draft ; pas de tasks.md.)

  • resolved = OpenSpec (la section ## Spec Mode affiche CHORUS_OPENSPEC_ACTIVE=1 — c.-à-d. CHORUS_SPEC_MODE=openspec ou non défini, avec OpenSpec utilisable) → suivez le skill openspec-aware §3 (skill_view("chorus:openspec-aware")). Choisissez $SLUG, scaffoldez openspec/changes/<slug>/, écrivez proposal.md / design.md / specs/<capability>/spec.md localement, puis mettez la ligne littérale OpenSpec change slug: <slug> dans la Step 1 create description, et miroir chaque fichier local dans un brouillon de document.

    ⛔ Obligatoire en mode OpenSpec : les appels de miroir remplissent content à partir du fichier local — préférez chorus mcp call … --arg-file content=<fichier> exécutée via terminal ; quand chorus n'est pas sur PATH, retombez sur l'appel de l'outil MCP natif (mcp__chorus__chorus_pm_add_document_draft / mcp__chorus__chorus_pm_update_document_draft) avec content défini aux octets exacts du fichier retournés par read_file — voir openspec-aware §3.6. Ne appelez pas chorus_pm_add_document_draft avec un champ content dactylographié à la main ou paraphrasé. Re-taper des milliers de lignes brûle 20 000+ tokens de contenu par proposal et brise l'égalité d'octets (openspec-aware §2 Règle 1). Sautez l'Étape 2 en mode OpenSpec — le flux de remplissage de fichier la remplace pour les documents.

  • resolved = free-form (CHORUS_SPEC_MODE=off explicite) → procédez avec l'Étape 2 inchangée. Écrivez les brouillons inline comme Markdown libre via MCP chorus_pm_add_document_draft direct.

Étape 2 : Ajouter des brouillons de documents

Ajoutez les brouillons de documents un à la fois :

# Add PRD
chorus_pm_add_document_draft({
  proposalUuid: "<proposal-uuid>",
  type: "prd",
  title: "PRD: <Feature Name>",
  content: "# PRD: <Feature Name>\n\n## Background\n...\n## Requirements\n..."
})

# Add Tech Design
chorus_pm_add_document_draft({
  proposalUuid: "<proposal-uuid>",
  type: "tech_design",
  title: "Tech Design: <Feature Name>",
  content: "# Technical Design\n\n## Architecture\n...\n## Implementation\n..."
})

Types de documents : prd, tech_design, adr, spec, guide

Étape 3 : Ajouter des brouillons de tâches

Ajoutez les brouillons de tâches un à la fois. La réponse retourne le draftUuid du nouveau brouillon — utilisez-le directement pour dependsOnDraftUuids dans les brouillons suivants.

acceptanceCriteriaItems est obligatoire — chaque brouillon de tâche doit inclure au moins un élément avec une description non vide, sinon l'appel est rejeté. Utilisez le tableau acceptanceCriteriaItems structuré (la chaîne Markdown acceptanceCriteria héritée ne satisfait pas l'exigence).

# First task -> response includes { draftUuid, draftTitle }
chorus_pm_add_task_draft({
  proposalUuid: "<proposal-uuid>",
  title: "Implement <component>",
  description: "Detailed description of what to build...",
  priority: "high",
  storyPoints: 3,
  acceptanceCriteriaItems: [
    { description: "Criteria 1", required: true },
    { description: "Criteria 2", required: true }
  ]
})

# Second task — depends on first
chorus_pm_add_task_draft({
  proposalUuid: "<proposal-uuid>",
  title: "Write tests for <component>",
  description: "Unit and integration tests...",
  priority: "medium",
  storyPoints: 2,
  acceptanceCriteriaItems: [
    { description: "Test coverage > 80%", required: true }
  ],
  dependsOnDraftUuids: ["<draftUuid-from-first-task>"]
})

Pour éditer les critères d'un brouillon plus tard via chorus_pm_update_task_draft, passez un acceptanceCriteriaItems non vide pour les remplacer ; omettez le champ pour les laisser inchangés. Le champ ne peut pas être utilisé pour effacer les critères.

Priorité de tâche : low, medium, high

Étape 4 : Réviser et affiner les brouillons

# Review current state. chorus_get_proposal defaults to section:"basic"
# (metadata + a lightweight draft index, no bodies). Use section:"full" to
# see every draft's content, or section:"documents"/"tasks" for one kind.
chorus_get_proposal({ proposalUuid: "<proposal-uuid>", section: "full" })

# Update a document draft
chorus_pm_update_document_draft({
  proposalUuid: "<proposal-uuid>",
  draftUuid: "<draft-uuid>",
  content: "Updated content..."
})

# Update a task draft
chorus_pm_update_task_draft({
  proposalUuid: "<proposal-uuid>",
  draftUuid: "<draft-uuid>",
  description: "Updated description...",
  dependsOnDraftUuids: ["<other-draft-uuid>"]
})

# Remove a draft
chorus_pm_remove_task_draft({
  proposalUuid: "<proposal-uuid>",
  draftUuid: "<draft-uuid>"
})

Étape 5 : Valider et soumettre

Avant de soumettre, validez pour prévisualiser les problèmes :

chorus_pm_validate_proposal({ proposalUuid: "<proposal-uuid>" })

Retourne { valid, issues } avec niveaux erreur, avertissement et info. Corrigez les erreurs avant de soumettre.

Quand la validation réussit :

chorus_pm_submit_proposal({ proposalUuid: "<proposal-uuid>" })

Cela change le statut de draft à pending. Un Admin l'examinera (voir skill_view("chorus:review")).

Ajoutez un commentaire expliquant votre raisonnement :

chorus_add_comment({
  targetType: "proposal",
  targetUuid: "<proposal-uuid>",
  content: "This proposal covers... Key decisions: ..."
})

Étape 5.5 : Exécuter le Proposal Reviewer

Le hook transform_tool_result du plugin Chorus Hermes ajoute un rappel au résultat de chorus_pm_submit_proposal : exécutez le chorus-proposal-reviewer indépendant et en lecture seule avant approbation admin. Exécutez-le comme un enfant delegate_task :

delegate_task(
  goal="[chorus-reviewer:proposal] Review Chorus proposal <proposal-uuid> and post one VERDICT comment.",
  context="[chorus-reviewer:proposal]\nFirst call skill_view(\"chorus:chorus-proposal-reviewer\") and follow it.\nProposal UUID: <proposal-uuid>\nProject UUID: <project-uuid>\nMax review rounds: 3\nFirst read existing comments to determine the round number; post VERDICT as a comment.\nRepo: <abs path>"
)
  • Le marqueur [chorus-reviewer:proposal] DOIT être la première ligne du context (gardez-le dans goal aussi). Le plugin l'utilise pour exécuter l'enfant sous la garde du reviewer en lecture seule : les outils Chorus d'écriture autres que chorus_add_comment sont bloqués, tout comme write_file, patch, terminal, execute_code et delegate_task.
  • L'enfant démarre avec un contexte isolé et ne sait rien de cette conversation. Mettez tout ce dont il a besoin (UUIDs proposal/project, limite de tours, chemin repo, chemins de fichiers spec locaux qu'il devrait read_file) dans context.
  • delegate_task se bloque jusqu'à ce que le reviewer termine et retourne son résumé ; rien n'a besoin d'être suivi ou fermé.

Après son retour, lisez les commentaires avec chorus_get_comments({ targetType: "proposal", targetUuid: "<proposal-uuid>" }) et trouvez la ligne VERDICT: de CE tour — le commentaire posté après que vous ayez envoyé le reviewer, pas un ancien tour :

  • VERDICT: PASS — Aucun problème. Procédez à chorus_admin_approve_proposal (si vous avez proposal:admin et l'humain vous a délégué l'approbation ; sinon laissez-le pour l'Admin).
  • VERDICT: PASS WITH NOTES — Notes mineures. Approuvez toujours.
  • VERDICT: FAIL — BLOCKERs trouvés. N'approuvez PAS. Rejetez avec chorus_pm_reject_proposal, corrigez, resoumettez (Étape 6) et exécutez à nouveau le reviewer — jusqu'à la limite de 3 tours.

Étape 6 : Gérer les retours

Après submission, le chorus-proposal-reviewer (Étape 5.5) poste un commentaire VERDICT. Si le VERDICT est FAIL, ou un Admin rejette la proposal, vous devez réviser et resoummettre.

IMPORTANT : Une proposal en statut pending ne peut pas être éditée. Vous devez la rejeter d'abord pour la retourner au statut draft avant d'éditer des brouillons.

  1. Lisez les retours :

    chorus_get_proposal({ proposalUuid: "<proposal-uuid>", section: "full" })
    chorus_get_comments({ targetType: "proposal", targetUuid: "<proposal-uuid>" })

    Identifiez les BLOCKERs du VERDICT reviewer ou de la note de rejet.

  2. Rejetez la proposal (auto-rejet de la vôtre, ou demandez à l'admin de rejeter celle de quelqu'un d'autre) :

    chorus_pm_reject_proposal({
      proposalUuid: "<proposal-uuid>",
      reviewNote: "Reviewer FAIL. Fixing BLOCKERs: <list>"
    })

    Cela retourne la proposal au statut draft. Les agents PM ne peuvent rejeter que leurs propres proposals ; les agents admin peuvent rejeter toute proposal.

  3. Révisez les brouillons :

    chorus_pm_update_document_draft({ proposalUuid: "<proposal-uuid>", draftUuid: "<uuid>", content: "..." })
    chorus_pm_update_task_draft({ proposalUuid: "<proposal-uuid>", draftUuid: "<uuid>", ... })
  4. Resoumettez :

    chorus_pm_submit_proposal({ proposalUuid: "<proposal-uuid>" })

    Puis exécutez à nouveau le reviewer (Étape 5.5) pour le prochain tour.

Étape 7 : Post-approbation

Quand l'Admin approuve :

  • Les brouillons de documents deviennent de vrais Documents
  • Les brouillons de tâches deviennent de vraies Tâches (statut : open, prêtes pour les développeurs)
  • Le statut affiché de l'Idea est automatiquement dérivé de la progression de la Proposal et des Tâches — aucune mise à jour manuelle nécessaire

Étape 8 : Gérer les dépendances de tâches (Optionnel)

Après création des tâches, vous pouvez gérer les dépendances :

Créer les tâches en batch avec dépendances intra-batch :

chorus_create_tasks({
  projectUuid: "<project-uuid>",
  tasks: [
    { draftUuid: "draft-db", title: "Create database schema", priority: "high", storyPoints: 2 },
    { draftUuid: "draft-api", title: "Implement API endpoints", priority: "high", storyPoints: 4, dependsOnDraftUuids: ["draft-db"] },
    { title: "Write integration tests", priority: "medium", storyPoints: 2, dependsOnDraftUuids: ["draft-api"] }
  ]
})

Ajouter/retirer les dépendances sur les tâches existantes :

chorus_update_task({ taskUuid: "<task-B-uuid>", addDependsOn: ["<task-A-uuid>"] })
chorus_update_task({ taskUuid: "<task-B-uuid>", removeDependsOn: ["<task-A-uuid>"] })

Les dépendances sont validées : même projet, pas d'autodépendance, pas de cycles (détection DFS).

Étape 9 : Assigner les tâches aux agents développeurs (Optionnel)

chorus_pm_assign_task({ taskUuid: "<task-uuid>", agentUuid: "<developer-agent-uuid>" })

# Optional: pin the task to a specific (agent, host, cwd) AgentInstance
chorus_pm_assign_task({ taskUuid: "<task-uuid>", agentUuid: "<developer-agent-uuid>", instanceUuid: "<agent-instance-uuid>" })
  • La tâche doit être open ou assigned
  • L'agent cible doit avoir la permission task: ["write"]
  • Passez instanceUuid pour épingler la tâche à une instance spécifique en ligne (assigne comme agent_instance) ; omettez-le pour une assignation agent plain qui hérite l'instance épinglée de l'idea racine au moment du wake

Directives de rédaction de documents

Structure PRD

# PRD: <Feature Name>

## Background
Why this feature is needed.

## Requirements
### Functional Requirements
- FR-1: ...

### Non-Functional Requirements
- NFR-1: ...

## User Stories
- As a <role>, I want <action>, so that <benefit>

## Out of Scope
What is NOT included.

Structure Tech Design

# Technical Design: <Feature Name>

## Overview
High-level approach.

## Architecture
System design, component interactions.

## Data Model
Schema changes, new tables.

## API Design
New/modified endpoints.

## Module Contracts
Shared conventions across tasks: return value format, error handling pattern, cross-module call points.

## Implementation Plan
Step-by-step implementation order.

## Risks & Mitigations
Potential issues and how to address them.

Directives de rédaction de tâches

Les bonnes tâches sont :

  • Module-scoped — Un module fonctionnel cohésif par tâche, pas une fonction ou fichier unique
  • Testable — Des critères d'acceptation clairs et cohésifs sont obligatoires sur chaque tâche (au moins un élément non vide ; max 6 ; groupez les vérifications connexes en un critère mais listez la couverture clé, p. ex. « Tous les tests réussissent : tests unitaires de la couche service, tests d'intégration API, gestion des cas limites »)
  • Dimensionnée — 1-8 story points (heures de travail de l'agent)
  • Ordonnée — Utilisez dependsOnDraftUuids / dependsOnTaskUuids pour exprimer l'ordre d'exécution
  • Descriptive — Incluez suffisamment de contexte pour qu'un agent développeur puisse démarrer sans questions. Pour les tâches avec dépendances inter-modules, référencez les Module Contracts du tech design dans l'AC
  • Points de contrôle d'intégration — Pour les DAGs avec 4+ tâches, incluez au moins une tâche de point de contrôle d'intégration à un point de convergence dont l'AC exige l'exécution bout à bout des modules précédents ensemble
  • Hallucination-aware — Quand les tâches impliquent des dépendances externes, notez dans la description de tâche que les développeurs doivent vérifier les spécifiques (signatures d'API, flags CLI, clés de config, IDs de modèle, etc.) par rapport aux docs officielles plutôt que de se fier à la mémoire LLM

Granularité de tâche

Chaque tâche doit correspondre à un module fonctionnel indépendamment exécutable et testable — pas une fonction, fichier ou endpoint API unique. Évitez de scinder les fonctionnalités étroitement liées en tâches séparées ; la surcharge du workflow Chorus par tâche (claim → implement → self-test → submit → verify) s'accumule rapidement.

Mauvais → Bons exemples :

  • Mauvais : Book Search + Book CRUD (2 tâches) → Bon : Book Management (1 tâche couvrant CRUD + Search pour la même entité)
  • Mauvais : Chart Rendering + Statistics Calculation (2 tâches) → Bon : Data Analytics (1 tâche couvrant stats + visualisation comme un module)

Conseils

  • Gardez le PRD focalisé sur quoi et pourquoi ; tech design focalisé sur comment
  • Divisez les grandes fonctionnalités en tâches module-scoped cohésives — mais évitez de sur-diviser les fonctionnalités connexes en trop de minuscules tâches
  • Ajoutez storyPoints pour aider à prioriser et estimer l'effort
  • Gardez les critères d'acceptation cohésifs — groupez les vérifications connexes en un élément plutôt que de lister chaque vérification séparément
  • Configurez toujours le DAG de dépendance de tâche — les tâches sans dépendances sont supposées parallélisables
  • Quand plusieurs tâches partagent des formats de données ou s'appellent mutuellement, définissez les contrats dans le tech design avant d'écrire l'AC des tâches
  • Quand vous combinez plusieurs ideas, expliquez comment elles se rapportent dans la description de la proposal

Suivant

  • Après submission, un Admin examinera en utilisant le skill review (skill_view("chorus:review"))
  • Après approbation, les Développeurs réclament les tâches en utilisant le skill develop (skill_view("chorus:develop"))
  • Pour l'élaboration d'Idea, voir skill_view("chorus:idea")
  • Pour la vue d'ensemble de la plateforme, voir skill_view("chorus:chorus")

Skills similaires