Raccourcis clavier

Appuyez sur ← ou → pour passer d’un chapitre à l’autre

Appuyez sur S ou / pour rechercher dans la documentation

Appuyez sur ? pour afficher cette aide

Appuyez sur Échap pour la masquer

Sortie JSON

Toute commande qui agit sur un projet accepte --json. La sortie constitue un contrat public et versionné — la version 1 — sur lequel s’appuient les skills, et que vous pouvez utiliser dans vos scripts et votre CI.

Garanties

  • Un seul document. La sortie standard contient exactement un document JSON, indenté, y compris lorsque la commande échoue. Rien d’autre n’est écrit sur la sortie standard.
  • Un tableau status. Chaque document comporte un tableau status, vide lorsque tout s’est bien passé, et qui liste sinon les avertissements et les erreurs.
  • La même forme en cas d’échec. Une commande en échec renvoie la forme de sa sortie nominale, avec des champs vides ou null, plus l’erreur dans status. Un consommateur analyse les deux cas avec le même code.
  • Des noms stables. Les noms de champs sont en camelCase. Les codes sont stables et faits pour être testés ; les messages sont faits pour être lus et peuvent être reformulés.
  • Des chemins portables. Tous les chemins, absolus ou relatifs, utilisent le séparateur / sur tous les systèmes — sous Windows, C:/work/acme-app. Les chemins figurant dans les constats sont relatifs à la racine du projet.
  • Une évolution par ajout. Au sein de la version 1, des champs peuvent être ajoutés, jamais renommés ni supprimés. Certains champs facultatifs sont omis lorsqu’ils sont vides, comme indiqué ci-dessous.

Le code de sortie suit les mêmes règles qu’en mode lisible : 0 en cas de succès, 1 en cas d’échec et, pour codev validate, 1 en présence d’erreurs (ou de tout constat avec --strict).

Le tableau status

{
  "status": [
    {
      "level": "error",
      "code": "ambiguous_change",
      "message": "several active changes: add-audit-log, rework — specify which one"
    }
  ]
}
ChampValeurs
levelerror ou warning
codeUn identifiant stable, comme no_codev_root
messageTexte lisible par un humain

Codes d’erreur courants :

CodeSignification
no_codev_rootAucun _codev/ dans le répertoire courant ni dans ses parents
no_active_changeLe projet n’a aucun change actif
ambiguous_changePlusieurs changes actifs et aucun --change
unknown_changeLe change désigné n’existe pas
invalid_change_idUn nom de change qui n’est pas en kebab-case, ou le nom réservé archive ; le message nomme la règle enfreinte
change_existsnew change avec un nom déjà pris
schema_not_foundNom de schéma inconnu
schema_invalid, schema_unreadableUn fichier de schéma que codev refuse : un défaut de structure, ou un YAML invalide ou une clé inconnue
unknown_artifactinstructions avec un artefact que le schéma du change n’a pas
no_artifact_readyinstructions sans artefact, alors qu’aucun n’est prêt
template_not_foundUn schéma fait référence à un template manquant
validation_failedsync ou archive a refusé un change dont la validation signale des erreurs
review_blockedarchive a refusé un change dont le compte rendu de revue manque pour une étape relue, contient un constat de gravité haute encore ouvert ou contesté, ou vient d’un codev plus récent ; le message nomme chaque raison
invalid_review_modereview.mode, dans _codev/config.yaml ou le change.yaml d’un change, n’est ni inline ni isolated ; le message nomme le fichier et les valeurs admises
invalidUn fichier invalide, ou un delta qui ne peut pas être fusionné dans sa spec principale
unreadableUn fichier n’a pas pu être lu
write_failedUn fichier n’a pas pu être écrit

Les avertissements reprennent le code de la situation qu’ils signalent, par exemple inherit_unresolved, git_source_unlocked, unknown_workflow ou artifact_skipped.

Documents par commande

init et update

codev init --json et codev update --json :

{
  "root": "/home/you/acme-app",
  "created": ["…"],
  "updated": ["…"],
  "untouched": ["…"],
  "preserved": ["/home/you/acme-app/.claude/skills/codev-apply/SKILL.md"],
  "skills": ["codev-propose", "codev-explore", "…"],
  "integration": [
    {
      "step": "claude_md",
      "action": "appended",
      "path": "CLAUDE.md",
      "reason": null
    },
    {
      "step": "ci",
      "action": "skipped",
      "path": ".github/workflows/codev.yml",
      "reason": ".github/workflows/ci.yml already runs codev validate"
    },
    {
      "step": "pr_template",
      "action": "created",
      "path": ".github/PULL_REQUEST_TEMPLATE.md",
      "reason": null
    }
  ],
  "status": []
}

preserved liste les skills laissées en place parce qu’elles ont été modifiées à la main. integration compte une entrée par étape d’intégration au dépôt : step vaut claude_md, ci ou pr_template ; action vaut created, appended, refreshed, unchanged ou skipped ; path est relatif au projet, ou null ; reason explique une étape écartée, ou vaut null. codev update ne liste que les fichiers gérés qu’il a trouvés. L’indication codev doctor et le job GitLab n’apparaissent que dans la sortie humaine.

Avertissements propres à init : inherit_not_written (--inherit alors que config.yaml existe), inherit_pin_failed (une source git n’a pas pu être épinglée) et managed_section_malformed (marqueurs codev déséquilibrés ; le fichier reste intact). Une valeur --inherit invalide échoue avec invalid_inherit.

doctor

codev doctor --json :

{
  "root": "/home/you/acme-app",
  "checks": [
    {
      "id": "config.rules",
      "group": "configuration",
      "status": "missing",
      "code": "rules_missing",
      "message": "no rules: in _codev/config.yaml",
      "fix": "/codev-configure"
    },
    {
      "id": "config.language",
      "group": "configuration",
      "status": "ok",
      "code": "ok",
      "message": "language: is set",
      "fix": null
    },
    "…"
  ],
  "summary": {
    "total": 14,
    "missing": 2,
    "warnings": 1
  },
  "status": []
}

Chaque vérification a un id stable, son group, un status (ok, missing ou warning), un code stable (ok lorsque la vérification réussit), un message et un fix — la commande ou la skill à lancer — ou null lorsque le statut est ok. Les vérifications suivent l’ordre du tableau ci-dessous ; pr_template n’apparaît que pour un dépôt GitHub. summary.missing détermine le code de sortie de --strict.

id de la vérificationgroupCodes lorsque le statut n’est pas ok
config.rulesconfigurationrules_missing
config.languageconfigurationlanguage_missing
config.keysconfigurationunknown_config_key (avertissement)
config.rolesconfigurationroles_invalid (avertissement) ; lorsqu’il est ok, message liste les rôles actifs, les rôles actifs selon le domaine avec leurs domaines, et les rôles désactivés
skillsconfigurationskills_missing, skills_outdated, skills_review_mode
sourcesconfigurationsource_unpinned, lock_stale (avertissement)
codev_versionconfigurationcodev_version_unsatisfied, update_available (avertissement)
specsplanningno_main_spec
decisionsplanningno_accepted_decision (avertissement)
validateplanningvalidate_errors, validate_warnings (avertissement)
claude_mdrepositoryclaude_md_section_missing
cirepositoryci_validate_missing
pr_templaterepositorypr_template_section_missing
changelogrepositorychangelog_missing (avertissement), changelog_outdated (avertissement)

changelog

codev changelog --format json (le --json de cette commande) :

{
  "root": "/home/you/acme-app",
  "since": "v1.3.0",
  "until": null,
  "release": null,
  "entries": [
    {
      "category": "Added",
      "text": "`--format json` pour `codev export`.",
      "breaking": false,
      "change": "2026-10-02-export-json",
      "archivePath": "_codev/changes/archive/2026-10-02-export-json",
      "source": "release_note"
    }
  ],
  "markdown": "## [Unreleased]\n\n### Added\n\n- `--format json` pour `codev export`.\n",
  "written": null,
  "status": []
}
  • since — la référence après laquelle commence l’intervalle, explicite ou le tag par défaut ; null lorsque tous les changes archivés en font partie. until — null pour l’arbre de travail.
  • release — { "version", "date" } avec --release, sinon null.
  • entries — dans l’ordre d’affichage. text est l’élément tel qu’écrit, marqueur **BREAKING** compris. source vaut release_note, ou what_changes pour un change archivé sans note de version.
  • markdown — les éléments mis en forme au format Keep a Changelog.
  • written — avec --write, { "path", "action" }, action valant created, updated ou unchanged ; sinon null.

Avertissements dans status : release_note_missing, release_note_invalid, release_note_inconsistent, not_a_git_repository, archived_change_unreadable. Codes d’erreur : unknown_ref, not_a_git_repository (avec --since ou --until hors de git), invalid_release_version, invalid_date, invalid_argument, changelog_malformed.

new change

{
  "changeName": "add-audit-log",
  "schemaName": "spec-driven",
  "changeRoot": "/home/you/acme-app/_codev/changes/add-audit-log",
  "created": [
    "/home/you/acme-app/_codev/changes/add-audit-log/change.yaml"
  ],
  "status": []
}

list

{
  "changes": ["add-audit-log"],
  "root": "/home/you/acme-app",
  "status": []
}

Avec --specs, le tableau s’appelle specs et liste des chemins de capacités.

codev search --json :

{
  "root": "/home/you/acme-app",
  "query": "decision seal",
  "language": "en",
  "results": [
    {
      "kind": "requirement",
      "id": "decisions::Body seal recorded by the CLI",
      "capability": "decisions",
      "requirement": "Body seal recorded by the CLI",
      "excerpt": "The CLI SHALL maintain a `_codev/decisions/seal.yaml` file…"
    },
    {
      "kind": "decision",
      "id": "project/0003",
      "decision": "0003",
      "title": "The planning folder is hidden",
      "origin": "project",
      "status": "superseded",
      "inEffect": false,
      "supersededBy": "project/0009",
      "excerpt": "…"
    }
  ],
  "archived": [
    { "change": "2026-09-09-enforce-decision-immutability", "excerpt": "…" }
  ],
  "status": []
}

language est la langue dans laquelle les mots ont été réduits à leur racine. Un résultat ne porte que les champs de son type ; archived n’est présent qu’avec --archive. Dans un résultat, status est le statut de la décision, pas le tableau des erreurs de la racine.

show

codev show --json :

{
  "root": "/home/you/acme-app",
  "capability": "decisions",
  "requirement": {
    "name": "Creating a decision through the CLI",
    "text": "### Requirement: Creating a decision through the CLI\n\n…"
  },
  "status": []
}

codev show <capacité> porte requirements, les noms des exigences, et purpose au lieu de requirement. Un échec porte capability: null et son code dans status.

status

{
  "changeName": "add-audit-log",
  "schemaName": "spec-driven",
  "planningHome": "/home/you/acme-app",
  "changeRoot": "/home/you/acme-app/_codev/changes/add-audit-log",
  "applyRequires": ["tasks"],
  "isPlanningComplete": false,
  "artifacts": [
    {
      "id": "proposal",
      "outputPath": "proposal.md",
      "status": "ready",
      "requires": [],
      "missingDeps": []
    },
    {
      "id": "specs",
      "outputPath": "specs/**/*.md",
      "status": "blocked",
      "requires": ["proposal"],
      "missingDeps": ["proposal"]
    }
  ],
  "update": {
    "current": "0.5.0",
    "latest": "0.6.0",
    "url": "https://github.com/mairistem/codev/releases/tag/v0.6.0",
    "available": true,
    "snoozed": false
  },
  "versionRequirement": {
    "requirement": ">=0.5",
    "satisfied": true
  },
  "status": []
}

Le status d’un artefact vaut done, ready, blocked ou skipped. planningHome est la racine du projet ; les skills s’en servent plutôt que de supposer le répertoire courant.

update est présent lorsque la dernière release de codev est connue : current est la version en cours, latest la dernière release, url sa page, available indique si latest est plus récente, et snoozed si codev self-update --snooze l’a mise en sourdine. Il est absent lorsque la vérification est désactivée (CI, CODEV_NO_UPDATE_CHECK=1) ou n’a encore jamais réussi. versionRequirement est présent lorsque _codev/config.yaml définit codev_version : requirement est sa valeur, satisfied indique si la version en cours la respecte. Ces deux objets s’ajoutent sans rien changer : un consommateur qui les ignore lit le document comme avant.

self-update

codev self-update --json, qui implique --yes :

{
  "current": "0.5.0",
  "latest": "0.6.0",
  "url": "https://github.com/mairistem/codev/releases/tag/v0.6.0",
  "action": "updated",
  "installMethod": "standalone",
  "path": "/home/you/.local/bin/codev",
  "hint": null,
  "projectUpdated": true,
  "status": []
}

action vaut updated, up_to_date, available (avec --check), snoozed, nothing_to_snooze ou managed_elsewhere. installMethod vaut standalone, cargo, build ou package_manager ; pour les trois derniers, hint contient la commande qui met codev à jour. latest et url valent null lorsqu’ils sont inconnus. Les échecs gardent cette forme et portent leur code dans status — voir les codes.

instructions

{
  "changeName": "add-dark-mode",
  "schemaName": "spec-driven",
  "artifact": "design",
  "description": "Technical approach and decisions",
  "resolvedOutputPath": "/home/you/acme-app/_codev/changes/add-dark-mode/design.md",
  "instruction": "Write the document that explains HOW to implement the change.\n…",
  "template": "# Design: <change title>\n…",
  "language": "en",
  "context": [
    { "origin": "path:~/src/acme-standards", "text": "All services log in JSON." },
    { "origin": "project", "text": "TypeScript monorepo." }
  ],
  "rules": [
    { "origin": "project", "text": "Cite the decisions that constrain the approach." }
  ],
  "dependencies": [
    { "id": "proposal", "path": "/home/you/acme-app/_codev/changes/add-dark-mode/proposal.md", "done": true }
  ],
  "unlocks": ["tasks"],
  "decisions": [
    {
      "id": "0003",
      "qualifiedId": "project/0003",
      "title": "Use SQLite for persistence",
      "status": "accepted",
      "tags": [],
      "path": "_codev/decisions/0003-use-sqlite-for-persistence.md",
      "origin": "project"
    }
  ],
  "related": [
    {
      "capability": "decisions",
      "requirement": "Creating a decision through the CLI",
      "excerpt": "`codev decision new <title>` SHALL create a new ADR in the project…"
    }
  ],
  "skipped": false,
  "role": {
    "id": "architect",
    "name": "Architect",
    "kind": "artifact",
    "at": "plan.write",
    "steps": ["plan.write"],
    "artifact": "design",
    "domains": [],
    "question": "How will it be built?",
    "when": "always",
    "whenOrigin": "default",
    "activatedBy": "always",
    "disableable": false,
    "knowledge": null,
    "doneWhen": [
      { "origin": "schema:spec-driven", "text": "each decision names the alternative it rejects and why" },
      "…"
    ]
  },
  "status": []
}
ChampSignification
resolvedOutputPathOù écrire ; peut être un motif glob comme …/specs/**/*.md
instruction, templateIssus du schéma ; null lorsque le schéma n’en définit pas
languageLa langue des artefacts, en par défaut
relatedLes exigences existantes que le change touche probablement, classées par rapport au Why et au What Changes de la proposition, au plus 10, chacune avec capability, requirement et excerpt — pour les artefacts qui requièrent directement la proposition (specs, design), une fois celle-ci écrite ; un tableau vide sinon
context, rulesBlocs ordonnés de la source la plus générale jusqu’au projet, chacun avec son origin (project, path:<path> ou git:<url>)
dependenciesLes artefacts dont celui-ci dépend, avec leur chemin et leur état d’achèvement
unlocksLes artefacts qui deviennent rédigeables dès que celui-ci existe
decisionsLes décisions en vigueur — renseigné pour design, vide pour les autres artefacts
skippedtrue lorsque skip_specs désactive cet artefact : il ne doit pas être rédigé
roleLe rôle qui a la charge de l’artefact, sous la forme de codev roles ; null lorsque le schéma n’en déclare pas

Un échec conserve cette forme, avec language toujours renseigné — la langue configurée, ou en lorsque la configuration ne peut pas être lue — et les autres champs à null ou vides.

validate

{
  "root": "/home/you/acme-app",
  "items": [
    {
      "kind": "change",
      "name": "add-audit-log",
      "path": "_codev/changes/add-audit-log",
      "findings": [
        {
          "path": "_codev/changes/add-audit-log/change.yaml",
          "line": 1,
          "severity": "error",
          "code": "zero_delta_without_marker",
          "message": "no delta file under `specs/` and `skip_specs: true` is not declared; add a delta or set `skip_specs: true` in change.yaml"
        }
      ]
    }
  ],
  "hasWarnings": false,
  "status": []
}

kind vaut change, spec, decisions ou config — ce dernier seulement lorsque _codev/config.yaml contient des clés que ce codev ne connaît pas (voir Clés inconnues). Les constats sont rapportés dans items, et non dans status : status ne signale qu’un échec de la commande elle-même. Voir Codes de validation.

sync et archive

{
  "changeName": "add-dark-mode",
  "root": "/home/you/acme-app",
  "updated": [],
  "created": ["/home/you/acme-app/_codev/specs/ui/theme/spec.md"],
  "unchanged": [],
  "deleted": [],
  "movedTo": "/home/you/acme-app/_codev/changes/archive/2026-09-30-add-dark-mode",
  "status": []
}

codev sync --json renvoie le même document, sans movedTo. deleted liste les specs principales supprimées par un change qui retire une capacité.

review

{
  "changeName": "add-sessions",
  "path": "_codev/changes/add-sessions/review.md",
  "exists": true,
  "format": 1,
  "steps": [
    {
      "step": "plan.challenge",
      "recorded": true,
      "activeRoles": ["skeptic", "security"],
      "roles": [
        { "role": "skeptic", "state": "no-finding", "fallback": null, "credited": ["R-security-1"] },
        { "role": "security", "state": "findings", "fallback": null, "credited": [] }
      ],
      "mode": "isolated",
      "summarized": []
    },
    {
      "step": "code.review",
      "recorded": false,
      "activeRoles": ["newcomer", "security"],
      "roles": [],
      "mode": null,
      "summarized": []
    }
  ],
  "findings": [
    {
      "id": "R-security-1",
      "title": "Session tokens are stored in clear",
      "role": "security",
      "step": "plan.challenge",
      "line": 13,
      "severity": "high",
      "confidence": "high",
      "reported": true,
      "location": "design.md#Decision: Sessions live in the database",
      "evidence": "The session token is stored in the `sessions` table.\n",
      "recommendation": "Store a SHA-256 of the token and compare digests.",
      "status": "disputed",
      "awaiting": "human",
      "history": [
        { "status": "open", "by": "security", "note": null, "ref": null, "to": null },
        { "status": "disputed", "by": "architect", "note": "Tokens expire after 5 minutes.", "ref": null, "to": null },
        { "status": "disputed", "by": "security", "note": "Five minutes is enough to replay a stolen token.", "ref": null, "to": null }
      ],
      "raisedBy": ["security", "skeptic"]
    }
  ],
  "issues": [],
  "archive": {
    "ready": false,
    "blockers": [
      { "code": "review_step_missing", "message": "the review record has no `## code.review` section, while roles were active at it" },
      { "code": "review_unresolved", "message": "R-security-1 (Session tokens are stored in clear) is high and still disputed; fix it, or a human accepts the risk or defers it" }
    ]
  },
  "status": []
}
ChampSignification
existsfalse sans review.md ; format et findings sont alors null ou vides
steps[].activeRolesLes rôles actifs à l’étape pour le change, tels que codev roles --at <step> --change <name> les renvoie
steps[].roles[].statefindings, no-finding, disabled, empty (une section sans rien d’exploitable), ou missing (un rôle actif sans section, dans une étape consignée)
steps[].roles[].fallbackLa ligne Fallback: du rôle — pourquoi il a relu en ligne lors d’une revue isolée — ou null
steps[].roles[].creditedLes identifiants des constats d’autres rôles de l’étape dont le raised_by nomme ce rôle
steps[].modeLa ligne Mode: de l’étape, inline ou isolated, ou null lorsqu’elle n’est pas écrite
steps[].summarizedLes lignes Summarized: de l’étape, dans l’ordre du fichier
findings[].raisedByChaque rôle qui a relevé le constat, le sien en premier : son raised_by, ou son rôle seul
findings[].reportedtrue quand la confiance est high : les skills ne présentent que ceux-là
findings[].statusLe statut de la dernière entrée d’historique
findings[].awaitingQui agit ensuite : author (ouvert), reviewer (une correction à vérifier, une contestation à laquelle répondre), human (une contestation que le relecteur a maintenue), ou null
issuesLes défauts du compte rendu, sous la forme des constats de validate, avec les codes review_*
archive.blockers[].codereview_record_missing, review_step_missing, review_unresolved ou review_format_unsupported

Le code de sortie vaut 1 seulement quand issues contient une erreur. Les champs que le fichier omet ou rend invalides valent null.

roles

codev roles --at plan.challenge --change add-dark-mode --json :

{
  "changeName": "add-dark-mode",
  "schemaName": "spec-driven",
  "at": "plan.challenge",
  "language": "en",
  "stacks": { "detected": ["TypeScript", "JavaScript"], "filter": "detected" },
  "diff": {
    "available": true,
    "reason": null,
    "base": "origin/main",
    "files": 14,
    "scanned": 11,
    "skipped": { "lockfile": 1, "prose": 2 },
    "truncated": false
  },
  "suggestions": [
    {
      "domain": "user-interface",
      "state": "ticked",
      "justification": null,
      "matchCount": 6,
      "matches": [
        { "source": "accessibility", "kind": "paths", "trigger": "**/*.{html,htm,css,scss,sass,less,jsx,tsx,vue,svelte,astro}", "path": "web/src/theme.css", "line": null },
        "…"
      ]
    },
    {
      "domain": "performance",
      "state": "justified",
      "justification": "the cache is the browser's, not ours",
      "matchCount": 1,
      "matches": [
        { "source": "performance", "kind": "patterns", "trigger": "(?i)\\b(cache|caching|memoi[sz]e|lru)\\b", "path": "web/src/theme.ts", "line": 12 }
      ]
    }
  ],
  "roles": [
    {
      "id": "skeptic",
      "name": "Skeptic",
      "kind": "step",
      "at": "plan.challenge",
      "steps": ["plan.challenge"],
      "artifact": null,
      "domains": [],
      "question": "Would the plan survive a reviewer who did not write it?",
      "when": "always",
      "whenOrigin": "project",
      "activatedBy": "project",
      "disableable": true,
      "knowledge": "## Signals\n\nPlanning smells — each one is a question to raise, not a verdict.\n…",
      "doneWhen": [
        { "origin": "built-in", "text": "**Need** — does the change solve the Why? Is there a simpler solution, or one without code?" },
        "…",
        { "origin": "project", "text": "The rollback plan is stated" }
      ]
    },
    {
      "id": "accessibility",
      "name": "Accessibility",
      "kind": "step",
      "at": "plan.challenge",
      "steps": ["plan.challenge", "code.review"],
      "artifact": null,
      "domains": ["user-interface"],
      "question": "Can everyone use what this change adds, with a keyboard or assistive technology?",
      "when": "on_domain",
      "whenOrigin": "default",
      "activatedBy": "domain:user-interface",
      "disableable": true,
      "knowledge": "## Scope\n\nLook at the user interface the change adds or modifies…",
      "doneWhen": [
        { "origin": "built-in", "text": "Every interactive element is reachable and operable with the keyboard alone, in a logical focus order, with a visible focus" },
        "…"
      ]
    }
  ],
  "disabled": [{ "id": "newcomer", "name": "Newcomer", "whenOrigin": "project" }],
  "review": {
    "mode": "isolated",
    "origin": "project",
    "material": {
      "limitBytes": 163840,
      "totalBytes": 18342,
      "summarized": false,
      "files": [
        { "path": "_codev/changes/add-dark-mode/design.md", "bytes": 6120, "treatment": "full" },
        "…"
      ]
    }
  },
  "status": []
}
ChampSignification
changeNameLe change donné avec --change ; null sans lui
schemaNameLe schéma d’où viennent les rôles d’artefact
atL’étape donnée avec --at ; null liste tous les rôles, actifs ou non
stacksLes langages détectés à partir des manifestes de dépendances du projet (detected : Rust, TypeScript, JavaScript, Python, Go, Java) et le filtre (filter) appliqué à la partie By stack des connaissances : detected, none-detected (tout est conservé) ou all-stacks (--all-stacks)
diffAvec --change, le diff du change : available, reason lorsqu’il n’y en a pas, la branche par défaut base, les fichiers modifiés (files), les fichiers lus par les motifs (scanned), les fichiers écartés par catégorie (skipped : planning, vendored, lockfile, generated, binary, prose, large), et truncated lorsqu’un plafond a été atteint ; null sans --change
suggestionsAvec --change, les domaines que suggère le diff, dans l’ordre de la liste des domaines : state vaut ticked, justified (avec sa justification) ou unticked ; matchCount compte les correspondances et matches liste les cinq premières, chacune avec sa source (le rôle, ou project), son kind (paths, manifests, patterns), le trigger tel qu’écrit, le path, et la line pour un motif ; vide sans --change
roles[].nameLe nom affiché dans la language configurée, en anglais lorsque le rôle n’en a pas dans cette langue
roles[].kindstep, ou artifact avec l’identifiant de l’artefact dans artifact
roles[].atL’étape donnée avec --at, sinon la première étape du rôle ; plan.write pour tous les rôles d’artefact
roles[].stepsToutes les étapes que sert le rôle, dans l’ordre du workflow : un expert sert plan.challenge et code.review
roles[].domainsLes domaines qui activent un expert, comme ["personal-data"] ; vide pour les autres rôles
roles[].when, roles[].whenOriginalways, never ou on_domain, fixé par default, project ou change
roles[].activatedByPourquoi le rôle est actif : always, project, change, ou domain:<nom> pour un expert dont la proposal coche le domaine ; null lorsqu’il est inactif
roles[].disableablefalse pour les rôles d’artefact, l’analyst et le developer
roles[].knowledgeLes connaissances du rôle, en markdown dans les sections Scope, Signals, By stack, References et Reporting, pour un rôle actif qui en a, sa partie By stack filtrée comme l’indique stacks.filter ; null sinon
roles[].doneWhenLes critères du rôle, puis ceux du projet, chacun avec son origin : built-in, schema:<name> ou project
disabledAvec --at, les rôles de l’étape que la configuration a désactivés — leur activation, une fois appliqués les réglages du projet puis ceux du change, vaut never —, chacun avec id, name et whenOrigin (project ou change, le fichier dont le réglage l’emporte). Les skills écrivent pour eux Disabled by configuration. dans le compte rendu de revue, sans second appel. Vide sans --at ; un expert dont le domaine n’est pas coché est inactif, pas désactivé
review.mode, review.originLe mode de revue en vigueur, inline ou isolated, fixé par default, project ou change
review.materialAvec --change à plan.trace, plan.challenge ou code.review, ce que lisent les relecteurs : les fichiers de planification du change sauf change.yaml et review.md aux étapes du plan, les fichiers du diff à code.review — aucun fichier de planification, vendorisé, généré, de verrouillage ou binaire, aucun lien symbolique ; un fichier supprimé compte 0 octet. Chaque fichier a ses bytes et son treatment : full, ou summarize dès que les fichiers pris du plus petit au plus gros ne tiennent plus dans limitBytes (160 Kio). null sinon, et à code.review sans diff. Un fichier écarté parce que sa taille ne peut pas être lue ou que son nom contient un caractère de contrôle est nommé par un avertissement review_material_incomplete dans status

Avec --at, roles ne contient que les rôles actifs, éventuellement aucun : l’étape est alors sautée. Sans --change, aucune proposal n’est lue : les experts sont donc inactifs. Un échec — unknown_step, unknown_role, invalid_role_activation, role_not_disableable — conserve cette forme, avec roles, disabled et suggestions vides, stacks, diff et review à null, et language renseigné comme pour instructions ; un mode de revue invalide échoue avec invalid_review_mode. Un déclencheur du projet inutilisable est écarté, avec un avertissement invalid_trigger dans status.

schemas

{
  "schemas": [
    { "name": "spec-driven", "origin": "built-in", "flow": ["proposal", "specs", "design", "tasks"] }
  ],
  "root": "/home/you/acme-app",
  "status": []
}

origin vaut project ou built-in. Un schéma du projet inutilisable est écarté de schemas, avec un avertissement schema_unusable dans status. Un schéma du projet dont le name: diffère de son dossier est listé sous le nom de son dossier, avec un avertissement schema_name_mismatch.

decision

codev decision list --json renvoie { "root", "decisions": [...], "status" }, et codev decision show --json renvoie { "root", "decision", "content", "status" }, où content est le Markdown complet du fichier. Une décision se présente ainsi :

{
  "id": "0001",
  "qualifiedId": "project/0001",
  "title": "Use PostgreSQL for persistence",
  "status": "superseded",
  "date": "2026-09-30",
  "tags": [],
  "supersedes": [],
  "deviatesFrom": [],
  "path": "…/_codev/decisions/0001-use-postgresql-for-persistence.md",
  "origin": "project",
  "inEffect": false,
  "supersededBy": "project/0003"
}

deviatedBy est ajouté pour une décision héritée écartée par un écart local. origin vaut project, path:<path> ou git:<url>. path est relatif au projet pour une décision qui s’y trouve, absolu sinon.

Les commandes qui créent ou scellent des décisions renvoient :

CommandeChamps en plus de root et status
decision newdecision, path, bodySha256 (seulement avec --status accepted)
decision acceptdecision, path, bodySha256, superseded
decision supersedenewDecision, newPath, oldId, oldQualifiedId, oldPath
decision sealseal (id, bodySha256, sealedAt), wasNoop
decision deviatedecision, path, targetQualifiedId
decision promotedecision, path, sourceChange, designPath

bodySha256 n’est présent que si la commande a scellé la décision : decision supersede, decision deviate et decision promote créent une décision proposed et ne scellent rien. Pour decision supersede, oldId, oldQualifiedId et oldPath désignent la décision que l’acceptation de la nouvelle remplacera ; elle n’est pas modifiée. superseded liste les prédécesseurs que decision accept a passés à superseded — chacun avec son id, son qualifiedId et son path — et reste vide quand la décision ne remplace rien.

Par exemple, codev decision accept 0002 --json pour une décision créée par codev decision supersede 0001 "Use SQLite" :

{
  "root": "/home/you/acme-app",
  "decision": {
    "id": "0002",
    "qualifiedId": "project/0002",
    "title": "Use SQLite",
    "status": "accepted",
    "date": "2026-09-30",
    "tags": [],
    "supersedes": [
      "0001"
    ],
    "deviatesFrom": [],
    "path": "_codev/decisions/0002-use-sqlite.md",
    "origin": "project",
    "inEffect": true,
    "supersededBy": null
  },
  "path": "/home/you/acme-app/_codev/decisions/0002-use-sqlite.md",
  "bodySha256": "sha256:c8873b83c178dbf8434045f43a722911b9d9913ee9f13915ccda893539b788c1",
  "superseded": [
    {
      "id": "0001",
      "qualifiedId": "project/0001",
      "path": "/home/you/acme-app/_codev/decisions/0001-use-postgresql.md"
    }
  ],
  "status": []
}

Une acceptation refusée garde la même forme, avec decision et path à null, superseded vide et le code dans status : unknown_decision_id, cannot_accept_inherited, decision_not_proposed, cannot_supersede_inherited ou predecessor_not_accepted.

sources

codev sources list --json renvoie { "root", "sources": [...], "status" }, où une source se présente ainsi :

{
  "type": "git",
  "address": "git@github.com:acme/codev-standards.git",
  "state": "locked",
  "gitRef": "main",
  "sha": "12958274cbed0eb66985f57d3272c6d3134b672d",
  "resolvedPath": "/home/you/.cache/codev/content/12958274cbed0eb66985f57d3272c6d3134b672d"
}

type vaut path ou git ; state prend l’une des valeurs resolved, unreadable, unlocked, locked, needs_update. gitRef, subpath, sha et resolvedPath sont omis lorsqu’ils ne s’appliquent pas.

codev sources show --json renvoie { "source", "filesExposed", "root", "status" }. codev sources update --json renvoie { "root", "changes", "lockWritten", "status" }, où chaque modification comporte un kind (added, moved ou unchanged), url, gitRef, from (pour moved) et to.