Skip to content

Latest commit

 

History

History
292 lines (212 loc) · 27.9 KB

File metadata and controls

292 lines (212 loc) · 27.9 KB
Bernstein
Bernstein - the open-source governance layer for AI agents

"To achieve great things, two things are needed: a plan and not quite enough time." - attributed to Leonard Bernstein

la couche de gouvernance open source pour agents IA

CI PyPI GHCR Python 3.12+ License OpenSSF Scorecard CodeQL Open in Codespaces MCP Toplist Ask DeepWiki

website · docs · install · first run · glossary · limitations · name policy · sponsor

简体中文 · 繁體中文 · 日本語 · 한국어 · हिन्दी · বাংলা · Русский · Español · Português · Deutsch · Français · Italiano · Nederlands · Polski · Svenska · Suomi · Українська · Türkçe · العربية · עברית · Bahasa Indonesia · Tiếng Việt · ไทย


Statut : bêta. Maintenu par une seule personne, en développement actif. Le numéro de version compte les releases, pas la maturité — les versions mineures peuvent modifier les interfaces. Épinglez la version pour tout usage critique ; les régressions sont corrigées rapidement, signalez-les.

Bernstein est la couche de gouvernance open source pour agents IA. Il fonctionne en policy as code : vous écrivez la politique - qui a le droit de faire quoi, ce qui exige une approbation, ce qui doit être consigné - et Bernstein l'applique et produit l'enregistrement vérifiable. Un ordonnanceur déterministe - aucun modèle dans la boucle de coordination - exécute les agents en parallèle, filtre ce qu'ils produisent derrière des gates et consigne chaque étape, si bien qu'une exécution se vérifie après coup, hors ligne, à partir des seuls artefacts. Les agents CLI de code fonctionnent d'emblée (Claude Code, Codex, Gemini CLI et 40+ autres), et la même couche gouverne toute charge agentique : le livrable peut être un diff, un rapport de recherche, un dataset ou un dossier de preuves d'audit. Profil d'installation air-gap inclus. Apache-2.0.

en un coup d'œil

Quatre éléments le distinguent ; le reste n'est que détail.

  • Aucun LLM dans la boucle de coordination. L'ordonnancement est en pur Python, garantissant une reproductibilité de bout en bout. Rejouez le plan d'hier et obtenez exactement le graphe de tâches d'hier.
  • Vérifiable a posteriori. Le journal de relecture enregistre chaque exécution, et la colonne vertébrale de lignage (lineage spine) toujours active enregistre chaque étape productrice de lignage ; le journal d'audit optionnel chaîné par HMAC (BERNSTEIN_AUDIT=1) ajoute des reçus vérifiables hors ligne. Le non-déterminisme apparaît sous forme de non-concordance de hachage à l'étape exacte, plutôt que par un nouvel essai instable. Les livrables autres que le code reçoivent le même traitement : une tâche peut déclarer un contrat d'artefact (rapport, jeu de données, journal d'actions, résultat d'exploitation) et se conclut par un reçu de lignage signé plutôt que par un commit git.
  • Isolé par conception. Chaque tâche de codage obtient son propre git worktree protégé par des barrières de fusion ; les tâches en mode artefact obtiennent un répertoire de travail sous .sdd/workspaces/. Les agents ne partagent aucun espace de travail modifiable par défaut ; le seul état partagé est le backlog de tâches, réservé de manière atomique. Un contrôle plus strict du système de fichiers est optionnel via les backends de sandbox. Désactivez les worktrees et chaque tâche s'exécute dans l'espace partagé.
  • Large et local. Plus de 40 adaptateurs d'agents CLI plus un wrapper générique --prompt, état basé sur fichiers, sans dépendance SaaS, sans plan de données tiers.

La liste complète figure sur la page des capacités ; la matrice des fonctionnalités en est l'index exhaustif.

à quoi ressemble une exécution

Un seul fichier YAML déclare l'exécution : phases, rôles, dépendances et conditions sous lesquelles un nœud s'exécute. L'ordonnanceur l'exécute comme du Python pur - rien dans le fichier n'est un prompt, et aucun modèle ne décide de la suite. Ce graphe produit un dossier de preuves d'audit ; le fichier complet est dans .bernstein/workflows/audit-evidence-pack.yaml.

name: audit-evidence-pack
version: "1.0.0"

phases:
  - name: scope
    allowed_roles: [manager, architect]
  - name: collect
  - name: validate
    allowed_roles: [qa, security]
  - name: deliver
    allowed_roles: [security, manager]

nodes:
  define-control-inventory:
    phase: scope
    role: architect

  collect-audit-logs:
    phase: collect
    role: security
    depends_on: [define-control-inventory]

  # three more evidence streams collect in parallel:
  # collect-sboms-and-attestations, collect-runbooks-and-policies,
  # collect-eval-results

  assemble-pack:
    phase: validate
    role: docs
    depends_on:
      - collect-audit-logs
      - collect-sboms-and-attestations
      - collect-runbooks-and-policies
      - collect-eval-results

  mock-auditor-pass:
    phase: validate
    role: qa
    depends_on: [assemble-pack]

  remediate-findings:
    phase: collect
    role: docs
    depends_on:
      - source: mock-auditor-pass
        condition: "status == 'failed'"
    retry:
      max_attempts: 3
      until: "status == 'done'"

  sign-and-deliver:
    phase: deliver
    role: security
    depends_on:
      - source: mock-auditor-pass
        condition: "status == 'done'"
flowchart LR
    inv[define-control-inventory] --> logs[collect-audit-logs]
    inv --> sbom[collect-sboms-and-attestations]
    inv --> rb[collect-runbooks-and-policies]
    inv --> ev[collect-eval-results]
    logs --> pack[assemble-pack]
    sbom --> pack
    rb --> pack
    ev --> pack
    pack --> gate{mock-auditor-pass}
    gate -->|failed| fix["remediate-findings (retry x3)"]
    gate -->|done| sign[sign-and-deliver]
Loading

Chaque nœud est pris par un agent dont le rôle est autorisé par la phase ; les clôtures de rôle et les gates d'approbation tiennent quoi que fasse l'agent dans la tâche. Un nœud de code se termine derrière des merge gates dans son propre git worktree. Les nœuds ci-dessus se terminent autrement : un contrat d'artefact nomme le livrable (rapport, dataset, scan, journal d'actions), et le nœud se clôt sur un reçu de lineage signé plutôt qu'un commit. Même ordonnanceur, même journal, même vérification hors ligne - que le graphe livre du code, de la recherche, un changement d'ops ou un mélange des trois. Des graphes prêts à l'emploi pour le logiciel, la recherche, la doc, l'enterprise et les workflows de contribution vivent dans .bernstein/scenarios/.

installation en 30 secondes

uv tool install bernstein    # or: pipx install bernstein
bernstein init
bernstein doctor             # checks a CLI agent is installed and authenticated
bernstein -g "fix the failing test in tests/test_foo.py"

pipx, pip, brew, dnf, npm et Docker sont abordés dans le guide d'installation ; le wheelhouse air-gap dispose de son propre guide air-gap.

A real bernstein demo run: mock agents fix four seeded bugs, ending on the run's signed receipt verifying offline

L'enregistrement ci-dessus correspond à une exécution réelle et fournit sa propre preuve. La session, le reçu signé issu du journal de cette exécution et la clé publique associée résident dans docs/assets/demo-run/. Vérifiez l'exécution hors ligne :

bernstein verify receipt docs/assets/demo-run/run-receipt.json \
    --public-key docs/assets/demo-run/run-receipt.pub.pem

L'intégration continue revérifie le reçu enregistré à chaque push sur main — et démontre qu'une copie altérée échoue — afin que la preuve publiée ne devienne pas un simple fichier décoratif. scripts/record_demo.sh régénère l'enregistrement, le reçu et la clé depuis une nouvelle exécution réelle ; rien dans le terminal n'est synthétisé.

Une exécution en cours est observable depuis l'une ou l'autre des interfaces opérateur. Toutes deux lisent la même API de tâches, évitant tout décalage d'affichage. Dans bernstein live, les colonnes gauche et droite défilent indépendamment sous forme de panneaux entiers, maintenant les composants accessibles sur des terminaux courts.

A two-column terminal dashboard - agents with their live logs on the left, the task board on the right - with a full-width activity feed and a cost line underneath A browser dashboard listing sixty-two tasks with eleven running, one of them opened to its working-tree diff
bernstein live — le tableau de bord terminal bernstein gui serve — le tableau de bord navigateur

prouver une exécution

Le déterminisme est ici un élément vérifiable, non un acte de foi. Lancez une exécution avec audit activé, puis vérifiez les enregistrements :

BERNSTEIN_AUDIT=1 bernstein -g "fix the failing test in tests/test_foo.py"
bernstein replay list                 # run ids recorded on disk
bernstein replay latest --verify      # recompute the journal head, name the first divergent step
bernstein lineage verify <run_id>     # recompute the always-on lineage spine
bernstein audit verify                # HMAC chain + Merkle seal (written because audit was enabled)
bernstein audit diagnose <run_id> --signal gate --sign-key KEY
                                      # name the exact step a failure entered the run, as a signed receipt
bernstein verify run <run_id> --signing-key-path key.pem   # sign one portable run receipt
bernstein verify receipt .sdd/runs/<run_id>/run-receipt.json  # verify it offline: file only

Le journal est écrit à chaque exécution ; la colonne vertébrale de lignage est active en permanence et s'enrichit d'une entrée pour chaque étape traçable, permettant à une exécution brève de se terminer avec une structure valide et vide. bernstein audit verify n'a de chaîne à vérifier que si le lancement a utilisé BERNSTEIN_AUDIT=1, un profil de conformité ou bernstein run --audit. L'option --audit appartient à bernstein run ; avec la commande bernstein -g ci-dessus, définissez la variable d'environnement.

Un reçu d'exécution lie la tête du journal, la tête de lignage (si des entrées ont été écrites) et, en option, une plage de chaîne d'audit, sous un objet signé Ed25519 intégrant la clé publique. Un relecteur disposant de ce fichier et de la clé publique de l'opérateur peut vérifier l'intégrité des actions et chaînes sans clé HMAC ni dossier .sdd/ actif, avec un code de sortie 2 précisant la première divergence en cas d'altération. Ce reçu certifie l'état du journal qu'il intègre ; prouver que cet état constitue l'intégralité du journal final requiert en outre un scellé indépendant d'en-tête et de décompte. Sans spécifier de clé via --public-key, le contrôle valide l'intégrité interne sans certifier l'émetteur. Détails dans le guide de relecture déterministe.

La même vérifiabilité s'applique aux métriques d'évaluation. bernstein bench run <suite> --reliability k (aussi disponible sous bernstein eval --reliability k) exécute chaque tâche k fois sous coordination fixe, puis rapporte le plancher pass^k (les k tentatives doivent réussir) ainsi que le plafond pass@1. Ce résultat est scellé dans un reçu signé recalculé hors ligne par bernstein bench reliability-verify, invalidant toute valeur falsifiée. Détails : plancher de fiabilité pass^k.

comment ça marche

Chaque objectif franchit quatre étapes :

  1. Décomposer (Decompose). Le gestionnaire scinde votre objectif en tâches assorties de rôles, de fichiers assignés et de critères d'achèvement. Un appel LLM unique, puis du pur Python.
  2. Instancier (Spawn). Les agents démarrent dans des git worktrees isolés, un par tâche de code ; les tâches en mode artefact reçoivent un répertoire standard. La branche principale reste intacte.
  3. Vérifier (Verify). Le vérificateur (janitor) valide les signaux concrets : tests au vert, présence des fichiers, conformité du lint, exactitude des types.
  4. Fusionner (Merge). Les réalisations validées intègrent main. Les tâches en échec sont réessayées ou redirigées vers un autre modèle.

Pourquoi l'ordonnanceur est en pur Python et quels sont les compromis associés : pourquoi déterministe.

commandes courantes

cd your-project
bernstein init                    # creates .sdd/ workspace, bernstein.yaml + templates/
bernstein -g "Add rate limiting"  # agents spawn, work in parallel, verify, exit
bernstein live                    # watch progress in the TUI dashboard
bernstein run plan.yaml           # multi-stage plan: skip LLM planning, execute directly
bernstein stop                    # graceful shutdown with drain

L'ensemble des commandes opérateur (automatisation de PR, planifications, passerelles de discussion, démon d'autofix) est détaillé dans commandes opérateur.

bernstein workflow exécute des DAGs déclaratifs en YAML composés de nœuds agent, command et loop - avec prise en charge de la reprise pour les exécutions interrompues :

bernstein workflow run idea-to-pr -g "Add JWT auth"   # prints run_id
bernstein workflow resume <run_id>                    # picks up at the first non-completed node

L'état d'exécution enregistre un point de contrôle dans .sdd/runs/<run_id>/ à chaque nœud. La reprise valide l'empreinte du manifeste au démarrage de l'exécution, de sorte qu'une modification de spécification est refusée plutôt que d'exécuter silencieusement un manifeste différent. Consultez manifestes de workflow.

Contrôles d'hygiène du dépôt : bernstein readme-l10n verify invalide une PR dont les READMEs traduits divergent de la source anglaise (en pointant la section obsolète), bernstein readme-l10n sync réaligne les liaisons après modification anglaise. Consultez readme-l10n.

agents pris en charge

Claude Code, Codex CLI, Gemini CLI, GitHub Copilot CLI, Cursor, Aider, Goose, Muse Code, OpenAI Agents SDK, Amp, Cody, Continue, Devin Terminal, Junie, Kilo, Kiro, AWS Q Developer, Ollama, OpenCode, OpenHands, Open Interpreter, gptme, Plandex, AIChat, Letta Code, Qwen et bien d'autres. L'index des adaptateurs fournit les commandes d'installation pour 30 d'entre eux. bernstein integrations list recense les 54 intégrations actives de src/bernstein/adapters/registry.py, référence unique de résolution. 52 constituent des adaptateurs sélectionnables ; les deux autres lignes correspondent au bouchon de test mock et au profil self-hosted-endpoints. Tout autre outil doté d'une option --prompt fonctionne via le wrapper générique.

Combinez différents agents au cours d'une même session : modèles locaux économiques pour le code générique, modèles cloud plus robustes pour l'architecture. bernstein integrations list --installed indique les outils disponibles sur votre machine.

calcul bénévole

Un projet peut marquer des tickets comme ouverts aux bénévoles, et n'importe qui peut en exécuter un sur sa propre machine, sans compte ni coordinateur. Le projet déclare ce qu'une tâche a le droit de faire dans un manifeste volunteer.json - backend de bac à sable, liste réseau autorisée, plafonds de temps et de mémoire - et les limites propres au donateur ne peuvent que le restreindre, jamais l'élargir. Le reçu produit par une tâche terminée lie le résultat à la décision de confinement sous laquelle elle a tourné, si bien qu'un mainteneur peut vérifier des mois plus tard ce que le travail avait réellement le droit de toucher.

bernstein volunteer verify .
bernstein volunteer browse --budget 60

Le guide du donateur couvre l'exécution d'un worker et le budget que vous fixez, le guide du projet couvre la déclaration d'un manifeste, et le modèle de menaces indique ce que chaque frontière protège et ne protège pas. Le lanceur en une seule commande n'est pas encore livré : aujourd'hui verify, browse et hub sont les sous-commandes qui fonctionnent.

au-delà de la page d'accueil

Toutes les ressources approfondies sont réunies sur le site de documentation :

page contenu
capabilities liste exhaustive des capacités : mode serveur MCP, cartes d'agent signées, moteurs de sandbox, collecteurs d'artefacts, conformité réglementaire
who this is for cas d'usage pertinents et situations où Bernstein n'est pas adapté
workflows DAGs déclaratifs en YAML composés de nœuds agent / command / loop
web UI tableau de bord web reposant sur la même API que la TUI
cloud execution expérimental : exécution d'agents sur Cloudflare Workers avec synchronisation R2 sur votre propre compte. Le service hébergé api.bernstein.run n'est pas encore ouvert
datasources reçus de requêtes en lecture seule et pilote associant chaque résultat à l'empreinte du schéma sous-jacent
agent catalogs liaison de rôles vers des définitions d'agents personnalisées — arborescence YAML/SKILL.md générique ou structure de plugin Claude Code
security scorecard, fuzzing, durcissement
architecture fonctionnement interne du système

pourquoi ce nom ?

Bernstein rend hommage à Leonard Bernstein, chef d'orchestre et compositeur américain. Le projet orchestre un ensemble d'agents CLI comme Bernstein dirigeait le New York Philharmonic : chaque interprète entre au bon moment, la partition est déterministe et le chef répond du résultat final.

j'ai écrit bernstein après avoir constaté 400 $/mois de factures claude en exécutant trois agents de code en parallèle avec des fusions non déterministes. Apache 2.0, maintenu individuellement. Statistiques en direct : bernstein.run.

ils en parlent

Référencé dans vinta/awesome-python, présenté dans le comparatif d'Augment Code sur les orchestrateurs d'agents open source et sélectionné dans Python Weekly #742. La démarche est également documentée comme pattern d'orchestration déterministe sans LLM dans awesome-agentic-patterns.

Toutes les mentions : plus de 20 listes awesome, annuaires, newsletters et citations

La liste complète des mentions dans les listes awesome, catalogues, références antérieures et newsletters est consultable dans docs/mentions.md. Les entrées sont complétées au fil de l'eau ; corrections bienvenues par issue ou PR.

contribution, support, licence

Les contributions sont les bienvenues ; CONTRIBUTING.md présente l'installation et les règles de style. Les signalements de sécurité s'effectuent via SECURITY.md. Si Bernstein vous fait gagner du temps : GitHub Sponsors. Contact : forte@bernstein.run.

Les métadonnées de citation sont disponibles dans CITATION.cff. Licence : Apache-2.0 ; le nom du projet est protégé séparément dans TRADEMARKS.md.


Alex Chernysh · GitHub · X · bernstein.run