» answers its finding
Skip to main content

Release history and per-version changelog

This file lists the notable changes of Roomi's Grillhouse, the frame itself. A project created by grillhouse init receives its own changelog, templates/projet/CHANGELOG.md.

The format follows Keep a Changelog, and the versions follow Semantic Versioning in 0.x: a change that obliges a project to act raises the minor, a fix the patch. One version covers the frame: it is the version of packages/grillhouse/package.json, which npm publishes with the frame's plugin, which takes it when the package is packed. A version is released per lot delivered to the projects, never per commit: its section is dated here and its commit tagged v<version>, whose push publishes the package (CONTRIBUTING.md, §5). The version of package.json (1.0.0) is the one a new project starts from, not a version of the frame.

[Unreleased]​

[0.28.1] - 2026-11-01​

Added​

  • The pane shows several projects (grillhouse-erp): the session of OSC Bridge coordinates three projects (osc-bridge, synthhub, open-synth-descriptors), and /grillhouse showed only the project of the session's folder, grillhouse tableau run in its cwd. As a multi-root workspace of VS Code lists its folders and shows them together, each item prefixed by its root, /grillhouse ajouter <chemin> now adds a project to the pane and /grillhouse retirer <chemin> removes it; a path whose package.json does not declare @roomi-fields/grillhouse is refused by its name. The list lives in the session: the mod's store keeps it for the session's folder, on the machine, and the next session opened there finds it; nothing enters a repository. Each project's board is still grillhouse tableau run in its folder, side by side, and the pane fuses them, the owner's maquette (« fusionnés », 2026-11-01): one list of the tickets at a step, sorted by step, the last step first and the questions after, each line « <étape> [] — », then each project's chantiers; a footer sums up each project, its tickets in progress and waiting (osc 2▶ · SH 1▶ 3 en attente · OSD 0), and names a project whose board does not read with its fault, the others shown. The card's whole text and the switch of a chantier run bd in the ticket's project. For the fusion to read no text of the board, each ticket line of AGENTS names its step (etape: its number and title) and, stopped on a question, who must answer it (question), and the board names its ticket prefix (prefixe), the label of its lines. With the session's project alone, the pane is unchanged.

Fixed​

  • A reference red at the checks of the plan is regenerated before any red goes to the developpeur (grillhouse-du1): in BPScript (bp-mono-vbwf.320.6.5, 0.27.0, 2026-11-01), the lot added grillhouse.lit to the package.json of five packages, so their turbo.json, which the frame generates, had to change. At the checks (3.1), the guard turbo-des-paquets and a test of the project that reads the hash the turbo.json declare (declarations-des-captures.test.ts) were red; the circuit regenerated references only when the checks were green but for them, so the test went to the developpeur, who had nothing to deliver (sans-livraison), and, relaunched to write the turbo.json, met EROFS, the references being out of his rights: the ticket never reached 4.2. As Bazel builds a genrule before the tests that read it, the checks of the plan with a red of a reference, mixed with other reds or not, now regenerate it first (the gesture regeneration, 4.2); beside other reds, the checks of the plan play again on the regenerated tree, which judges the guard and the test that reads the reference, then each red that remains goes to its owner; alone, the final pass that is due follows, as before. Neither pass regenerates again a reference regenerated on the same tree, so the regeneration of the final pass stays and changes nothing after the checks'; a regeneration that changes nothing plays the checks no more, their reds standing. The skills of the testwriter and the developpeur, the instruction template and the package's architecture say it.

  • The names a component publishes to another enter the description from the plan (grillhouse-la3): in BPScript (0.27.0, 2026-11-01), three times the same day (320.14.2.10, 320.28, 320.6.5), the explorateur wrote the names a ticket publishes and their consumers in a criterion (320.14.2.10, criterion 6: « Les lignes de 020-loader, 040-checker et 130-projector … gagnent designatedRef »); the developpeur wrote those lines, and the guard consommateurs-arbitres, which reads the title and the sections « Architecture » and « Noms publiés » of the ticket and never its criteria, by design, refused the lot; the developpeur cannot write the ticket, so he stopped, the supervisor added « ## Noms publiés » by hand and relaunched, one session lost each time. As a code owner's approval covers what it reviewed, the explorateur's sheet of the plan now carries noms_publies (the provider, each consumer, its names), which the circuit writes in the section « ## Noms publiés » of the description, written again at each plan from the last sheet, an answer to the questionneur without it keeping the plan's; a lot that adds those names to the provider's « Consommateurs » lines passes the guard with no arbitrage, and a name the plan does not publish stays refused, the guard unchanged. The explorateur's skill and the template of his instruction say when to fill them.

[0.28.0] - 2026-11-01​

Added​

  • A gesture without new behaviour leaves the circuit of code (grillhouse-sos): in BPScript, since 2026-10-17, gestures without new behaviour went through the testwriter and the developpeur and cost sessions there: 320.16 (38 tools moved by mv, 117 comments), 322.11.1 (Vitest set up on 31 packages), 320.40.1 (an unused variable, 4 sessions), si61.8 (a threshold 77 → 95, 2 sessions « aucun code à livrer »), 320.21.4.3 (grillhouse.lit alone, 56 comments), 320.15 (296 TSDoc summaries); others left it by hand, with no rule (43 commits chore(cadre): version, 322.11 and 322.12 « commité à la main par le superviseur »); the lot with nothing for the developpeur, a proof without a red, played on 29 tickets, rien-a-livrer 16 times, sans-livraison 79 stops. As Google's large-scale changes (Rosie, ClangMR) let a tool make the change that a verification and a review judge, with no new test, and as Renovate, nx migrate and eslint --fix do, the explorateur's sheet of the plan now carries the sort of the ticket (sorte: mécanique with its reason and the command that makes the gesture, or comportement with its reason, inchangé when the lot changes no behaviour its tests measure), which the circuit writes in the description (« ## Sorte ») and at the ticket. A mechanical ticket skips the testwriter, the proof of the red and the developpeur (the gesture mecanique): at the new step 1.1 Geste mécanique, one session of the explorateur in the envelope of the plan (lancer.sh --fiche geste, its sheet the schema geste) plays the command in the copy, then the checks, the final pass, the review and the queue judge the lot. While no testwriter nor developpeur has worked it and no --depuis sends it to an agent, a gesture that changes nothing stops at sans-livraison, a red of the checks at controles and a RENDU at relecture-arret, questions for the supervisor; a --reprendre at 1.1 whose copy already carries a change of the plan plays no session. A proof without a red goes to the checks with no session of the developpeur, as before; under a plan « comportement inchangé », nothing has to turn red and every green of the lot is expected, so only a file of the lot that does not load refuses the proof (no testwriter relaunched for a green without its expected green), then the developpeur writes the code, a reorganisation having code, even without a red, before the checks and the review. A sort absent, out of its kinds, without its reason, or mechanical without its command is « comportement »: the whole circuit. The common charter, the skills of the explorateur, the supervisor and the reviewer, the instruction templates and the package's architecture say the rule.

  • A package is born out of the circuit, in four times: npx grillhouse paquet <chemin> (grillhouse-b32): in SyntHub (OSC Bridge, SH-13y.6, 0.27.0, 2026-11-01), no procedure created a package. The circuit refused a ticket whose title named a package absent from the disk, and declaring the language of packages/interface first turned main red: the first package of TypeScript of a project of Rust arrived without the tools of its language (the index of the interfaces and the map of the boundaries « pas à jour », knip unreadable, « Turborepo sort en null »); every package of the projects was born before the circuit or by hand. A skeleton has neither behaviour nor test, so it no longer passes by the circuit: the grill decides the package (1); the supervisor writes its row of the table of the components, with its language, and its docs/CADRE.md and docs/INTERFACE.md (2); grillhouse paquet reads the row and builds what its language asks, as the generators of Nx and cargo new --lib added to the members of the workspace (3); its code is an ordinary ticket of the circuit (4). Times 2 and 3 enter one commit after a green verification. The command refuses, named, a path no row names, a row without language and a folder that already holds its manifest (a folder with docs/ alone is accepted); it writes each absent file of the skeleton of its language, a new demand of the join (squelette: typescript under packages/<nom>, cargo inheriting [workspace.package], python with its group test), the documents from templates/paquet/, the entry of the workspace (npm workspaces, cargo members, a uv workspace), and commits nothing; then, as nx add, the tools of the language: the update's share of each declared language, npm install, the module's lock command, the binaries, and the generators of the package's language whatever files the project holds. The generator of the boundaries (grillhouse frontieres --ecrire) writes .dependency-cruiser.projet.cjs empty when the project lacks one, so that knip resolves the require of the configuration it generates.

Fixed​

  • The column of the languages reads as « Language » too (grillhouse-4v1): osc-bridge and OSD write their architecture in English (« Crate | Responsibility | Owns | Calls »), and the column 0.27.0 asked for was French alone (OSC Bridge, 2026-10-31). The header of a table of the components, and the line of an interface, read as « Langage » or « Language », the document's language naming it.

[0.27.0] - 2026-10-31​

Added​

  • The module python: uv and pytest (grillhouse-ziy): in SyntHub (SH-13y.1, 2026-10-31), the package site holds 18 tests in Python (site/pages/test_pages.py), played by the CI alone (python3 -m unittest discover), without pyproject.toml nor lock; the frame had no module for them, so the testwriter could not write them and npm test never played them (the exploration grillhouse-1zu). Romain decided (grill of grillhouse-1zu, D2 to D5, 2026-10-31) a module python on uv and pytest, as Pants's Python backend reads a pyproject.toml. scripts/langages/python/ answers the whole join, as scripts/langages/cargo/: a package is a folder that holds a pyproject.toml (PEP 621), its language declared in the architecture; the testwriter writes the files pytest collects (test_*.py, *_test.py), conftest.py and the files under tests/, and of the manifest the group test of [dependency-groups] (PEP 735) and uv.lock, the lock naming any other part; npm test plays uv run --locked --group test pytest in each package, its JUnit report (family xunit1, which names each test's file) read by the verdict; typer is python -m compileall, preparer uv sync --locked --group test, the version of Python uv's choice from requires-python and .python-version. uv writes the environment of each package under .venv/<folder> at the root (UV_PROJECT_ENVIRONMENT), pytest its cache under .pytest_cache/<folder> (cache_dir), rather than in the package's folder (site/.venv with the real uv), which a session whose plan does not write the package could not write; the envelope opens both in writing with ~/.cache/uv, and uv's Pythons (~/.local/share/uv/python) read-only; Python writes its bytecode under one __pycache__ at the root (PYTHONPYCACHEPREFIX), proper to the session. A night test is *_nuit_test.py: the day leaves it out, tests-de-nuit plays it, and a named one plays. The guard of the sizes holds in Python (grillhouse tailles-des-tests, a large test of the day refused, its debt apart from the module typescript's), and each command plays under the base of its pass, which fails on what a test leaves in its temporary directory (tempfile, never mkdtemp by hand), the lock files uv takes there apart (uv-<hash>.lock, measured with uv 0.10.4 by the night test). npx grillhouse maj installs uv at its exact version, 0.10.4, by Astral's installer (curl -LsSf https://astral.sh/uv/<version>/install.sh | sh, under UV_NO_MODIFY_PATH, the profiles of the shell left as they are), and gives a project its test scripts (templates/python/). As the module cargo, it generates the index of the interfaces (grillhouse index-interfaces, its check a guard, --publie printing nothing), so that in a project of Python alone the launcher, which reads index-interfaces --publie before every session, does not stop on « sous-commande inconnue »; in a project of several languages the core's index takes its place. A manifest is never a test file, under tests/ neither. The suite of conformity holds the module (scripts/langages/python/exemples.mjs). The guard of the languages now also refuses a row that names a folder of the project no module finds, without the manifest of its language, so that SyntHub's site declared python without its pyproject.toml is named rather than silently left untested. The tests play against a fake uv; the real one at night (python.nuit.test.ts).

Changed​

  • A project declares several languages, a package has one (grillhouse-akd): SyntHub (SH-13y.1) holds Rust, Python and the JavaScript of a browser, and the core refused any project that declared two languages (R5 of packages/grillhouse/docs/CADRE.md, langageDe in scripts/langages.mjs, read by 15 files of the core). Romain lifted the rule (grill of grillhouse-1zu, D1 and D1 bis, 2026-10-31): as Bazel and Nx run one list of targets, one tool per language, each target of one language alone, the core now composes the modules a project declares (scripts/composition-des-langages.mjs). Each file goes to the module of the component that holds it, a file out of every component to the first module that judges it, as with one language; a folder two modules claim is refused, named with both languages. npm test -- <chemins>, npm run verifier, the circuit, the queue and the night play each command in each module that describes it, with its own tool, each path given to the module of its component (scripts/commandes-composees.mjs); the verdicts join, a red of one module makes the whole red, and the last green is kept once, after every module played green, so that a language played second never measures itself against the first one's green. The role lock, the envelope and npx grillhouse maj take the union of what the modules ask: the lock files, the outputs, the rules of the roles, the tools, the binaries, the generators and the directories to ignore. The index of the interfaces, which each module wrote whole into the same docs/agents/index-des-interfaces.md (two checks that contradict each other), is one generated file of the core for several languages (scripts/index-interfaces.mjs): each module gives the entries of its interfaces (entreesDeLIndex), assembled in the order of their paths, the root's once, under one command and one guard. npm run verifier -- --gardes, which the reviewer plays, played the tests of the module cargo, which ignored the option: it now plays the project's grillhouse:gardes then gardes, without its tests nor cargo deny, the verdict of the module typescript's. A language several packages carry is one language of the project (grillhouse-ca7: the languages are the column « Langage » of the architecture). One language declared works as before: its module is the composition. R5 becomes « a project has several languages, a package one ».
  • The language of each package is declared in the architecture (grillhouse-ca7): the core read the languages of a project in grillhouse.langages of its package.json, which init and maj filled from what the modules found in the repository (a tsconfig.json, a Cargo.toml at the root). Once a project has several languages (grillhouse-akd), that list says nothing of which package is of which language, and a recognition by the files cannot know that SyntHub's site/ is a Python generator beside a package of JavaScript for the browser. Romain decided (grill of grillhouse-1zu, D2 and D8, 2026-10-31): « ça doit être spécifié au design et donc fixé dans l'architecture et les interfaces, pas besoin de reconnaissance technique ». As the BUILD file of Bazel names the rule of each target, the table of the components of docs/ARCHITECTURE.md now carries a column « Langage », one row per package, and the core reads the languages of the project there and there alone (scripts/tableau-des-composants.mjs, langagesDeclares); the INTERFACE.md of each package repeats it (**Langage** : <nom>). A new guard, the first of the frame's (grillhouse langages-des-paquets), looks for the packages with the module of every language of the frame, not of the declared ones alone, and reads each manifest to refuse a gap, never to declare; it refuses, each named with its package: a package of a module (its manifest, the module's new manifeste: a package.json, a Cargo.toml) that no row names, a crate in a project whose table names typescript alone among them; a package a row declares of a language whose module does not find it there, named with the manifest it holds, or without the manifest of its language; an INTERFACE.md that names another language. The tables are read as the projects wrote them: every table whose header holds the column counts, each row naming its package in the first column of its table that names one (BPScript's phase comes before its package), a row without language naming no package of the project (SyntHub's crates of other repositories). grillhouse.langages disappears, with langagesTrouves and the modules' trouve and signe: nothing is guessed from the files, and a project that declares no language is refused, the column named. npx grillhouse maj brings the former declaration into the column before every other step (the migration of 0.27.0): it adds the column to the table where a row names a package, and writes the packages no table names in a section « Les paquets », a table Paquet | Langage, rather than in a table whose rows each do a step (BPScript's stages), then removes the key; the session start names npx grillhouse maj for a project that still holds the key, the grill for one that declares nothing. The template of a project carries its docs/ARCHITECTURE.md, its table declaring typescript; the session start keeps a document that holds a field <…> of its template among « Pas encore renseignés ». The grill (branch 8), the writer's reference and the common charter say it; Grillhouse declares its three packages in its own docs/ARCHITECTURE.md.

Fixed​

  • A generated file a project declares is written again at the integration, not merged (grillhouse-8o9): in OSC Bridge (2026-10-31), the generated files of a project conflicted at the integration as soon as two tickets touched their sources side by side, four times in one day: in synthhub, SH-cgi.7 twice then SH-a3x.4, on docs/SUPPORTED_DEVICES.md and docs/devices.json (written by scripts/regen_supported_devices.py and scripts/build_device_index.py, « U docs/devices.json »); in open-synth-descriptors, OSD-b91.2.12, on schemas/SHA256SUMS. Each time the copy was moved onto main by hand, the files regenerated, and the circuit relaunched --depuis developpeur. The integration already wrote again the generated files of the frame, which the module of the language names; a project could not declare its own. As npm writes package-lock.json again after a merge and a genrule of Bazel its output on the merged tree, a project now declares them under grillhouse.engendres of its root package.json, { "<name>": { "commande", "fichiers", "lit" } }, read from the main tree beside the module's generated files, in their form (scripts/engendres.mjs); a key without a command, without files, or with a pattern out of the repository is refused by its name before any work (the circuit stops at « lancement », the integration, the queue and the launcher refuse), as grillhouse.outils. The integration, the queue that replaces a branch on main, and the move of a copy onto main (and the lot of a branch sent back) no longer merge them: a lot that touches one of their files, or one they read, takes main's version, then the declared command runs out of the envelope, with the project's tools, on the lot applied, and what it writes enters the lot; the final pass (4.2) regenerates them only when a red of a pass lies in their files. A command that fails stops, its command, its code and its output named. The integration now also regenerates a reference of the frame written in full when the lot touches what it reads, not only its own files: the index of the interfaces is written again as soon as an INTERFACE.md changes. On Romain's framing (« les agents et le framework sont faits pour développer le produit, pas ajouter de la data »), the common charter now says that a ticket that only adds data (files a schema validates) goes through the project's data path, its validation and its CI, not through the code circuit, as Homebrew, DefinitelyTyped and caniuse do, and the supervisor's skill that he launches no circuit for it; and that a generated file is built rather than committed, a file a reader cannot build (a page read on GitHub, a published checksum) declared with its command and regenerated by the integration. couvertPar moves from the integration to scripts/engendres.mjs, with the regeneration the integration, the queue and the launcher share.
  • sccache starts in an agent's envelope, and the update installs it without a step by hand (grillhouse-qmk): in OSC Bridge (OB-p58, 0.26.0, 2026-10-31), every build of cargo stopped on « sccache: error: path must be shorter than SUN_LEN » (target/grillhouse/osc-bridge-build.log), and the circuit with it. The socket of the server was right (\x00grillhouse-sccache-…, abstract, read as it is by parse_uds, and the envelope passes it intact); sccache 0.19.0 starts its server by binding a second socket, of a path, under TMPDIR (<TMPDIR>/sccacheXXXXXX/sock, run_server_process in src/commands.rs), and in the envelope TMPDIR is the session's working directory, under which the pass of tests opens its base: 124 bytes for OB-p58, past the 108 of a socket's path. Replayed in a real envelope, the build of 0.26.0 fails so and the fix's passes. Every command of the module cargo that compiles (tests, verification, typing, clippy) now starts the copy's server itself, sccache --start-server under /tmp (the machine's, or in an envelope the session's, empty), before each run of cargo that compiles; cargo finds it running and keeps the pass's temporary directory. npx grillhouse maj installed sccache only once cargo-binstall was there (cargo install cargo-binstall by hand): a cargo without the subcommand binstall (cargo --list) first receives cargo-binstall 1.26.2 from cargo (cargo install --locked cargo-binstall@1.26.2, the installation its README gives), and a failure names that command. maj left the project at 0.25.5 under ^0.25.5: by design, the update brings the project to the version installed, and npm reads ^0.25.5 as >=0.25.5 <0.26.0, so npm install never reaches the next minor of a 0.x; the first line of the report now names the version installed and the command that installs another first, npm install -D @roomi-fields/grillhouse@<version>.

[0.26.0] - 2026-10-31​

Added​

  • The tools of the project enter the envelope (grillhouse-4id): in SyntHub (SH-cgi.8, 2026-10-30), the tests of the pages need a Python with the site's packages, given by SYNTHHUB_PYTHON (installed under ~/.cache/synthhub-python); the circuit's checks saw it, from the launcher's environment, but the developpeur's session did not: the envelope shows the home empty but what it declares and clears the environment, so « SYNTHHUB_PYTHON=… n'existe pas », and the developpeur could not play the tests he had to turn green. As Bazel declares what an action sees out of its sandbox (--sandbox_add_mount_pair) and the environment it gets (--action_env), a project declares its tools in grillhouse.outils of its package.json, { "<VARIABLE>": "<path>" } (absolute or under ~), read in one place, scripts/outils-cles.mjs. The envelope mounts each path read-only and passes each variable to the session; the circuit's passes (checks, final pass, regeneration of the references), npm run verifier and the night play with the same variables, taken from the key, whatever their launcher's environment. The key is read from the main tree, never a copy, so that an agent never opens a path for its next session; and a tool never undoes the envelope: a path is refused when it is /, the home or holds it, holds a mount of the envelope (the main tree and its copies, /tmp, ~/.claude, the scratchpads, the npm cache, the session directories), or lies under a hidden directory of the first level of the home (~/.ssh, ~/.gnupg…) but ~/.local and ~/.cache, or lies under or holds the keyrings ~/.local/share/keyrings, a link judged by its target too — the review found that "~" brought back the whole home, credentials included, over the mounts in writing. A value that is not a string, an invalid variable name, a refused or missing path is refused by its name before any work: the circuit stops at « lancement », the envelope, verifier and the night refuse. The project's charter template names the key under « Commandes ».

Fixed​

  • The frame's measures pass before the projects' at the lock of the machine (grillhouse-nhe): on 2026-10-31 the verification of 0.26.0 waited for the lock of the machine more than an hour without starting (« mesure de second rang (le dépôt du cadre), attente du verrou de la machine depuis 61 min »): every measure of the frame's repository was of the second rank, and five measures of the first rank from SyntHub and open-synth-descriptors passed before it, while every project waits for the frame's next version. The two ranks of 3uv.95.2 are inverted, as the priority classes of a batch scheduler (Slurm's partition priority): a measure played in the frame's repository, its agent copies included, is of the first rank, a project's of the second, which does not take the lock, even free, while a measure of the frame waits; the measure in progress always ends, nothing preempts it. The wait says its rank in the new words, « mesure du cadre », « mesure d'un projet ». Its bound is unchanged.

  • The finished copies and their build directories go at the end of each ticket, and Rust compiles through sccache (grillhouse-cyr): on 2026-10-31 Romain's disk was at 91-97 %. Each copy of a circuit of Rust kept its own target/, of 3 to 6.5 GB, after its ticket had ended: 34 GB under synthhub's .claude/worktrees (SH-cgi.7 alone 6.5 GB; SH-cgi.11, closed, still 2.9 GB), 8 GB in open-synth-descriptors, 3 GB in osc-bridge, 13 GB removed by hand in OSC Bridge; and not Rust alone: 180 copies under Grillhouse's (5 GB), 3.2 GB in BPScript's. The removal of the finished copies ran only at the end of the night, and kept every copy whose work had not entered main, its ticket closed or not: 58 of Grillhouse's 180 copies stayed for ever on « CHANGELOG.md n'est pas sur main », their entry having entered merged with its neighbours' by the CHANGELOG's merge driver. As a CI cleans its workspaces at the end of each pipeline, the removal now also runs at the end of each circuit; a file the CHANGELOG's driver merges counts as entered once each of its entries is on main; a copy's node_modules link, when it is all its local work, is no work; a locked copy (a live agent's) stays; a kept copy whose ticket is closed loses what the tools of its language wrote there, untracked by git (the module's ignorer, target or .turbo, and node_modules), its tracked work kept; and each kept copy's line names the place it holds. As Firefox and the CI of Rust, every cargo command of the frame that compiles (tests, verification, typing, clippy) runs rustc through sccache (RUSTC_WRAPPER=sccache), its cache ~/.cache/sccache, common to the copies of the machine and opened in writing by the envelope: each copy keeps its own target/, without the lock cargo takes on a shared one, and compiles nothing another copy compiled; each copy has its own server of sccache in each namespace of processes (/proc/self/ns/pid, which each envelope creates), on an abstract unix socket named after both (SCCACHE_SERVER_UDS), since sccache's default server listens on 127.0.0.1:4226 for the whole machine and the envelope shares the network; a wrapper the project sets is kept, without sccache, read as cargo reads it (the environment, then build.rustc-wrapper of each .cargo/config.toml from the project up to the root, then of $CARGO_HOME). npx grillhouse maj installs sccache 0.19.0 with the other binaries of the module cargo; a machine without it is refused before cargo runs, in one line that names npx grillhouse maj, rather than on the error of a wrapper cargo cannot run.

  • Two entries under the same heading of the CHANGELOG both enter main (grillhouse-tkv): in OSC Bridge (OB-d0b, 0.25.5, 2026-10-31 08:45), OB-20q.3 entered main with its entry under ## [Unreleased]; the integration of OB-d0b then refused its lot (« Rustine CHANGELOG.md appliquée avec des conflits », code 17), its copy brought to main conflicted the same way, and the supervisor kept both entries by hand. git's built-in merge=union, which git apply --3way honours (tried), would also keep both sides of one line changed twice, silently. As gnulib's git-merge-changelog, the frame now has a merge driver of the CHANGELOG (scripts/fusion-du-changelog.mjs, grillhouse fusion-du-changelog): git's own three-way merge, where a conflict whose base is empty (two additions at the same place) keeps both, main's first, each word for word, and any other conflict stays one, marked as git marks it. .gitattributes names it (CHANGELOG.md merge=grillhouse-changelog): the template of a project holds the line, npx grillhouse maj adds it to an existing project, and Grillhouse holds it. The hooks' placing (grillhouse hooks, the prepare of each npm install, and the update) writes the driver's command in the repository's configuration, the main tree's node_modules/.bin/grillhouse, so a copy writes the same; without the command, git's own merge marks the conflict. Grillhouse's root prepare now runs grillhouse hooks. Every three-way path takes it: the integration's git apply --3way --index, the relaunch's git apply --3way, the copy's git merge --ff-only --autostash.

  • After a green rerun of the CI, the resumption closes the ticket (grillhouse-906): in OSC Bridge (OB-20q.3, 0.25.5, 2026-10-31), 24fc218 entered main and was pushed; its CI was red on macOS on a flaky test unrelated to the lot (osc_transport_full_roundtrip, run 41181823725), and the queue reopened the ticket. The supervisor reran the failed jobs (gh run rerun 41181823725 --failed), green, and answered --reprendre: the queue had nothing in it, and the circuit stopped again at « 5.2 File » on « aucun commentaire de la file »; no command of the circuit led to the closure, and the ticket was closed by hand. As a merge queue (GitHub merge queue, bors, Zuul) judges the last attempt of a commit's checks, the circuit at 5.2, the branch out of the queue and the ticket open, now runs file.mjs --ci <ticket>: the queue finds the commit of main that delivers the ticket and reads its CI by its one reading (gh run view <id> gives the run's current attempt); green, it closes the ticket « intégré : », as an entry does, the run named at the ticket; still red, the ticket stays open on the red named. A flaky test gets no path of its own: the red comment gives the rerun and the charter's rule, a test known red goes into quarantine in the test, with the ticket that fixes it.

  • The board opens in the desktop app's Code tab (grillhouse-jqp): in BPScript (2026-10-31), /grillhouse did not open in the Code tab of the desktop app. The plugin registered its command and its board only when session.start said isInteractive, which the engine's types give true under the terminal's prompt alone, false for a -p run or the SDK; the desktop app starts its local session headless, as the SDK does (no surface, no person at the prompt), then attaches to it. As the engine's API provides, the plugin now also registers the command and starts the board when a surface attaches (session.attach, raised when the desktop app connects), once; a run nothing attaches to (an agent's claude -p, the SDK without a display) and an agent's copy still have neither, and the refusal of cd stays armed everywhere. The plugin's tests start a headless session, attach the desktop, and draw the pane on the terminal and on the desktop.

  • A finding to the testwriter that the plan skips stops the circuit at once (grillhouse-26x): in OSC Bridge (SyntHub SH-13y.1, 0.25.5, 2026-10-31), the package site holds its tests in Python, played by the CI alone, grillhouse.langages being ["cargo"], so the circuit skipped the testwriter (« aucun test dans le plan »). The reviewer sent the lot back three times with findings « Agent : testwriter »; each time the circuit skipped the testwriter again, relaunched the developpeur on an empty diff and the checks, then stopped at relecture-arret: 72 min, 30 of them lost, 2,18 $. As a CI fails fast on a step it cannot run rather than playing it again, a RENDU whose open finding goes to the testwriter while the plan skips him now stops at relecture-arret at that verdict, before any relaunch; its report names the finding, the role skipped and the plan whose packages play no test, its piece is the finding's, and its question to the supervisor is to declare the tests of the package to the frame, then --reprendre, or to settle the finding (--depuis developpeur --contexte, or --arreter). A finding to the testwriter when the plan plays tests follows its path unchanged.

  • The plugin refuses a Bash command that starts with cd (grillhouse-9cv): the agent of grillhouse-ool ran cd <its copy> && npm test -- … > log; echo $? at 04:22; Claude Code asks a person to approve a compound command that starts with cd, even where it asks nothing else, and the agent waited an hour for Romain. The charter and the instruction already said « env -C or git -C instead of cd »: the written rule was not enough. As Claude Code provides, a guard on the tool call now refuses (deny) with its reason, since a refusal never waits and a prompt does: in a Grillhouse project, the plugin's tool.call hook on Bash refuses at once a command with cd at the head of a subcommand (at the start, or after &&, ||, ;, |, ( or a newline), in every session, an agent's copy and a session without screen included, and the refusal names env -C, git -C, or the command alone when the working directory is already the right one; the agent takes that form and goes on. cd as an argument, in a path or in a word (abcd, cdk) passes. The recognition is one pure function, commenceParCd in mods/grillhouse/hooks/register.tsx, which the plugin's tests hold.

  • The night reads the tickets in progress only when a copy is left to judge, and the night tests follow the frame of 0.25 (grillhouse-8ye): the night of 2026-10-31 (b048461) was red on 12 files of night tests, 35 tests; the night of the 30th had not played the trials of the circuit and of the night yet. The removal of the finished copies (grillhouse-5vv) called bd list --status in_progress even when the night's copy was the only one, and the trials that a green night calls no bd went red (nuit, tests-de-nuit): retirerLesCopiesFinies now takes lireEnCours and reads only when a copy is left to judge, as a cleanup with nothing to clean asks nothing. The other reds were trials that no longer followed a rule decided since: the supervisor's context heads the instruction as its task (grillhouse-jya), so five files of the circuit read TA TÂCHE where they read the line CONTEXTE; --etendre orders the plan by the imports (grillhouse-x7c.1), so the trial of --etendre gives binder an import of forms; the envelope writes the components of the module typescript alone (grillhouse-pkl.5), so the agent of sous-modules.partage writes in its plan, packages/a; the frame installed in a trial carries its package.json (read by verrou-de-machine.mjs, pre-push-nuit) and the tools a project of TypeScript installs beside it (jsonc-parser, file-integration.renvois).

  • An answer titled « Constat N — (grillhouse-y42): in open-synth-descriptors (OSD-b91.2.3), the developpeur's sheet FAIT gave its 4 answers, one per finding, each with its piece, but each title began with « Constat N — », copied from the heading the instruction gives the finding (texteDesOuverts); reponsesAuxConstats compared the titles as they were and declared the 4 findings « sans réponse », twice, then the stop « sans-fiche » at 3 Code. As a review attaches a reply to its thread by its identifier, never by a copy of its display (GitHub, Gerrit), the circuit now recognises its own numbering: one function, cleDuConstat in scripts/resultats.mjs, brings an answer's title back to its finding's, used by reponsesAuxConstats and by avecLesReponses in scripts/circuit.mjs; a title of no finding, numbered or not, stays without answer, and the refusal names each expected title as it is. The reviewer, whose instruction heads each finding before it the same way (lignesDesConstats), had the same fault: a suivi levé titled « Constat N — » lifted nothing (constatsOuverts); it goes through cleDuConstat too. The schemas of reponses.titre and suivi.titre, the instruction and the reviewer's skill ask the title without its number.

  • The night tests' trial projects declare their language (grillhouse-0v3): the night of 2026-10-30 (255b40d) was red on four tests. Three came from grillhouse-3dr.2.3 (c34d354), which made the core refuse a project without grillhouse.langages and declared the language in the day's trials only: the real session of lancer-modele launched the launcher in a repository without a package.json, and the packed package of paquet-publie installed into a fresh project that declared none. The project of paquet-publie now declares its language as a project does (LANGAGE of the shared material); the real session moves, as it is, to the package of the trials (lancer-modele.seance.nuit.spec.ts), where its repository is the project the launcher prepares (projetDuLanceur: its language declared, Turborepo's stand-in), as every other test that launches the launcher (grillhouse-3dr.3.3); the guard of the trial directories (dossiers-d-essai.spec.ts) reads that package too, where the trials outside the temp directory of the envelope and of the locks now live. The fourth, the trial avecTests of grillhouse-pkl.2 (a7cb14d) missing from the directories a script leaves to its caller, was fixed on main by de5a160.

  • The testwriter writes the test dependencies of a manifest (grillhouse-ool): in open-synth-descriptors (OSD-b91.2.3), after the review, the testwriter rewrote his tests with tempfile::tempdir, as the rule of the temporary directory asks; osd had no tempfile in [dev-dependencies], and the testwriter's lock refused osd/Cargo.toml whole: BLOQUÉ, out of reach at 2 Tests. The same gap held for devDependencies of a package.json. As the author of a test of Bazel declares the deps of his test target, the module of each language now says which part of a manifest is test material (manifestes of the join, beside estUnTest): cargo, [dev-dependencies] and [target.<cible>.dev-dependencies] of a crate's Cargo.toml, read with smol-toml, an optional peer of the package that the update adds to a project of cargo alone (outils of the module cargo, its version in templates/cargo/package.json), loaded when a manifest is judged so that a project of TypeScript never needs it, and Cargo.lock; typescript, devDependencies of a package's package.json, and package-lock.json. The testwriter's write lock accepts a Write, Edit or MultiEdit of a manifest whose only change from the file on disk lies in that part, and the lock file at the root, even when the plan leaves the root read-only; any other change is refused, the path and each table or field named. The envelope opens the lock file in writing to the testwriter alone, so that his npm test brings Cargo.lock in line. A manifest out of the plan still stops the session, and the developpeur's rights do not change; the core knows no name of a section.

  • The launcher keeps a copy's work in the copy, never in git's stash (grillhouse-fy3): in OSC Bridge (OB-d0b, 2026-10-31), after an integration refusal, --depuis developpeur moved the copy forward to main by git merge --ff-only --autostash; the reapplication met CHANGELOG.md and the launcher stopped at « lancement » (code 10, « il reste dans la remise de git »). The supervisor resolved it by hand, then dropped the stash (0ba2b07). Git's stash (refs/stash) is common to every copy of a repository: a stash one copy leaves is seen, and can be popped, from another. As git keeps the state of a merge in conflict in the worktree that holds it, the launcher now moves a copy forward by the mechanism that already carries the lot of a branch the queue sent back (grillhouse-3uv.63), one module, scripts/enveloppe/travail-de-la-copie.mjs: the work is set aside as a lot in the copy's own git directory, the copy fast-forwards, the lot is applied three ways. A conflict stops the launch as before (CODE_COPIE, no agent started), the conflicts marked in the copy's files and unmerged in its index, the log naming the copy and each file; a relaunch on a copy whose conflicts are unresolved, or whose lot git refused whole (a deletion of a file main changed) still waits in its git directory, is refused until they are taken back, the stop naming the file. A relaunch without conflict moves as before.

  • The unit tests of a crate live in tests.rs near their module (grillhouse-agr): in SyntHub (SH-ae6.4, 0.25.5, 2026-10-31), two flaky relay tests lived in the #[cfg(test)] mod tests of a file of code (crates/service/src/server.rs:2176), and no role could fix them: the testwriter's lock refused every file of src/, the developpeur writes no test, and the tests could not move under tests/, since they call hosted_in, private to the module. Decision 5 of the epic grillhouse-pkl is amended: a test lives in a file of its own, never in a file of code. As rustc's tidy check wants them (src/tools/tidy/src/unit_tests.rs), the unit tests live near their module, in a file tests.rs or a folder tests/ under src/, a child module that sees the private; the tests by the interface stay under tests/ of the crate. The module cargo's estUnTest now says that a tests.rs under src/, and any file of a folder tests/ under src/, is a test file (played with its crate when it is Rust), so the testwriter writes it and the developpeur does not; of a file of code of src/, the testwriter writes the test module alone, as he writes the [dev-dependencies] of a manifest: he adds or removes the declaration #[cfg(test)] mod tests; (without it a new tests.rs is never compiled, and the proof of the red never sees it played), and removes an inline #[cfg(test)] mod tests { … } he moves into tests.rs; the lock refuses him any other change of the file, its first changed line named, and the rest of src/ stays the developpeur's. The test module is read as rustc reads it: other attributes may stand between #[cfg(test)] and mod tests {, and the braces of a comment (nested ones included), a string (raw ones, r#"…"#, br, included) or a character do not count, so that the move of SyntHub's pages.rs passes and no code after the module can go with it; the lines compare as they are. src/bin/tests.rs stays a binary target, code. The verdict of nextest ties a unit test to its file by its module path (server::tests::relais to src/server/tests.rs, or a file of src/server/tests/), so that the proof of the red finds the result of a new tests.rs. A crate plays tests when it has such a file, even without a folder tests/. The common charter says the rule once for every language: the kinds of tests, who writes, reads and plays them do not change, only the address of a test file follows the tool of its language.

  • No test reads the changelog (grillhouse-an7): in OSC Bridge (2026-10-31), two release commits in a row were red, because the testwriter of each ticket checked its changelog entry under the open section, which each release moves: tests/privacy_policy.rs (OB-vch.1.3) broke 0.18.0, tests/checksum_lenient.rs:325 (OB-20q.3) broke 0.19.0, looking for the title through ["Unre", "leased"].concat(). The common cause: the criterion « the changelog says it under the open section » became a test. As mature projects review their release notes rather than test them, and as a test that reads a document binds itself to its layout, the testwriter's skill and agent now say that no test reads the changelog, nor another document that tracks the versions; a criterion that names it is judged at the review, without a test, and only the tests of the release tool, which writes that document, read it. The form of the criteria (docs/agents/issue-tracker.md and its template, the explorer's and the supervisor's skills) says « the CHANGELOG says it », never tied to a section title, and the reviewer's skill judges the entry on the lot and sends back a test of the lot that reads it. No guard refuses such a test: the frame's reading of what a test names (TypeScript's, for the paths of the tests) over-reaches by design, for replay, and would refuse a test that only leaves the changelog out of a scan, and cargo reads no test's text at all; the rule stays the skill's and the review's.

[0.25.5] - 2026-10-30​

Added​

  • The night removes the copies whose content is on main (grillhouse-5vv): working copies survived the entry of their content on main, the circuit removing only its own at the integration: OSC Bridge kept 5 copies out of the frame (4.4 GB) and 2 agent copies (.claude/worktrees/agent-*, the Agent tool in isolation) after their merge, Grillhouse 79 agent copies (5.7 GB). As git worktree prune and a CI's workspace cleanup at the end of a pipeline, the night (scripts/nuit.sh), once its steps are played, prunes the list, then passes each copy git worktree list names, the main tree and its own left out, through the existing scripts/retirer-copie.sh without --jetable (scripts/copies-finies.mjs): a copy whose commits and local work have all entered main by their content goes, with its branch (main and a branch another copy holds stay); since retirer-copie.sh judges only the local work, the copy's HEAD is judged first, so that a detached copy's commit never becomes unreachable. A copy refused (commits or work not entered, its first path named; a lock) or held by a running circuit (its ticket in progress, its <copie>.travail, the lock of the integration or of the queue) stays, its log line naming why; tickets in progress that do not read within a minute hold every copy. The removal never changes the night's verdict.

Fixed​

  • The proof of the red reads tests of cargo that do not compile as a red of the build (grillhouse-egm): in open-synth-descriptors (OSD-b91.2.3), the testwriter's tests called the ticket's new interface (osd::convert, osd::read_as, Version::V0_5); the crate's test targets did not compile, cargo stopped the whole pass, and the proof read « 0 rouge(s) … 6 fichier(s) qui ne se charge(nt) pas … non joué (code 1) » and refused the lot, the testwriter stopping out of reach. In TDD a test that does not compile is a red (Kent Beck, TDD by Example), and the circuit already reads a failed build of a package of the plan as « construction de », whose tests play at the checks. The module cargo now plays the build of a crate's test targets as a task of its own, cargo test --no-run -p <crate> (the build nextest runs itself), before nextest and the doctests, as Turborepo's test depends on build: a task build of the verdict, named after the crate, its log <target>/grillhouse/<crate>-build.log; a failed build leaves the crate's other tasks not played. The core does not change.

  • The reviewer never accepts a lot on a required piece he cannot read (grillhouse-dw5): in OSC Bridge (SyntHub SH-cgi.9, commit 92234db) the ticket required that a change visible to the users go up to the owner; the reviewer wrote he could not read the developer's handover on it, then rendered ACCEPTÉ, and the circuit integrated, pushed and deployed. As Gerrit's « Verified » requires the result, the reviewer's skill now says that a piece a criterion or a section of the ticket requires, unreadable, renders the lot by a blocking finding to the agent who owes it, and that a decision of the owner the lot has not received goes up by the reviewer's question, never under an ACCEPTÉ. No new mechanism of the circuit.

  • The supervisor's context comes before the open findings (grillhouse-jya): under 0.25.2, BPScript relaunched bp-mono-vbwf.320.14.2.3 with --depuis developpeur --contexte "<écris dans 030-binder la demande de racine…>"; the instruction carried the context at its line 13, after the rule that a sheet FAIT answers each open finding of the reviewer. An old finding (the documentation of 130-projector) stayed open: the session worked it alone, its sheet was refused for a missing answer, the resumption changed no file, then « sans-livraison », twice: 16 sessions, 11.70 $, 84 % of the time lost. As the owner asks (the instruction always comes first, old remarks at most as context) and as a review relaunched by its author on a change he frames keeps its open threads in sight without blocking on them (GitHub, Gerrit), the supervisor's --contexte (with --depuis, --reprendre or --etendre) now heads the instruction of the testwriter and the developpeur, fresh or resumed, as their task, before the ticket, the report and the findings; the findings open at the launch of the run are marked (auLancement) and given as context, and a developpeur's sheet FAIT is no longer refused for want of an answer to one of them (constatsDeLaSeance in scripts/circuit.mjs); a finding a RENDU states within the run is the task again and asks its answer; an answer given is still kept with its finding. Without --contexte, nothing changes. The line CONTEXTE : of their first template is gone; the reviewer's stays.

  • --etendre orders the plan by the join (grillhouse-x7c.1): the reviewer of grillhouse-x7c found that etendre in scripts/circuit.mjs placed a component added to the plan before its reader by the dependencies, devDependencies and peerDependencies of the package.json files; in a workspace of cargo such as OSC Bridge no crate has one, so the component added always went to the end of the plan. As the core asks the order of the language's module (Pants and its backends), the plan is now ordered by lecteurs of the join (ordonnerLePlan): its lit, and its new parLesTests, what a component's tests read (the imports of a package's tests, which the guard of the consumers keeps out of lit; a crate's dependencies of development), so that BPScript's 010-parser, read by the chain tests of 040-checker alone, still enters before it. etendre reads no package.json any more. lecteurs builds TypeScript's language service only when the ticket's text names an element to resolve (7.9 s on BPScript for none).

[0.25.4] - 2026-10-30​

Changed​

  • The last five large tests of the day leave the debt (grillhouse-3dr.3.7): after grillhouse-3dr.3.6, five large tests of the day stayed in Grillhouse's debt (un-commit-par-ticket, verrous, version, consommateurs-arbitres, turbo-des-paquets-donnees), each running a hook, a guard or a command in a process inside a trial git repository, or Turborepo itself. As the test pyramid of Google and Bazel's size ask, their modules take what they read from outside as an argument: the hook of one commit per ticket its reading of the history (gitLog, commitsDelivering) and its verdict on Beads' answers (controle, lireBeads), the tagging of a release the git it runs (etiqueter), the guard of the consumers its judgement on the interfaces' texts and the ticket's readers (juger, ticketDeLaBranche). Their day cases test the module by that interface, in process (the hook's history still read by git in a trial repository, a medium test), each new test seen red on the fault its former test caught (a mutant of the module); the locks' cases keep refusal and refusDeCommande in process, their trial directories in the run's own root. Their cases that only a large test proves (the hook, the lock, the guard or the release command run as a process in a git repository, Turborepo's own graph and hashes on the generated turbo.json) move as they are to packages/grillhouse-essais as night tests. The debt of the large tests of the day falls from 5 to 0.

Fixed​

  • The circuit refuses at its start a ticket without its « ## Architecture » section (grillhouse-d57): OSC Bridge's circuit OB-vch.1.3 under 0.25.3 led step 1 (plan, questioner) and step 2 (testwriter) on a ticket without that section, then the developer's lock refused it at step 3 (scripts/verrous/verrou.mjs: « n'a pas sa section « ## Architecture » : le code attend l'architecture »), two steps of sessions lost. As a CI validates its configuration before it runs its jobs, npx grillhouse circuit now checks the section before step 1, exit 2, with the lock's reason: the rule lives once, sansArchitecture in verrou.mjs, read by the lock and by the start of the circuit.
  • The circuit reads a ticket's components by the join (grillhouse-x7c): OSC Bridge's first circuit under 0.25.3 stopped at once, npx grillhouse circuit OB-vch.1.3 refusing « le composant « osc-bridge » du titre ne nomme ni un paquet ni un chemin du dépôt. »: osc-bridge is a workspace of cargo whose application is the root crate (members = ["."], [package] name = "osc-bridge"), and scripts/circuit.mjs listed the components by the workspaces of npm (paquets) at seven places. As the core asks its components of the language's module (Pants and its backends), and as the envelope does since grillhouse-pkl.5, the circuit now reads them from paquetsDuLangage: a crate at the root is the component ., named by its crate, which the title, the discoveries and the scope of the commit message name; the packages out of the frame keep their mark (hors). A project of TypeScript resolves its components as before.
  • A Cargo.lock that git does not track is refused by name (grillhouse-rph): OSC Bridge's circuit OB-vch.1.3 under 0.25.3 stopped at 5.1 Commit: osc-bridge ignored its Cargo.lock in .gitignore, so the integration's copy, taken from git, had none, and the module cargo's verification, which plays --locked, failed with « error: cannot create the lock file …/.claude/worktrees/integration/Cargo.lock because --locked was passed to prevent this », while the main repository, its lock lying on disk, stayed green. Cargo recommends committing Cargo.lock for every project, and a verification plays the exact versions of the repository, as npm ci refuses a project without package-lock.json: the frame keeps --locked and makes the lack readable early. grillhouse tests, grillhouse verifier and the preparation refuse, before any run of cargo, a workspace whose Cargo.lock git does not track, in one line (« ⛔ Cargo.lock non versionné : git add Cargo.lock », or cargo generate-lockfile first when it is absent), code 2; grillhouse maj writes the same line on the error stream, its code 1, and plays no verification (aFaire, a new field of the language's share of the update). A project that ignores its Cargo.lock removes that line from .gitignore and commits the file.

[0.25.3] - 2026-10-30​

Fixed​

  • The template's deny.toml allows CDLA-Permissive-2.0 (grillhouse-0wy): OSC Bridge's cargo deny check licenses refused webpki-roots, Mozilla's certificate authorities, which most TLS in Rust pulls in (tungstenite, ureq), under CDLA-Permissive-2.0, a permissive licence of the Linux Foundation for data, which asks only that its text go along with the data. On the owner's word (2026-10-30), templates/cargo/deny.toml adds it to allow. grillhouse maj writes deny.toml once; a project that has one adds the licence itself.

[0.25.2] - 2026-10-30​

Fixed​

  • grillhouse maj brings the frame's range up in every manifest of the project (grillhouse-49r): BPScript's update to 0.25.1 (bp-mono-vbwf.322.15) left each package declaring "@roomi-fields/grillhouse": "^0.24.0" in its devDependencies, as the update kept a declaration a package held; npm then kept a copy 0.24.15 under each packages/*/node_modules (32 copies), where the entry ./vitest-config/duree does not resolve (« Missing "./vitest-config/duree" specifier »), and the hook refused the commit until BPScript set each range by hand. As npm install <pkg>@<version> --workspaces, Renovate and syncpack align every declaration of a dependency of the workspace, the module typescript's share of the update now writes ^<version> in each manifest (the root and each package, dependencies or devDependencies) whose range of the frame's package is lower than the version installed; a range that covers the version, one above it or one that is no range of versions (file:) stays. The report names each manifest brought up, and asks for npm install before the verification.

[0.25.1] - 2026-10-30​

Fixed​

  • The duration reporter is a published entry, @roomi-fields/grillhouse/vitest-config/duree (grillhouse-8cf): BPScript's update to 0.25.0 (bp-mono-vbwf.322.15) failed at its version commit: packages/995-tools/src/verif-portes.mjs:38 launches each test of a gate with the frame's duration reporter, read at the package's inner path scripts/vitest-config/duree.reporter.mjs, which 0.25.0 moved under scripts/langages/typescript/vitest-config/ (ERR_MODULE_NOT_FOUND), and no published entry gave the reporter. As Vitest loads a reporter by a package's name (--reporter=<specifier>, reporters: ['<specifier>']), the package now publishes ./vitest-config/duree beside ./vitest-config/mesure, typed as a Vitest Reporter (duree.reporter.d.ts); a project names --reporter=@roomi-fields/grillhouse/vitest-config/duree and no longer depends on where the file lives. The report « reste au projet » of grillhouse maj now names this entry for the former path.
  • The template's deny.toml leaves the project's unpublished crates out of the licence check (grillhouse-is4): OSC Bridge's update to 0.25.0 turned npm run verifier red on cargo deny check licenses: cargo-deny checked the project's own crate, AGPL-3.0-or-later, against the template's allow, a list of permissive licences meant for the dependencies, so every project under a copyleft licence was refused. As cargo-deny provides, templates/cargo/deny.toml sets [licenses.private] ignore = true: a crate with publish = false is not checked. grillhouse maj writes deny.toml once; a project that has one adds the table itself, and each crate of the project not published on a registry says so with publish = false (a crate without the field counts as published on crates.io, and is checked).

[0.25.0] - 2026-10-30​

Added​

  • A change of one script replays the tests that read it, not the whole package (grillhouse-3dr.3.4): the measure of grillhouse-3dr.3.1 at rest (main fc795af) took 439 s for the full pass and 442 s after a one-line change of scripts/verrous/verrou.mjs and scripts/services-du-noyau.mjs, its 127 test files of packages/grillhouse all replayed, none from the cache: the package declared its whole scripts/ in its grillhouse.lit, because its tests launch the scripts by their path, which Vitest's graph does not hold. As Bazel hashes a test on the data its target declares and Turborepo a task on its inputs, the frame now reads, in each test's code and in the test material it imports (by a relative path, or a package of the shared material by its name), the paths it names whole (the constant SCRIPT of a test that launches a script), the files a pattern with a fixed start covers (packages/grillhouse/scripts/**/*.mjs), and a command of the workspace it runs by its link or its command line (node_modules/.bin/grillhouse, npx grillhouse maj, the plugin's hook), with what those files import and name from file to file, the scripts of the shell included (vitest-config/lances.mjs, which the guard of the sizes shares); a pass measured against the last green adds those tests to the ones Vitest relates to the changed files. packages/grillhouse no longer declares its scripts: after a change of verrou.mjs, Vitest lists 58 test files of 127 (1 070 s of the 3 987 s cumulated, the longest tests-de-nuit.spec.ts, 172 s); after verrou.mjs and services-du-noyau.mjs, 105 files (3 306 s), the second being imported by most of the frame. A new guard of the frame, grillhouse chemins-des-tests, keeps any script from being lost in silence, as Bazel's sandbox fails a test that reads an undeclared input: a string of a test that ends the path of a module of its package which the frame does not find in what the test reads nor under its package's grillhouse.lit (a path built at run time, path.join(SCRIPTS, nom)), or a pattern without a fixed start that names a directory of it (**/scripts/*.mjs), is refused; the test writes the path whole, or its package declares it. Grillhouse had one such test (the cargo module's conformity, its guards named by their file name), BPScript would inscribe 11; npx grillhouse maj inscribes a project's findings in its debt once (migration 0.25.0). The guard of the sizes now also follows the shared test material imported by its package's name (@roomi-fields/grillhouse-matiere/test-fixtures, any entry ./test-fixtures of a package of the workspace), a barrel of it to the modules that declare the names imported, so that a large test does not hide there: tests-de-nuit.spec.ts is large again, as its debt inscribes it.
  • The tests of every project leave nothing in the temporary directory (grillhouse-nt4, grillhouse-1js merged into it): the tests of several projects (OSC Bridge, SyntHub, Grillhouse itself) left files and folders in /tmp, above all when a test failed; /tmp is often a memory disk every session of the machine shares, and it had already run out of inodes and broken projects at work (2026-10-24: df -i /tmp at 1 044 633 of 1 048 576, 2 888 entries over 2 h old left by trials; SyntHub leaves ~10 folders synthhub-db-* at each pass). The base of a pass removed what tests left without a word, and a pass interrupted by Ctrl-C left its base in /tmp until the next one swept it. As pytest's tmp_path and the CI of OSC Bridge (OB-ud1.3), which runs its tests under a temporary directory of their own and fails on anything left there, the common charter now writes the rule, in no language's words: a test makes its temporary files with its language's tool, removed at its end, a red test included, and each pass of tests plays under a temporary directory of its own, removed at its end even red or interrupted, and fails naming what a test left there. Each module of language names its tool and plays the guard. The module typescript: the base of each run of Vitest (the frame's base configuration, so npm test, npm run verifier and a direct run alike) is named in TMPDIR, TMP and TEMP; what the tests left in it at the end of the run, once Vitest removed its own directory, makes the run red (code 1), each name written, the caches of the tools a test launches tolerated by name with their reason (node-compile-cache, Node's compile cache npm enables; claude-<uid>, Claude Code's temporary directory: their variables would enable the cache in every Node the tests start, or bring Claude's scratchpads back into /tmp); mkdtempSync under tmpdir(), removed in afterAll, is the tool. The module cargo: tester and verifier play nextest and the doctests under a base of their pass named in TMPDIR, TMP and TEMP, and fail the same way; the crate tempfile is the tool. Every pass of tests, npm test and npm run verifier included, removes its base when SIGINT, SIGTERM or SIGHUP interrupts it, then lets the signal end it; a base whose owner died is still swept by the next pass. The core gives the modules the line of the guard (ligneDesRestes) and the removal at the interruption (retirerALInterruption); a base names its variables (env) and what is left in it (restes). A project's use of the tool in its code stays its own (tempfile, OSC Bridge's common::temp): from this version, a test of a project that leaves a file in its temporary directory turns its pass red.
  • The guards of structure of a workspace of cargo (grillhouse-pkl.6): the module cargo played no guard and engendered no file, so grillhouse gardes-du-cadre checked nothing in a project of Rust, and the probe of grillhouse-pkl.1 found OSC Bridge red at cargo clippy -D warnings (code 101, 18 lints), its tests/ unread without --all-targets. The module now plays three guards, in this order. clippy.mjs runs cargo clippy --all-targets --message-format=json -- -D warnings and makes each diagnostic with a code a finding (its file, its line, the lint as its rule), judged by the project's debt and written in SARIF, so that an adopting project inscribes its lints, a lint more refuses and a lint less is pruned; clippy red without a diagnostic refuses, named. frontieres.mjs holds each dependency between members that cargo metadata --no-deps reports, of any kind, against one list in the workspace's manifest, [workspace.metadata.grillhouse.frontieres] (a crate, the crates it may depend on), as Nx's depConstraints: one absent refuses with its kind (normal, dev, build); the probe found cargo-deny's bans read the other way and leaving an absent crate free, so it stays for the crates out of the workspace. index-interfaces.mjs engenders docs/agents/index-des-interfaces.md, one line per crate's docs/INTERFACE.md and one for the root's, as the module typescript's index, and its check finds it up to date or late. OSC Bridge has one crate today; the boundaries matter once its crates/* get their manifests. The plan dropped cargo semver-checks, cargo public-api and its pinned nightly, which no project needs now.
  • The module cargo: a workspace of Rust served by the join (grillhouse-pkl.3, grillhouse-pkl.4 merged into it): the frame's list of languages held typescript alone, a project that declared another was refused, and a project of Rust (OSC Bridge, SyntHub, open-synth-descriptors, decisions 1, 2, 3 and 5 of the epic grillhouse-pkl) had nothing to plug into. As Pants's Rust backend and Bazel's rules_rust read a Cargo workspace from cargo itself, the module scripts/langages/cargo/ answers each demand of the join, on the probe of grillhouse-pkl.1: the components are the members of cargo metadata --no-deps --offline, each crate's folder and name; a file's crate is the longest folder that holds it; the readers of a crate are the members that depend on it by its path, the kind (normal, dev, build) in par; the crates touched since a commit come from git's diff, their dependents from the manifests, development dependencies included, and the workspace's own Cargo.toml and Cargo.lock touch every crate, as Turborepo's global dependencies; <crate>/tests/** is a test file, played when cargo makes a target of it (tests/<nom>.rs, tests/<dossier>/main.rs; OSC Bridge's tests/fixtures/devices/ is data), tests/common/** the test material, src/** never a test (decision 5), and the crates whose manifest says [package.metadata.grillhouse] matiere = true are the shared material; a crate with a folder tests/ plays tests. Its commands, { script, args }, describe and never run: tester plays cargo nextest run -p <crate> --no-fail-fast, then cargo test --doc -p <crate>, which nextest does not play (the probe: 228 tests, no doctest), each crate touched since the last green and its dependents under the circuit's mark; verifier the same, then cargo deny check, and keeps the green, under the lock of the machine as the module typescript's (a measure that holds it makes it wait; the bound reached, it stops at 75 without running cargo); typer cargo check --all-targets; preparer cargo fetch --locked. Nextest reads the frame's profile grillhouse as a tool's configuration (--tool-config-file), under the project's own, and its JUnit report goes to the results directory with the task of each run, which the verdict reads (code null for a task that did not run, 75 « à repasser », a red making verifier 1). The lot of a review gives one element per crate added, changed or removed, and each changed Rust source to the reviewer himself. trouve finds a Cargo.toml at the root; the module installs no package of npm. The frame's tests play it against a fake cargo first on the PATH, and the real one at night (cargo.nuit.test.ts): the suite of conformity passes on both. A project that declares two languages is refused, both named, and the message cites no ticket any more (Q5 of the ticket: SyntHub, osc-bridge and OSD hold no TypeScript today); the clippy guard, the boundaries and the index of the interfaces come with grillhouse-pkl.6, the envelope and the integration with grillhouse-pkl.5, the update and the template with grillhouse-pkl.7.
  • The other tests of the frame's chain, at night, beside the circuit's (grillhouse-3dr.3.3): after grillhouse-3dr.3.2, 25 test files still mounted a trial repository by day and launched an entry point that chains others (the night nuit.sh, the integration and its queue, the launcher of an agent, the session start, grillhouse maj and init, retirer-copie.sh): 2 838 s of the cumulated time of a green verification of main, 946 tests, 25 of the 42 large tests of the day inscribed in the debt. Each file's body was read before its move: each launches one of these entry points and asserts on the effect of the chain. They move as they are to packages/grillhouse-essais (git mv, *.nuit.spec.ts, their it and expect counted the same in tests/paquet.spec.ts), with their harnesses (integration-essai.ts, file-integration-essai.ts, sous-modules-essai.ts); the functions and values of the frame's scripts they took in their process (mettreAJour, rapport, regenerer, gardesDuCadre, optionsDuRole, publie, refusLots, lireEntrees, fluxDeLaBranche, the exit codes of the envelope, the hooks…) are read in a process of their own (tests/cadre.ts, the frame of the same tree). The harnesses both packages use (the night's projects of trial, the language of a project of trial, the trial directories of the envelope) move to the shared material, @roomi-fields/grillhouse-matiere/test-fixtures, the frame's repository and its update passed in by the caller so that it still imports no package. The frame's own tests that played a moved file name it in its package (machine.spec.ts, the night test dossiers-d-essai.nuit.test.ts). The debt of the large tests of the day falls by 25, from 42 to 17.
  • The tests of the circuit, at night, in a package of their own (grillhouse-3dr.3.2): the 28 test files that mount a trial repository and launch the circuit (circuit*.spec.ts, base-de-passe.spec.ts) took 8 379 s of the 15 736 s of a green verification of main (53 %), played by day each time a script of the frame moved, and inscribed 28 of the 70 large tests of the day in the debt. As Nx keeps its end-to-end projects apart from the projects they test, and as turborepo-tests launch the binary of turbo, they move as they are (git mv, their it and expect counted the same) to a new private package, packages/grillhouse-essais, as night tests (*.nuit.spec.ts), with their harness circuit-essai.ts: the night plays them all, npm test -- packages/grillhouse-essais/tests/<file> one named, and the day the package's own small test (tests/paquet.spec.ts). They launch in processes the scripts of the frame's package of their own tree (packages/grillhouse beside them, never main's, which its name reaches from a copy without its own install); a function of a script they called in their process (the codes of the circuit's stops, texteDuVerdict, commitIntegre, couvertPar, lireAvancement, departDe, dossierDeTravail, schemaDeFiche, the writing of the turbo.json) is called in a process of its own, and a base of a pass is held by a process that lives until it closes. The test material both packages share (machine.ts, claude-substitut.ts, config-git.ts, couvre) moves to a third private package, packages/grillhouse-matiere, which imports no package and exports ./test-fixtures, as BPScript's corpus (the owner's word of 2026-10-29, « ok pour le 3eme paquet »): an entry ./test-fixtures on the frame's package would have made the whole frame shared material, and the material under the essais a cycle that Turborepo refuses. The debt of the large tests of the day falls by 28, from 70 to 42.
  • The test pyramid, in the frame and in Grillhouse (grillhouse-3dr.4): 118 of Grillhouse's 158 test files started a process, a verification of main took about 22 minutes, 54 % of it for the tests of the circuit, which mount a trial repository; no rule of the frame said to test a module by its interface, nor classed the tests by size. As the test pyramid of Google (Software Engineering at Google, ch. 11 and 14) and Bazel's size, the common charter now writes the rule: a small test checks its module by its interface, a medium one assembles a few modules on the machine, and a large one, which mounts a trial project and starts the product or the frame there, is a night test (*.nuit.test.*), never played during the work. The testwriter chooses the smallest size that proves the criterion; the reviewer sends back a large test where a small one suffices. A new guard of the frame, grillhouse tailles-des-tests, classes each test file git lists by a static reading of its text and of the test material it imports (large: git's init, clone or worktree add and the start of something else than git; medium: a process, or several modules of the repository; small otherwise), and refuses a large test of the day; a night test or a bench never. The large tests of the day that exist are the known debt (grillhouse-dette.json), frozen: Grillhouse inscribes 70 (of 170 files: 24 small, 74 medium, 72 large, 2 of them at night), BPScript would inscribe 7 (of 1 079: 514 small, 558 medium, all large ones in 995-tools). npx grillhouse maj inscribes a project's debt once, at the update that brings the guard (migration 0.25.0), so that its verification does not change that day; the frame rewrites no test of a project.
  • The join of the languages: the core asks a module of language, typescript first (grillhouse-3dr.2.1): the core of the frame called TypeScript's tools in place: the survey of the affected components, the locks, the guards, the circuit and grillhouse tests/verifier imported the modules of Turborepo, Vitest and the guards of structure (composants-affectes.mjs the language service, verrous/verrou.mjs the rule of a test file of consommateurs.mjs, resultats.mjs the summaries of Turborepo and the reports of Vitest, avancement.mjs a call of turbo), so that a project of another language (Rust, grillhouse-pkl) had nothing to plug into. As Pants activates the backends its configuration names, the core now asks the module of the project's language (grillhouse.langages of its package.json, a closed list, typescript; a project without the declaration is read as ["typescript"] until grillhouse-3dr.2.3 writes it; one language served, their merge is grillhouse-pkl.3): its components and the readers by the code of the elements a ticket names, the components touched since a commit with their dependents, its commands and the reading of their verdict, the rule of a test file, its generated files and its guards. The core's docs/INTERFACE.md and docs/CADRE.md write it, scripts/jointure.d.ts types it, and the new entries @roomi-fields/grillhouse/jointure (langageDe) and @roomi-fields/grillhouse/conformite publish it; a suite of conformity, as ESLint's RuleTester, holds a module to each demand, and seven defective modules each fail their own case alone. The module typescript (scripts/langages/typescript/) calls the scripts in place, which grillhouse-3dr.2.2 moves by tests/temoins/repartition.json; the three modules of the core kept in vitest-config/ (the progress, the base of a pass, the CPU pressure) move to scripts/mesure/, and the readers of Turborepo's summaries and Vitest's reports to scripts/langages/typescript/verdict.mjs. Witnesses recorded on main before the change (tests/temoins/) hold « as before »: the survey of BPScript 320.8, the 30 paths of the rule of a test file and the rights of the locks, the codes 0, 1 and 75 of grillhouse tests and grillhouse verifier with their verdicts. The guards of grillhouse:gardes play the language's first, then the core's (resumes last). The rests of the core that still name a tool are inscribed with their ticket (tests/unit/jointure.spec.ts: the rights, the envelope and the night, grillhouse-pkl.5; the update and the sources, grillhouse-pkl.7; the script test:vitest, grillhouse-pkl.2).
  • The module typescript under its folder, its tools optional (grillhouse-3dr.2.2): after grillhouse-3dr.2.1, the core still imported five files of TypeScript out of the join (the circuit elements-du-lot.mjs, the integration consommateurs-arbitres.mjs, resumes.mjs index-interfaces.mjs and interfaces-contre-code.mjs, the envelope consommateurs.mjs, grillhouse-maj.mjs), the scripts of the module lay among the core's, and every project installed API Extractor and jsonc-parser, a project all Rust included (the owner's word of 2026-10-29: « un projet full rust a ses outils rust uniquement »). The 31 files of the module move under scripts/langages/typescript/ by git mv, with resumes.mjs (a check of the TSDoc summaries, as lintian's synopsis check lives with Debian's tools) and the four migrations that replay one of its guards (as each plugin of Nx carries its own migrations); their tests follow under tests/unit/langages/typescript/, and the published entries keep their address, so that no project rewrites an import. The core asks the module, by the join, the elements of a lot (elementsDuLot), the shared test material (matieres), its migrations (migrations), and its guards and generators as commands, each a subcommand by its name (grillhouse frontieres), which the command runs in a Node of its own: loaded to name it, the module's scripts would not run again in its process. The arbitrages of a ticket, the code of src/ and the typing script move to the core (arbitrages.mjs, CODE and TYPAGE of paquets.mjs). As a plugin of Nx imports @nx/devkit alone, the module imports of the core its published entries alone, ./jointure (now scripts/services-du-noyau.mjs) giving it the core's services; the guard of the boundaries holds both ways, by the repository's own rules of dependency-cruiser (.dependency-cruiser.projet.cjs), as Nx's enforce-module-boundaries. The suite of conformity covers the components alone, the readers, the elements of a lot and the shared test material, and its defective entry makes each generated file late; twelve defective modules each fail their own case. The tools of the language (API Extractor and its model, TSDoc's configuration, jsonc-parser, Turborepo, Vitest, knip, dependency-cruiser, TypeScript) become optional peers of the package (peerDependenciesMeta), as Vite declares the preprocessors it imports: npm installs no optional peer, where optionalDependencies would install them all; grillhouse maj adds to a project the ones the template declares, API Extractor and jsonc-parser now among them, and the package lists the ones its own scripts import in its devDependencies, as Vite lists its optional peers for its own tests.
  • The languages a project declares (grillhouse-3dr.2.3): after grillhouse-3dr.2.2, a project without grillhouse.langages was read as ["typescript"], and grillhouse maj added every optional peer of the package but TypeScript and Vitest, whatever the project's language: nothing wrote the declaration, and a project all Rust would have received the tools of TypeScript (the owner's word of 2026-10-29: « un projet full rust a ses outils rust uniquement »). The declaration is now the only reading: the core refuses a project that declares none, named, with npx grillhouse maj. As each plugin of Nx infers its projects from its own files (createNodes), each module of language says where it finds its code (trouve: typescript, a tsconfig.json at the root or in a package of the frame, as BPScript holds none at its root) and lists its tools (outils); grillhouse maj and grillhouse init write grillhouse.langages from what the modules find, keep a declaration present, and add the tools of the declared language alone. Where no module finds its language (a project of Rust, until the module cargo of grillhouse-pkl.3 and its detection of grillhouse-pkl.7), maj refuses the project, named, nothing written: the frame invents no declaration. No import of a project is rewritten. Witness: a trial copied from BPScript (tests/cas-reels/bp-3dr.2.3), declared ["typescript"], no tool of another language added, nothing rewritten on a second pass. The suite of conformity gains the case trouve; the frame's repository declares its language. Between the install of 0.25 and npx grillhouse maj, a project has no declaration yet: the write lock refuses each write there, exit code 2, in one line naming grillhouse.langages and npx grillhouse maj (a hook that threw exited 1, which Claude Code lets pass), while the commands, npx grillhouse maj among them, stay open (the write lock judges the tools of writing alone, the lock of the commands no language); the session start names the missing declaration under « Manque », with the same command.

Changed​

  • The tests of one module are small tests by day, their chain at night (grillhouse-3dr.3.6): 17 large tests of the day stayed in Grillhouse's debt after grillhouse-3dr.3.3, each testing one module through a process in a trial repository (963 s cumulated on the green pass of 3dr.3.1, the three longest verifier.depuis-le-vert 214 s, tests-cibles 168 s, tests-de-nuit 167 s). As the test pyramid of Google and Bazel's size ask, 12 of them leave the debt, their day cases testing the module by its interface: rewritten for the options the plugin of Vitest leaves for each change since the last green (changements.spec.ts) and the complete pass of the measure (dernier-vert.spec.ts), the day's and the night's configurations, the plan of the envelope (bwrap's arguments) for the shared material and the home, the reporter and the reading of the progress, each new small test seen red on the fault its former test caught (a mutant of the module); kept as they were for the plan of the envelope, a package and the enclosure, the register, the status line, git's setting and npm test out of git (medium). Their cases that only a large test proves (bwrap itself, a real pass of npm run verifier and npm test under Turborepo and Vitest, a hook in a git repository and its copy) move as they are to packages/grillhouse-essais as night tests. The sorting of the session's environment by the envelope (no variable it does not declare passes) keeps a guard by day, a small test of environnementDeLaSeance; lierDependances of the shared material, its own module, serves the day and the night without a copy. The debt of the large tests of the day falls from 17 to 5 (un-commit-par-ticket, verrous, version, consommateurs-arbitres, turbo-des-paquets-donnees).
  • The update, the template and the guards of a project of Rust (grillhouse-pkl.7): after grillhouse-pkl.5, four files of the core still named TypeScript's tools (the join's test inscribed them as rests): grillhouse maj wrote the tests by Vitest, the turbo.json, the typing and .turbo/ in every project, installed no binary of cargo, and read its scripts in the template of TypeScript alone; the source files left .turbo out, never target; the session start ran a file of the module typescript by its path; the list of the core's migrations held the one of Vitest's configuration. And a red guard of cargo was named grillhouse clippy, a command the module did not offer (grillhouse-pkl.6.1). Now the module of the language brings its share of the update (miseAJour: its template, templates/projet/ or the new templates/cargo/ — deny.toml, without which cargo-deny permits no licence and exits 4, .config/nextest.toml, rust-toolchain.toml, a minimal package.json — what its tools ask of the project, its generators), its binaries (binaires: nextest and cargo-deny, installed by the commands the module describes, cargo install --list then cargo binstall --no-confirm --locked <nom>@<version>, which the core only runs) and what its tools write (ignorer: .turbo, target), which the source files leave out and the .gitignore receives; the refusal of maj names each language's sign (signe); the index of the interfaces is a generator of cargo's share; the migration of Vitest's configuration is the module typescript's; each guard of cargo is a command by its name. The core names no tool, cargo included, and the join's test holds no rest.
  • The envelope, the rights, the launcher, the integration and the night of a project of cargo (grillhouse-pkl.5): after grillhouse-pkl.3, four scripts of the core still named TypeScript's tools in their code, inscribed as rests of the join: the envelope opened .turbo and Vite's cache and mounted Turborepo's cache in the main tree, so that a session of a project of cargo found its target/ and cargo's registry read-only, and neither cargo nor rustup at all (the home of the envelope shows only what it declares); the plan of the envelope knew the packages of npm alone, so that a plan naming a crate wrote the whole copy; the rights refused Vitest and Turborepo to a writer, and let cargo test and cargo nextest through; the launcher built the copy by Turborepo and the night played its night tests by Vitest, each by the path of a file of the module typescript; and the integration played no cargo fetch --locked before the verification. The module of a language now declares where its tools write (sorties: TypeScript's .turbo and node_modules/.vite proper to the session and //.turbo/cache written, mount for mount as before; cargo's target, and in ~/.cargo its registry, git dependencies, advisories and the files of its locks and of the SQLite cache of its packages in writing, ~/.cargo itself, whose env the shells source, and ~/.rustup read-only; cargo fetch --locked of osc-bridge passes in bwrap with these mounts alone); the plan of the envelope, of its lock and of the launcher reads the components of the module (composants) and the packages out of the frame, so that a plan naming a crate writes that crate alone; one point runs a command of the module when it describes it (scripts/commande-du-langage.mjs) and the test tool a writer may not run (droits); the integration and the queue play its preparer before the verification; the launcher plays its construire and the night its tests-de-nuit, when it describes them; the verification writes each red task with the command that replays it alone, which the night gives to git bisect run. The four scripts leave the rests of the join.
  • The script of the tests is named test:unit, for every language (grillhouse-pkl.2): the script of the tests and its task of Turborepo were named test:vitest, after the runner of one language, and the core named it: the circuit decided by it which package of a plan carries tests, and which red task of a run its failed tests already said; a project of Rust (grillhouse-pkl) would have carried a script named after Vitest. Decision 4 of the epic grillhouse-pkl, the owner's word of 2026-10-29: a neutral name, test:unit, without alias. The join gains joueDesTests(racine, composant), which the module typescript answers by the script test:unit of the component's package.json, and each task of a verdict says whether it plays the tests of its component (tests); the circuit asks them and names no script of the tests. The templates (templates/projet/package.json, templates/turbo/*.json), grillhouse tests, grillhouse verifier and the generator of the packages' turbo.json name test:unit. npx grillhouse maj rewrites a project's test:vitest (migration 0.25.0): in the package.json of its root and of each package of the frame, the command and its place kept, and in each turbo.json; a package that holds both with two commands is left to the project, named, the update failing, so that the former name never stays beside the new one; a second pass changes nothing. On BPScript, every package of the frame and its turbo.json are rewritten; its own tests that name the task (060-encoder/test/trace.test.ts) stay its own to change. A test of the frame finds no test:vitest in a package.json, a template or a document of the repository, out of the migrations and this changelog.

Fixed​

  • The tests of the frame's plugin play in the verification and the CI (grillhouse-3dr.3.5): claude plugin test mods/grillhouse gave 21 reds of 43 (pane.test.tsx, sections.test.tsx), « $.clock.every refused: result: not plain data: The object can not be cloned », and nothing played them: neither npm run verifier nor the CI ran the command. Two defects of the tests, not of the plugin: their hook stood for the clock with an answer holding a function ({ cancel }), which Claude Code 2.1.312 refuses, a clock.every resolving to nothing; and they recognized the board's process by node as its first word, which the plugin no longer runs since grillhouse-3uv.84.1 (node_modules/.bin/grillhouse tableau), so the pane drew an empty board. The tests now hold the clock with the kit's own, mock.clock, whose waits stay held until the test moves it, and recognize the board by its subcommand tableau: 43 green. The plugin's tests become the repository's own guards, its root script gardes (formerly mod:test), which npm run verifier and --gardes play beside the frame's, as the root task //#gardes of Turborepo, cached on the root's inputs: Grillhouse's turbo.json stays the template's, and the 43 tests take about 4 s. The CI installs the command claude at a fixed version (@anthropic-ai/claude-code@2.1.312) before the verification.
  • The tri of the discoveries reads its tickets and its commit (grillhouse-6ve): on BPScript (0.24.14), the three verdicts of the tri of bp-mono-vbwf.320.39 were non-confirmee, « Bash m'a été refusé (mode sans invite) : impossible de lire la découverte, le ticket parent, le commit 33b47e265 ni de rejouer la preuve sur main »: every discovery went up to the owner unchecked. Its journal shows one refusal, on the compound command cd /home/romi/dev/music/BPScript; for i in 1 2 3; do bd show bp-mono-vbwf.320.39.$i; done, which the rule Bash(bd show *) does not cover; the session did not try the simple form again. No rule read a commit (git show), and the instruction of the tri asked to replay the proof on main without naming the commands nor their form. As the help of a tool lists its commands, the explorateur's rights now read a commit of main, git show and git log, in the main tree and by git -C; the instruction of the tri lists the commands those rights permit, drawn from the role's rights (commandesPermises of droits.mjs, the template's {{commandes}}), and their form: one command per call, without cd nor chain, the session running in the main tree already, a refused command run again in its simple form. It also says that a piece file:line read on main suffices to an a-porter or a traitee, and that no test nor pass runs.
  • The commit-msg hook takes for a ticket only an id Beads knows (grillhouse-3dr.3.2.2): integrating grillhouse-3dr.3.2, the title « fix(grillhouse-essais): … (grillhouse-3dr.3.2) » was refused, « Le ticket grillhouse-essais a déjà son commit (02d9dd6, abd1f1b) »: the hook took every word <prefix>-… of the title line for a ticket, and in the frame's repository, whose prefix is grillhouse, the packages grillhouse-essais and grillhouse-matiere are such words; a commit naming its packages had to leave them out of its title. As Jira's smart commits and GitHub's « fixes #12 » link a commit to an existing key alone, a word of that shape now counts only when Beads knows it (bd show <id> --json lists a ticket of that exact id); a word Beads answers unknown is text. A known closed ticket named a second time is refused as before. When Beads does not answer, every word of the shape counts, as before, and the hook says so in one line.

[0.24.15] - 2026-10-29​

Fixed​

  • The journal of the tickets no longer replays the frame's tests (grillhouse-3dr.1): every verification of main played the frame's 3 200 tests (about 22 minutes) after any command of bd, its log saying « ↳ packages/grillhouse : tous ses tests, un chemin que ses tests déclarent lire (grillhouse.lit) (.beads/interactions.jsonl) »: grillhouse.lit named .beads whole, whose interactions.jsonl each command of bd rewrites, and the package's turbo.json hashed it for its test:vitest. As Bazel's data names a test's files one by one, grillhouse.lit now names under .beads the files the tests read, one by one: each file git follows there but the journals (*.jsonl) and the README, which git-des-tests.spec.ts reads for a setting of git's maintenance, the hooks of bd included. A change of the journal alone plays no test and leaves Turborepo's cache valid; a change of a hook or of the configuration of bd still plays every test. A change of a script of the package still plays every test, its tests running it by its path.
  • A plan out of the packages builds the copy as far as it builds (grillhouse-6q1): on BPScript bp-mono-vbwf.320.14.2.1, the title named libraries and spec, which are no packages of the frame; the launcher then built the copy whole by turbo run build, stopped on 990-corpus#build, red on the names the testwriter wrote for the developer (the red expected), and the developer's session never opened (code 10, « lancement »). A plan of packages already followed Bazel's --keep_going. The whole copy now builds as that plan does (--continue=dependencies-successful): a failure does not stop the launch, the session opens, and its instruction ends with the section « La construction échoue » (formerly « La construction de ton paquet échoue »), whose first line says which build failed, the plan's or the whole copy's, and what was built, then the end of the output. The graph of the whole copy is read dry first, as for a plan: Turborepo absent or its configuration refused is a preparation that fails, and, as a failed installation, still stops the launch, code 10.
  • One pass of the generator reaches its fixed point (grillhouse-kgx.3.2): on BPScript (ed70d6b86), after npx grillhouse maj to 0.24.14, grillhouse:gardes was red on the turbo.json of 140-scheduler, 150-renderer-audio, -midi, -osc and 995-tools, « diffère de ce que donnent les package.json », and a second npx grillhouse turbo-des-paquets --ecrire repaired them, each gaining build in its own typecheck. --ecrire wrote the packages' turbo.json first, from the root's tasks, then corrected the root (here its typecheck, which waited for ^build alone): a package whose task derives from a root task the same pass corrects was written from the old root. As make orders its targets by their prerequisites, --ecrire now corrects the root first, then writes the packages from it: one pass leaves a state the check accepts, and a second writes nothing.

[0.24.14] - 2026-10-28​

Fixed​

  • A declared read leaves the file in its owner's build (grillhouse-kgx.5): on BPScript (bp-mono-vbwf.320.21.4.3), 995-tools declared in grillhouse.lit the package.json and tsconfig*.json of the numbered packages its benches read; none holds code, so the generator wrote each as a data path left out of its own package's build (!package.json/**, !tsconfig.json/** beside the same files as inputs), and BPScript withdrew the 94 declarations: the benches of 995-tools no longer replayed on a change of them, for 27 packages of 31. As in Bazel, where a file may be srcs of one target and data of another, a reader's declaration no longer changes the owner's inputs: a declared file the owner's build reads by name (an entry of its inputs, else its package.json and tsconfig*.json) stays an input of that build, and the reader's tests keep it among theirs. A declared directory of data alone stays left out of its owner's build, as before.
  • The integration regenerates the references on main of the moment (grillhouse-kgx.2): on BPScript (bp-mono-vbwf.320.30, 0.24.13), the integration refused the lot twice at 5.1, code 17: its only conflict was on docs/agents/index-des-interfaces.md, which 320.26 had regenerated on main in the meantime, while the six other files applied; --reprendre replayed the same lot onto the same conflict, and BPScript lifted it by hand. The integration applied each lot by git apply --3way and regenerated nothing after. As a genrule of Bazel writes its output again on the merged tree, and npm install writes package-lock.json again after a merge, the integration now leaves out of the lot each file a reference writes in full (entiers: the index of the interfaces, the turbo.json of the packages), plays the reference that writes it in the integration copy, on main of the moment, after the install and before the verification, and commits what it writes. The circuit hands it its references (--references), its one list. A conflict on any other file still refuses the lot; so does a command that fails, or a file changed that no reference played writes. The API reports, which read the build, and the debt, which reads the notes of a pass, are applied as the rest of the lot.
  • The typing of each package, tests included, in the verification (grillhouse-kgx.3): on BPScript (bp-mono-vbwf.320.21.4), whose charter asks every commit to pass the strict typing, type errors in test/ showed only at night (110-timer for 10 days, then 060-encoder): npm run verifier played the guards and the tests, the build types src/ alone, Vitest types nothing, and typecheck was a script apart that no pass played; the guards' dependsOn, which the generator owns, refused a typing task a project added there. As the examples of create-turbo give each package a check-types task, cached per package, played beside the tests and the lint, npm run verifier now plays typecheck beside the guards and the tests (turbo run grillhouse:gardes gardes typecheck test:vitest …): a type error, in the sources or the tests, makes the pass red, its task named; a package whose files did not move reads its typing from Turborepo's cache; a package without a typecheck script plays none. The root's turbo.json holds the task typecheck, which waits, as test:vitest, for the build of its own package, whose built entry its tests may import (BPScript's 990-corpus imports 990-corpus/test-fixtures), and for the builds of its dependencies (build, ^build; build alone without packages): both templates of turbo.json and the frame's own hold it, and npx grillhouse turbo-des-paquets refuses a root without it, or whose dependsOn lacks one of those builds, --ecrire adding it, the rest of the task kept. The template of a project types its sources and its tests: its tsconfig.json includes src/, tests/ and the root's *.ts, nothing emitted, its typecheck is tsc -p tsconfig.json --noEmit, and its build is tsc -p tsconfig.build.json, the new configuration that emits src/ into dist/; tsconfig.eslint.json, which the lint read for the same scope, goes, the lint reading tsconfig.json. npx grillhouse maj gives the template's typecheck to each package of TypeScript (a tsconfig.json) that has none: each package of the frame in a project of packages, the root in a project without; a script of the project's own stays, a package out of the frame is not touched, and the report names the packages.
  • After a refusal of the integration, the developer receives the refusal, and rien-a-livrer no longer settles it (grillhouse-kgx.4): on BPScript bp-mono-vbwf.320.37 (0.24.13), the integration refused the lot (the tests of 060-encoder, 070-deriver, 090-ranker, 110-timer and 990-corpus red in the integration copy, absolute paths in the fingerprint of a trace) while the checks of the ticket's copy were green. Relaunched with --depuis developpeur --contexte <the defect>, the developer said FAIT without changing a file; the gesture rien-a-livrer sent the lot to the checks of the copy, green, and back to the integration, red again: three times on the same lot. The refusal reached the session only as the free text of --contexte. As a merge queue (GitHub merge queue, bors, Zuul) sends a lot back to its author with the log of the integration's check and lets it pass again only with a change, the circuit now keeps the refusal in its state (refus: its output, its piece, the fingerprint of the lot refused); a --depuis developpeur after a stop « integration » starts at the developer, the refusal as his report, the red to lift. A developer session so launched that changes no file of the lot refused does not go through rien-a-livrer: the circuit relaunches him once with the refusal, then stops at « sans-livraison », the refusal as its piece. As bors retries a lot, --reprendre after a stop « integration » still plays the integration, or the queue, again on the same lot (a refusal can come from the load or from main: BPScript 320.16 and 320.16.2 entered so); a --depuis testwriter makes the lot again and drops the refusal.
  • The testwriter inscribes what his tests import, and the sending to him carries the red of the checks (grillhouse-kgx.1): on BPScript bp-mono-vbwf.320.37 (0.24.13), the testwriter's lot made packages/060-encoder/test/publier-les-grammaires.ts import two new names of the shared test material (GRAMMARS_INPUTS, writeTraceFingerprint); the guard « consommateurs » refused the lot, the line of 060-encoder in the « Consommateurs » of 990-corpus/docs/INTERFACE.md not naming them, and that file is the testwriter's alone. His skill only read that section; the first sending to him came before any check and could not name the line, and the second, after checks that named it word for word, stopped at « sans-livraison », since a sending carried only the sheet and the handover. As who adds a dependency declares it in the same change (Bazel's BUILD, npm's package.json), and a CI hands back the log of the check that fails, the testwriter's skill and the first template of instruction now have him inscribe, in the same lot, each name of the shared test material his tests start to import, on their package's line of the provider's « Consommateurs »; and a sending to the testwriter carries, after the sheet and the handover, « La sortie rouge des derniers contrôles », the text the developer received, when checks ran red since the testwriter's session. The stop on a second sending in a row now holds only for a round trip without a new fact: a sending whose red output of the checks differs from the one before (none before any check, then the guard's line) relaunches the testwriter, and only the same output twice in a row, without green checks between, stops at « sans-livraison ». That output is written in the state of the circuit (controlesRouges), so that --reprendre and --depuis keep it.

[0.24.13] - 2026-10-28​

Fixed​

  • The night as the crontab runs it: the former line named, the line proposed that runs, its help (grillhouse-w47.1): on BPScript (bp-mono-vbwf.320.21), the night had stopped since 2026-10-25. The crontab still launched bash <root>/scripts/nuit.sh, absent since the frame became a package (0.24.0), and MAILTO="" kept the failure silent; the session start looked for its own line alone and said « La nuit n'est pas programmée », without naming the line that aimed at the missing script; the line it proposed did not carry Node's path, which #!/usr/bin/env node does not find under the crontab when nvm installed it; and grillhouse nuit --help launched the night. As brew doctor and npm doctor name a configuration that aims at a missing path with the command that repairs it, the session start now says « La nuit ne tourne plus » for a line of the crontab that launches a nuit.sh absent under the root (absolute, or relative after cd <root>), with that line and the one that replaces it. The line it proposes is 0 3 * * * export PATH=<Node's directory>:$PATH; cd <root> && node_modules/.bin/grillhouse nuit, the directory of the Node that runs the session start; a line that runs cd <root> && node_modules/.bin/grillhouse nuit and sets PATH=<that directory>: counts as programmed, and the former line without it no longer does. As a GNU command, grillhouse nuit answers --help (or -h) by its usage, exit 0, and refuses any other argument, exit 2, without launching the night. The skill grill writes the line in the session start's form.
  • The developer answers each finding open for him, and the reviewer receives the answer (grillhouse-w47.3): on BPScript bp-mono-vbwf.320.21 (0.24.12), the developer wrote why he kept his choice in his handover of 18:34; the circuit reads sheets, never a handover, and the reviewer's instruction carried the findings without any answer, so the reviewer wrote « la relecture n'a reçu aucune fiche du développeur »: three RENDU, then the stop at « relecture-arret ». As the author answers in each thread of a review on GitHub or Gerrit, and the reviewer reads the thread with the new patch set, a sheet FAIT of the developer now carries reponses, one per finding of the reviewer open for him, by its title: levé with its piece, or contesté with its reason and its piece; the circuit refuses a sheet without the answer to one (or a contesté without its reason), and asks it again once of the same session, naming the finding. The circuit keeps each answer with its finding, and the next review's instruction carries it under that finding (« Réponse du développeur », « Pièce de la réponse »). A sheet BLOQUÉ or BESOIN, and a sheet with no finding open, read as before.
  • The night plays each step and names each red task (grillhouse-w47.2): on BPScript (bp-mono-vbwf.320.21, the night stopped since 2026-10-25), the night stopped at its first red step: a red full pass ended it before the benches, a red bench before the project's night script, so the type check of npm run nuit:projet did not run the nights a bench failed (bp-mono-vbwf.320.21.5); every red commented the open night ticket whatever its task, so the 11 TS2739 errors of 110-timer (nights of 17, 21 and 22 October) stayed under a ticket open on another defect (bp-mono-si61); the red tasks were listed only with a last green, which BPScript never had; and the text showed the last 40 lines of the log, the build's noise. As a CI plays each independent job and an alerting system groups by fingerprint, the night now plays the full pass, the night tests and the project's script even when a step before is red, and is red when one of them is; « à repasser » keeps its rule. Its text names each red step and each red task (those GRILLHOUSE_ROUGES gives, else the full pass, the night tests or the project's script by its command, or the preparation), with or without a last green; the bisect command stays for a task of the full pass with a last green. Each red task comments the open night ticket whose title names it, « », once per ticket, or opens its own, « La nuit est rouge sur « » depuis la nuit du »; a refused push does the same with « origin/ ».

[0.24.12] - 2026-10-27​

Added​

  • The triage of the discoveries at the end of a ticket (grillhouse-0yu.5): the circuit filed each discovery of a sheet as a closed ticket labelled decouverte, and the supervisor's skill said he carried to the owner those that touch a real use; nothing held it. BPScript counted 161 discoveries since 2026-10-12, all closed, none read one by one; on bp-mono-vbwf.320.17 (0.24.11), 9 discoveries, three of which said the same « critère 10 non fait », one a real defect. As Chromium and Mozilla give each new report a verdict before it is filed, the circuit now ends on a step 5.3 « Tri des découvertes » (decided by Romain, 2026-10-27): once the queue has brought the lot onto main, the explorateur, on Sonnet, out of the envelope, in the main tree, with the rights of reading (it may build a package, npm run build -- --filter=<paquet>..., before judging an error of types of its export; no pass, no write), sorts the discoveries the sheets of the ticket filed; a ticket without one passes with no session. Its sheet (tri) gives one line per discovery, no more, no less, each with its verdict: traitee, doublon, sans-suite, a-porter or non-confirmee; the piece of a traitee or an a-porter is a command played again on main and its output, or file:line, without which the sheet is refused and asked again once. Each verdict is written at its discovery's ticket and set there as a label; an a-porter or a non-confirmee (with what lacks to settle it) reopens under a-valider, in the pane's list « à valider »; the others stay closed. A triage without a conforming sheet leaves the discoveries as they are and says so at the ticket, without undoing the integration; its line at the ticket names each writing that failed (a verdict, a label, a reopening). Its instruction names the commit the queue integrated for the ticket, read in the reason of the ticket's closure (intégré : <commit>), not main's last. The bilan counts its session and its verdicts. The migration 0.24.12 « tri des découvertes » of grillhouse maj replaces, in a project's own docs/agents/issue-tracker.md, the two sentences of the former rule (« it reopens on the owner's word », and the supervisor bringing the discoveries to the owner) by the rule of the triage, when they are present, and touches nothing else. The common charter, the explorateur's skill, the supervisor's, the eighth template of instruction, docs/agents/issue-tracker.md and the architecture say so. Past discoveries are not sorted by the frame (BPScript sorts its own).

Fixed​

  • A piece may cite the criterion or the section of the ticket (grillhouse-0yu.4): on BPScript bp-mono-vbwf.320.17 (0.24.11), three sheets of the questionneur out of four were refused for a piece that cites the ticket (« Plan, « Ce qui change » : … », « Ticket, critères 1 et 7, et Q1 amendée … », « n'est pas une pièce »): the proposal it questions has no file nor line. As a review of a specification cites its section (« RFC 9110 § 15.5 »), a piece may now be ticket, critère <N> or ticket, § <section> (in « » or up to « : »), then what it shows; the circuit gives the sheet's reading the description of the ticket, and such a piece is accepted when the description carries that criterion (a numbered line of its section of criteria) or that section (by its title or its beginning), else refused, naming what lacks. The forms of today (fichier:ligne, $ commande and its output) stay as they are.
  • The reviewer writes his line on any file the lot changes (grillhouse-0yu.2): on BPScript bp-mono-vbwf.320.17 (0.24.11), the reviewer's first sheet was refused for its lines on packages/000-forms/docs/INTERFACE.md#OBJECT_NUMBER, an INTERFACE.api.md, docs/agents/index-des-interfaces.md, packages/080-aligner/docs/CADRE.md#R13, an ARCHITECTURE.md and packages/995-tools/src/mots-de-librairie-plafond.txt, « n'est pas un élément du lot », though the commit changes each of them; the list of the lot kept the sources alone, and a line was accepted only on an element or a source out of the language service. One Opus session of the reviewer was played again. As a review on GitHub or Gerrit accepts a comment on any line of any changed file, the list of the lot now names every file the lot changes (fichiers), and a line on any of them, alone or as <fichier>#<nom>, is accepted; a line on a file the lot does not change is still refused, each element without its line is still a fault, and a changed document asks no line.
  • A criterion the developer does not hold out of the plan goes up at 3 Code (grillhouse-0yu.1): on BPScript bp-mono-vbwf.320.17 (0.24.11), the developer's sheet said FAIT three times while his handover said « garde de constantes d'objet (995-tools, critère 10) hors plan, non fait »; the circuit does not read a handover, so nothing went up, and the criterion fell at the review (4.3, « relecture-arret »), after 25 min of final passes. As a required check of a CI keeps a merge from a change that does not pass it, the developer's sheet now carries hors_plan, each criterion he does not hold for want of a package out of the plan, with its number, that package and its piece; a FAIT that carries one stops at 3 Code at « hors-portee », the question naming each criterion and its package, and the supervisor answers by --etendre <paquet> or amends the criterion and --reprendre. A sheet without it, or with it empty, reads as before.

[0.24.11] - 2026-10-27​

Fixed​

  • A warning of a guard is not a red (grillhouse-v98.1): on BPScript bp-mono-vbwf.320.17 (0.24.10), the guard of the library words wrote one finding of level error, on the ceiling the lot lowers (packages/995-tools/src/mots-de-librairie-plafond.txt:17, 110-timer 41 < 44, a file the reference « plafond des mots de librairie » covers), and 8 of level warning, words already present on lines the lot touches in 080-aligner and 110-timer; the circuit made a red of every finding whatever its level, gave the 8 warnings to the developer as « Tes rouges », who had nothing to deliver, and stopped at 3 Code, « sans-livraison » (15). As SARIF 2.1.0 and GitHub code scanning, where error fails and warning and note show without failing, only a finding of level error (the frame's default) is now a red, at the checks of the plan as at the final pass; the warnings and notes stay visible in the report of the checks, apart, under « Les avertissements », given to no developer; and a red that is a reference's alone goes to its regeneration whatever warnings stand beside it. A guards' task red without any finding of level error keeps its line of a red task, with its log.

[0.24.10] - 2026-10-27​

Fixed​

  • The writing of a guard's findings in SARIF has its public address (grillhouse-u4s.2): on bp-mono-vbwf.320.10, BPScript opened its ticket so that its guards write their SARIF, without which none of their reds is situated (decided by Romain, « A »), and stopped: the package's architecture told a project's guard to write by ecrireSarif of packages/grillhouse/scripts/resultats.mjs, a path a project reaches only deep in node_modules, which its charter refuses, and no entry of the package's exports led there. As eslint/use-at-your-own-risk publishes ESLint's tools, and as the package already publishes trancher, matieres and horsCadre, its exports now carry @roomi-fields/grillhouse/resultats, pointing at scripts/resultats.mjs, with its declaration of types beside it (scripts/resultats.d.ts), which declares ecrireSarif alone. The test of the named entries imports it in a project of trial by the package's name, writes a finding, and reads it back with its file and its line. A project's guard writes its findings by import { ecrireSarif } from '@roomi-fields/grillhouse/resultats'.

[0.24.9] - 2026-10-27​

Fixed​

  • A refusal that aims at the code of the plan goes to the developer, not to the regeneration (grillhouse-u4s.1): on BPScript bp-mono-vbwf.320.10 (0.24.8), the developer wrote the library word « door » in packages/030-binder/src/suffixes.ts, a package of the plan; the project's guard « un mot de librairie écrit dans le code » refused it from 3.1 on, each line with its file, yet none of the three « Tes rouges » reports named it, and the final pass ran the regeneration of the ceiling of the words, whose command refuses to raise it (« le plafond ne monte pas : 030-binder 86 > 83 », code 1), and stopped at « references » (23). The circuit counted every finding of a guard a reference names as that reference's, whatever file it aims at. As --update-snapshots and rustc --bless rewrite only the outputs the lot changed and leave every other failure to its owner, a finding of a guard of a project's reference on a file of the plan its files do not cover is now the developer's, at the checks of the plan as at the final pass; its finding without a file, or on a file it covers, stays the regeneration's, and the frame's references keep their sorting by guard. And when, at the final pass, a project's reference command refuses (no real failure) while the pass carries reds of the plan, the copy is restored and those reds go to the developer with the end of the command's output, within his sessions; without a red of the plan the stop « references » is unchanged. BPScript's guards write no SARIF, so none of their reds is situated: their refusal is one red of the task //#gardes, without a file, and the first rule does not reach it. In 320.10 the second rule sends the developer the command's refusal, which names the package beyond its ceiling, only because that final pass also carried other reds of the plan (findings of the frame's guard resumes on 000-forms, 020-loader and 040-checker); a final pass whose only reds are the guards' and the reference's tests would still stop at « references ».

[0.24.8] - 2026-10-27​

Fixed​

  • Each role reads the files of its own skill (grillhouse-9jr.2): on BPScript bp-mono-vbwf.328, the reviewer was refused Read on its skill's references/edge-case-hunter.md and verification-gap.md, and ls of that folder, files its skill tells it to follow to the letter: they live in the frame's installed plugin, out of the ticket's copy, and its rights gave no reading there. As Claude Code gives a session the reading of its folders of work (--add-dir), the rights of every role the circuit launches now carry a rule Read on its own skill's folder in the frame's plugin, as installed for the copy, else for the project, and for a role whose skill names it (the reviewer, the explorateur, the testwriter, the developpeur) a rule Read on the plugin's METACADRE.md alone; measured on Claude Code in dontAsk, they let Read and ls of those folders through, and neither the skill of another role, the rest of the plugin, nor any writing. A rule Read rather than a folder of work, which would open the whole plugin: narrower.
  • Each open question of the plan says why it goes up (grillhouse-9jr.3): on BPScript bp-mono-vbwf.328, the plan stopped at « questionnement » on the explorateur's open question « Faut-il un seuil ? (a) aucun, comme le ticket le dit ; … Recommandation : (a) », which the ticket already settled. The rule « an agent who has the answer applies it » was text only: the schema of an open question did not ask why it went up. As a structured output holds its form by its schema, each open question of the explorateur's sheet now carries a required motif: langage, architecture or écart à la référence (what is the owner's), or sans réponse. A sheet whose question lacks it, or carries another value, is refused and asked again once of the same session with the reason; the question that goes up to the supervisor, at the ticket and in the stop, shows its motif.
  • The reviewer names the elements of a file out of the language service (grillhouse-9jr.1): on BPScript bp-mono-vbwf.328, the circuit stopped at 4.3, « sans-fiche » (code 12): the instruction told the reviewer to survey himself the elements of packages/995-tools/src/verif-mots-de-librairie.mjs, which no tsconfig.json reads, and he returned ACCEPTÉ twice, his lines naming …mjs#juger, then the file alone; conformiteDuLot refused any line whose element was not in the list, so no form could pass for such a file. As a code review accepts a comment on any line of the diff, conformiteDuLot now receives the files out of the service too, and accepts a line on one of them, <fichier>#<nom> or the file alone; the instruction and the reviewer's skill say that form. A line on an element out of the lot and out of these files is still refused.
  • A package of the plan that provides another no longer stops the launch (grillhouse-9jr.4): on BPScript 320.10 (0.24.7), the plan held 990-corpus, the shared test material, whose build the testwriter's calls to a new signature left red until the developer's code (TS2345), the red expected. The tests of the plan's stages wait for the trace of 060-encoder, out of the plan, and that trace waits for 990-corpus's build: the step of the other packages' traces built 990-corpus, its failure stopped the launch (code 10, « lancement »), and the developer's session never opened. As Bazel under --keep_going builds every target whose dependencies succeed, a target of the plan staying one even as another's dependency, a provider's build or another package's trace that waits, directly or not, for a package of the plan is no longer played among the providers: it goes with the plan's own build, whose failure opens the session with « La construction de ton paquet échoue ». A provider out of the plan that fails on its own still stops the launch.
  • The explorateur answers each question put, or is asked again once (grillhouse-9jr.5): on BPScript bp-mono-vbwf.320.10, the stop « questionnement » came back with its 4 questions « question du questionneur, sans réponse », though the explorateur had answered them by adding the criteria 10 to 15: its second sheet carried no reponses, the circuit counts a question without its line as unanswered, and the sheet's validation never asked one line by question. As a structured output is validated and its error sent back to the same conversation (as the reviewer gives a line to each element of its lot), the explorateur's answer now needs one line of reponses by question put; without it the sheet is refused and asked again once of the same session, the numbers that lack named. Only after that resumption does a question without its line stay open.

[0.24.7] - 2026-10-26​

Fixed​

  • A resumed session's refused sheet is asked again of that same session (grillhouse-982.1): on BPScript 320.3.9, a resumed developer returned a right BESOIN whose $ command piece carried a « \n » written in two characters; lirePiece required a real line break and refused the sheet, and the circuit, on a resumption, launched a fresh and whole session whose instruction did not carry the question. That session declared alone what the question asked to arbitrate, the checks went red on it, and the question reached the supervisor 10 minutes later (4.3 min, 0.24 $ lost). As a validator of structured outputs sends its error back to the same conversation, a resumed session's sheet refused is now asked again once of that same session with the reason, as for a fresh one; only a resumption that ends in error falls back on a fresh session. A command piece written on one line, its output after a « \n » in two characters, reads as after a line break.
  • The bilan measures a relaunch without effect and the owner's wait on recorded facts (grillhouse-982.3): on BPScript 320.3.9, the developpeur session f67f2b9a (5.2 min, 1.24 $) corrected libraryWriting, which the commit delivers, yet the bilan counted it « relance sans effet » because the circuit followed it with a stop « sans-livraison » (his second sending to the testwriter); and the first stop's 0.9 min went to the owner because the supervisor wrote at the ticket a comment titled « ## Réponse du responsable » that quoted a « oui » given before the launch, while the owner wrote nothing during the circuit. As ccusage measures from what the transcripts and the register record, not from a title written: a developpeur is without effect only when his session changes no file of the plan (inchange, which the circuit now also keeps on that second sending), whatever stop follows him; each stop names the supervisor's session that ran the circuit (montee.superviseur, from CLAUDE_CODE_SESSION_ID, in place of montee.qui), and a wait is the owner's only when he writes in that session during it (a message whose origin is the person). The bilan reads no comment of the ticket any more.
  • A red of a reference the checks of the plan see is regenerated before the final pass (grillhouse-982.2): on BPScript 320.3.9, the checks at 09:25:58 saw 995-tools red on the ceiling of the words, a reference the regeneration (4.2) writes again; the circuit left it to the final pass, which played 000-forms, 050-emitter and 995-tools again on the same tree (6.1 min), found the same red, regenerated, then replayed 995-tools. As make remakes a generated file before what reads it and plays no target whose inputs did not change, checks green but for reds of references now call for their regeneration at once (the gesture regeneration); the final pass that is due then plays once, on the regenerated tree, and does not regenerate again a reference just regenerated on that same tree, whose red goes to its owner.
  • The update ends with the verification that keeps the last green (grillhouse-982.6): on BPScript 320.3.9, the full pass of the ticket measured 26 files since main's last green, 11 of which main had received without a green (the updates 0.24.5 and 0.24.6, committed on main without npm run verifier): about 12 minutes played again for changes that were not the ticket's. The last green is written only at the end of a green npm run verifier. As Nx affected moves its base to the last green commit of main, grillhouse maj now ends with npm run verifier in the project: its green keeps the tree the update leaves, so that once those changes are committed as they stand, a copy that starts from that commit measures nothing changed; the update exits with the verification's code, and the report's last line says the green kept, or why not (red with its code, « à repasser », or not played: work the update leaves to do, no verifier script, npm install first). The session start and the grill's skill, which send an agent to npx grillhouse maj, say that it ends with that long pass, to run in the background and its code read at the end.

Changed​

  • The reviewer blocks only on what the lot adds: what stood before the lot, even on a line it touches, is a remark, as a guard reports an existing finding without refusing it. On BPScript 320.3.9, a word of the language already on a touched line, which the guard only reported, was made blocking and cost about 16 minutes.

Fixed​

  • The update brings the frame's plugin to the package's version (grillhouse-982.4): on BPScript 320.3.9, the package was at 0.24.6 while the plugin installed for the project (the mod and the agents' skills) had stayed at 0.24.3 (~/.claude/plugins/installed_plugins.json), without a signal the agents could see: grillhouse maj installed an absent plugin and never updated a present one, and the gap was said only at a supervisor's session start. As npm install brings what is installed to what is declared, the installation of the plugins (grillhouse maj, grillhouse init) now updates the frame's mod installed for the project behind the package (claude plugin update grillhouse@roomi-fields --scope <its scope>, from the project's root) and reads it again; a mod left at another version (a failed update, a source without the package's version, a mod ahead of the package) has its line with both versions and the command to type, and the exit code is non-zero. The session start still names the gap, BPScript's case included.
  • The guard of the consumers reads the uses of the shared test material in the tests of its consumers (grillhouse-mo7): at 0.24.6, once its 17 lines were rewritten, BPScript's 990-corpus saw 176 names refused as declare-non-utilise, which it inscribed as debt. The guard read only production code, and a package of the material (it exports ./test-fixtures) has, by the rule that keeps tests out of the code, only tests for readers (packages/010-parser/test/corpus.ts imports 990-corpus/test-fixtures, no src/ does), so every name declared for it came out unused. As knip counts test files as entries out of its --production mode, the guard now reads, for a package of the material only, the tests of each consumer too (folders test/, tests/, __tests__/, files *.test.*, *.spec.*): a name a test imports, statically or by a destructured dynamic import, is used, and one the interface does not declare is refused (usage-non-declare), as for production code. For any other provider the tests still do not count. Replayed on BPScript, the 176 fall to 4, and 33 uses come out undeclared; the migration of 0.24.7 (« matière de test lue dans les tests ») names, after grillhouse maj, each such use beyond the debt and the command that inscribes them (npm run grillhouse:dette:inscrire).
  • A role that writes may not run Turborepo directly (grillhouse-982.5): on BPScript 320.3.9, a developer played npx turbo run test:vitest --filter=… (79 s) without a refusal, as the rights refused only Vitest under its forms, while the charter says no agent runs the test tool directly. Turborepo plays the test tool too, so its direct forms (turbo, npx turbo, npm exec turbo, node_modules/.bin/turbo) are refused as Vitest's are; npm test, npm run test:forcer and npm run verifier stay open.

[0.24.6] - 2026-10-26​

Fixed​

  • The guard of the consumers reads the names of a destructured dynamic import, and refuses a line of prose in a ## Consommateurs section (grillhouse-wwr): at 0.24.5, BPScript's 995-tools saw 6 names refused as declare-non-utilise that its code reads. A literal import('x') or require('x') gave the single name *, which covers no declared name, so const { a } = await import('x') refused a. As knip reads const { a, b } = await import('x') as a use of a and b, the guard now takes the names a literal dynamic import destructures as a static import's (a rest element or default gives *, as import X from 'p'); one not destructured keeps *, and a loader whose specifier is computed (createRequire(...).resolve(nom) then import(url), 995-tools/src/empreinte-v2.mjs:56) stays unread, as TypeScript types only a literal import(): the project writes import('900-driver') plainly (decided by Romain). The text after « : » of a line was cut at its commas, and a bullet of prose gave « names » that are none (990-corpus/docs/INTERFACE.md:289), or was passed over without « : » (990-corpus/docs/INTERFACE.md:274-288). One form stays for every bullet of the section, out of its generated part, - `consommateur` : nom, nom, each name a JavaScript identifier or *: a bullet of another form, with or without « : », is refused under the rule ligne-mal-formee, naming the file and the line and saying to write it as a list of names, and gives no name; a paragraph out of a bullet (« Aucun paquet de la v2. ») is no consumer and passes. One reading of such a line, lireLigne of consommateurs.mjs, serves this guard and consommateurs-arbitres.mjs, whose own copy is gone. The migration of 0.24.6 (« lignes de consommateurs mal formées ») names, after grillhouse maj, each such line beyond the debt and the command that inscribes them (npm run grillhouse:dette:inscrire), as the migration of 0.24.4 names its unused names.

[0.24.5] - 2026-10-25​

Fixed​

  • A file git does not track in main's last green is not removed from a new copy (grillhouse-5m1.4): on BPScript bp-mono-vbwf.320.3.2.1 (Grillhouse 0.24.3), main's last green held 54 .rapport-suite.json, untracked and not ignored, dated 12 October (an old name of report no script writes any more), absent from every new copy. Each package of the copy saw « un fichier supprimé, que le graphe des tests ne tient plus » and played all its tests, 264 times in the log; the first final pass took 12.9 min, of which 900-driver (597 s, a package the lot does not touch) and 050-emitter (335 s). As Nx affected and Turborepo's --filter=[ref] measure against a commit, a file the green's commit does not track lives in the working tree that kept it alone: measured against the last green of another branch (main's, from a copy or the queue's detached replay), its absence is no removal, and the package plays the tests Vitest relates to its changes. A tracked file removed in the copy still plays the package whole, and so does an untracked file the copy created, kept in its own green, then removed.
  • A document of a package plays none of its dependents' tests (grillhouse-5m1.5): on BPScript bp-mono-vbwf.320.8 (Grillhouse 0.24.3), a change of packages/000-forms/docs/INTERFACE.md played 900-driver (6 min 25 s) and 995-tools (5 min 15 s) whole (« tous ses tests, le code d’un paquet dont il dépend, que ses tests lisent construit (packages/000-forms/docs/INTERFACE.md) »), two packages that weigh 31.8 and 21.3 min of the 76.7 min of checks of 320.8: the rule took any file of a package it depends on but its tests. As Turborepo hashes the inputs of a neighbour's build task and Bazel the srcs of its target, the rule now takes a file, changed or removed, only when the neighbour's build reads it: the inputs of the build of its generated turbo.json read as Turborepo reads them (src/**, package.json, tsconfig.build.json… for 000-forms; $TURBO_DEFAULT$ every file of the package, $TURBO_EXTENDS$ the root's inputs, <x>/** covering <x>), or, when they name none, its files of code and configuration out of its docs/; a test is never one. A document renamed or a test removed in a neighbour (BPScript d09c7dbef, 2e2fbf644) no longer plays its dependents whole either; a file removed in the package itself still does. Replayed on the change of 320.8, 900-driver and 995-tools play only the tests Vitest relates to it.

[0.24.4] - 2026-10-25​

Fixed​

  • The guard of the consumers refuses a declared name its consumer no longer uses, and the circuit refuses to start or resume a ticket labelled arbitrage without its arbitrage (grillhouse-5m1.2): on BPScript bp-mono-vbwf.320.3.2.1 (Grillhouse 0.24.3), the guard only reported « packages/000-forms/docs/INTERFACE.md déclare « LEVEL_TYPES » pour 020-loader, qu'aucun code de 020-loader n'utilise » (11:54:57), and the second review caught it 37 min later (4.8 min, 0.78 $). As ESLint's no-unused-vars refuses a name nothing uses, the guard now refuses it, under the rule declare-non-utilise, and in a ticket it says to take the name out of its line. The names a project already holds are its known debt, inscribed once, at the passage of the rule: the migration of 0.24.4 (« noms déclarés inutilisés ») names, after grillhouse maj, each line the new rule refuses and the command that inscribes them in grillhouse-dette.json (npm run grillhouse:dette:inscrire), so that BPScript's main (26 names on 11 lines of 4 interfaces) does not turn red without a word. The same ticket carried the label arbitrage from its launch (11:37:05), and the integration refused it for want of an « Arbitrage » comment only after three reviews (12:36:31). As a CI refuses a pull request without its required label before it runs a job, the rule of the label stays one, refusArbitrage of integrer.mjs, and the circuit plays it at its launch and at each resumption, before any session: a refusal stops at « besoin », a question to the supervisor.
  • The bilan counts the loss of a ticket as measured, against a base computed again (grillhouse-5m1.1): on BPScript bp-mono-vbwf.320.3.2.1 (Grillhouse 0.24.3), the bilan said 34 % lost where the inspection measured 8.5 %. A session the circuit resumes (claude --resume) writes its queue operations and a message of no model (« No response requested. ») at the time of the resumption, before its incoming message; the reading of a transcript gave them to the turn before, so the first turn of the testwriter 25adfcd3 ended at 11:46:29 instead of 11:45:02, after the start of its proof, and the bilan took the next proof for its own and put 4.0 + 1.6 min of real work (25adfcd3, 0374e709) in « relance sans effet ». As ccusage cuts a transcript, a turn now starts at its incoming message, and those events bound no turn; read again from the transcripts of 320.3.2.1, both first turns count as work. The pass restricted to what a regeneration changed (12:10:03, 5.8 min) was counted without effect, the rule comparing its outcome (red, then red) and not its reds, another red (the index of the interfaces); the circuit now keeps the reds of each check with its outcome, its stop included (resultat.rouges), and checks play the same thing again only when outcome and reds are the same. The bilan compared itself with the bilan kept for 320.8 by an earlier version (« séances 0 → 10, coût 0,00 → 4,38 $ »); as a bench of time remakes its base, it now computes the bilan of the latest other ticket kept again from its sources, by the version that compares (« Face au bilan de …, recalculé »), and compares with nothing when they give none. The log of a ticket mixed two time zones, the sessions' headers in local time (date -Iseconds), the steps' in UTC; every header now says the local time with its offset, as ISO 8601 writes it.
  • The regeneration remakes what depends on it, regenerates a reference the plan does not name and says its deviations; the proof reads an expected green named with « > » or « › » (grillhouse-j2m): on BPScript 320.3.2.1 (Grillhouse 0.24.3), the regeneration of the API reports rewrote the generated part of packages/000-forms/docs/INTERFACE.md alone (12:09:52); the index of the interfaces, which reads it, fell out of date, the restricted pass reddened and the circuit stopped (« controles », « Aucun paquet du plan… ne tient ce rouge »). As make remakes a target with the targets that depend on its outputs, each reference now declares what it reads of another (lit, the index the docs/INTERFACE.md), and a command that writes a file another reads has it run after it, in the same regeneration; replayed, the pass that follows is green. The regeneration stopped (23, 12:08:52) on the ceiling of the words lowered from 546 to 542 because the plan named neither the ceiling nor its file, a mechanical gesture already met on 320.8: as a genrule is written again without a request, a reference of the project the lot changes is regenerated without a word of the plan, the reviewer reading its difference, and the requirement and its stop are gone. A stop of the regeneration (a command that fails, a file no reference writes) now carries its list of deviations in its question and in the comment at the ticket, which the supervisor found again in three commands. The first proof was refused (« 7 vert(s) sans vert attendu », 11:46:07) though the sheet named each green, as « the order of the cascade the library declares › critère 3 : … », where the report wrote the full name with a blank: the proof now reads the full name of an expected green whatever the separator between its group and its test, « > » as Vitest prints it, « › » as Jest and the report print it.

[0.24.3] - 2026-10-25​

Fixed​

  • The bilan counts every session at its cost, and puts the owner's answer to his wait (grillhouse-ybq.1): on BPScript 320.8 (625c8ca12, Grillhouse 0.24.2), the bilan wrote « 0 séances ; 0,00 $ ; 0,00 M jetons » for 25 sessions and 20,36 $, and « 67 % perdus » with them. The register writes each role as Claude Code names a plugin's agent, grillhouse:developpeur, and the bilan kept a line only for a bare role; it now reads a role as the board does, by one function (roleDeLAgent, moved to etapes.mjs). Replayed on the register of 320.8, it counts 25 sessions and 20,36 $. The circuit writes the supervisor as who must answer every stop but the reviewer's question, so the 78 min Romain took to answer criterion 5 counted as the supervisor's wait; as the supervisor writes the owner's answer at the ticket under « ## Réponse du responsable — » (skill pitmaster), the bilan reads the ticket's comments (bd comments <ticket> --json) and counts a wait during which that answer is written as the owner's, the title being the only text of a comment it reads, recognised as the integration recognises it (estReponseDuResponsable, consommateurs-arbitres.mjs). The register wrote cout: 0 for the supervisor's questionneur (78 083 tokens), as a sub-agent's transcript holds no total: as ccusage keeps the total Claude Code writes and reckons only in its absence, the register keeps that total, and prices a session without one, or with a total of 0 for tokens spent, on its tokens at its model's tariff (TARIFS, Sonnet 5.5, Opus 5.5, Haiku 4.5, a write of the cache by its duration); on 320.8 the tariff gives each of the 25 totals to the thousandth, and 0,29 $ for that questionneur, whose cache writes are of five minutes.
  • The plan accounts for each component of its survey, is played again only when its title or criteria change, and --etendre resumes the role a sending names (grillhouse-ybq.3): on BPScript 320.8 (Grillhouse 0.24.2), the supervisor wrote the names the testwriter asked for in a section of the description, and the whole plan was played again (explorateur, questionneur, answer: 2.9 min, 0.45 $), because the plan's fingerprint covered the whole description; it now covers the title and the section of criteria, as a CI replays a job only when its inputs move. The explorateur's survey named 001-kernel, 990-corpus and 995-tools, its packages none of them: two stops (« controles » on the final pass, « sans-livraison » on 990-corpus) and a final pass played again. As the section of affected components of a design document says of each whether it changes or why it stays, the circuit now plays the survey of composants-affectes on the plan's description itself, with no session, as it checks the packages; a component of the survey the sheet neither puts in its packages nor sets apart with its reason (ecartes, written at the ticket) makes the sheet out of conformity, resumed once, with no question to the supervisor. A component with nothing to change (850-mercury) is set apart, not forced into the plan. After the stop on the developpeur's second sending to the testwriter, --etendre 990-corpus relaunched the developpeur, who stopped again in 17 s; it now resumes at the testwriter, the sending as his report.
  • The testwriter and the developpeur know that 4.2 regenerates the references, and the circuit outlives the session that launches it (grillhouse-ybq.4): in BPScript 320.8 (625c8ca12, 0.24.2), a developpeur, code and tests green, stopped on the ceiling of the words, the frozen debt and the index of the interfaces (sheet of 17:36:12), three files the step 4.2 regenerated itself afterwards; and the circuit, a background command of the supervisor's session, died with it (« Background shell command didn't finish before the previous session ended », 17:10:43), resumed by hand. The instruction of the testwriter and of the developpeur now lists the references the circuit regenerates, the project's and the frame's, each with its files, and their skills say that no session stops on them. As daemon(3) and setsid --fork make a daemon, npx grillhouse circuit now launches the run through a relay that ends at once, so that the run is neither in the caller's process group nor under it in the tree of processes: the caller relays its output to its last line and ends on its code while it lives, and its death leaves the run going to its end. The state names the run by its number and its start (processus, depart, field 22 of /proc/<pid>/stat), as a service manager checks that a reused number names no other process: the board holds a circuit running on that process alone, no longer on the command line grillhouse circuit <ticket>, which the daemon does not carry; a second run of a ticket whose circuit still lives is refused (exit 2), and --arreter stops that process only.
  • The guard of the consumers reads no bullet of the generated part, and takes the ticket's title, « Architecture » and « Noms publiés » for the arbitrage of the names it adds (grillhouse-ybq.2): on BPScript's bp-mono-vbwf.320.8 (625c8ca12), consommateurs-arbitres refused 18 lines of packages/000-forms/docs/INTERFACE.md and stopped two sessions of the developer, then went up to the supervisor, who wrote an arbitrage for what the plan already said. Seven of them were the « Paramètres » bullets (object, line, collection, value, path) of the generated entries of refOf, heldName, dataFound, lastRuleStep and ratioIn: the section ## Consommateurs ends the written text, and the guard read on into the generated part, as on 320.9 (its defect 26). The eleven others were consumers the plan named: its title names each component, its « Noms publiés » each new name, yet the guard asked the section « Architecture » alone for the consumer and for every name of the line, some fifty names a consumer read long before the lot. The guard now reads the section out of the generated marks, as the catalogue of the faults does, and a changed line passes when the ticket's title, its section « Architecture » or its section « Noms publiés » name its consumer and each name the lot adds to it, the names HEAD's section already gave that consumer being settled before; a refusal says the names the plan misses. Replayed on 320.8, ten lines pass, and 080-aligner refuses on ROLE, which none of them names; the rest of the description (a question, a criterion) never authorises a line, as criterion 20 of 320.8 keeps asRecord out.

[0.24.2] - 2026-10-24​

Fixed​

  • grillhouse maj no longer adds @microsoft/api-extractor, which only the package imports (grillhouse-3uv.95.11.3): BPScript, on a copy of its main at 0.24.0 (0c5064a99), played grillhouse maj 0.24.1, which added "@microsoft/api-extractor": "7.59.2" to the devDependencies of its root (« Dépendances de développement ajoutées : @microsoft/api-extractor »); grillhouse code-mort then refused it (« dépendance de développement sans usage »), the very dependency the guide of 0.24.0 had BPScript remove. The update counted it among the tools a project runs as commands; the package imports it as a library (scripts/interfaces-contre-code.mjs) and declares it in its own dependencies, and no command of a project runs it. As npm leaves to a package what it imports, the update now adds dependency-cruiser, knip and Turborepo only, and the template of a project no longer declares API Extractor. A project's tsdoc.json extended API Extractor's TSDoc base, which resolves only when npm hoists it to the root: in BPScript's lock it lies under the package (node_modules/@roomi-fields/grillhouse/node_modules/), and once uninstalled from the root interfaces-contre-code failed (« Unable to resolve "extends" reference »). As a rig of Rushstack carries the base configuration beside the dependency it names, the package publishes its TSDoc base, @roomi-fields/grillhouse/tsdoc-base.json, which extends API Extractor's, and the template's tsdoc.json extends it. The migration 0.24.2 « API Extractor du paquet » rewrites the extends of a project's tsdoc.json that still names API Extractor's base, the rest of the file kept; then, once the update is done (« reste au projet »), it names a root that still declares API Extractor while no source of the project imports it, with the line of the other dependencies only the package imports and npm uninstall, never removing it; the migration 0.23.2 leaves it to that one, so that it is named once.

Migration​

For a project in 0.24.x: npm install -D @roomi-fields/grillhouse@0.24.2, then npx grillhouse maj (it rewrites tsdoc.json), then npm uninstall @microsoft/api-extractor when the report names it.

[0.24.1] - 2026-10-24​

Fixed​

  • grillhouse maj declares the frame's package in the dependencies of a package whose code imports it, and its report sees a path to a former copy written in pieces (grillhouse-3uv.95.11.2): BPScript's migration from 0.22.2 to 0.24.0 (0c5064a99, bp-mono-vbwf.322.14, after the 320.9 that 0.24.0 answers) found four gaps. The update declared @roomi-fields/grillhouse in the devDependencies of packages/995-tools, whose guards under src/ import /consommateurs, /dette and /paquets, and grillhouse frontieres refused it three times (pas-d-outil-de-developpement-dans-le-code); BPScript moved it by hand (npm install -w packages/995-tools @roomi-fields/grillhouse@^0.24.0 --save-prod). As npm puts in dependencies what the published code imports, a package of the frame whose src/, out of the tests (the files the guard judges), imports an entry of the package now declares it in its dependencies, a declaration in its devDependencies moved there with its range; the imports are read by TypeScript (preProcessFile), a comment or a string importing nothing, and the report names the packages. The report « reste au projet » missed two forms of path, "file://$1/scripts/consommateurs.mjs" (generation-des-paquets.sh:16) and path.join(RACINE, 'scripts', 'vitest-config', 'duree.reporter.mjs') (verif-portes.mjs:38): it now finds a path by its words, a word cut at its / or the literal arguments of a call after 'scripts', a scripts/ under a literal directory (a package of the project, the installed package) being another's and . or .. naming none (path.join(import.meta.dirname, '..', '..', '..', 'scripts', 'dette.mjs'), verif-un-seul-etage.mjs:25), and a script of the package with no subcommand, hook nor entry is named with « aucune entrée publiée ne la remplace ». The guide of the supervisor sent horsCadre to /consommateurs; the section Migration below names each entry.

Migration​

For a project in 0.24.0, or migrating from 0.22.x or 0.23.x (the section of 0.24.0, then this one):

  1. npm install -D @roomi-fields/grillhouse@0.24.1, then npx grillhouse maj, then npm install.
  2. Each function a project's guard imported from a former copy comes from its entry, never from scripts/: horsCadre from @roomi-fields/grillhouse/paquets (not /consommateurs, which it left in 0.23), trancher from @roomi-fields/grillhouse/dette, matieres from @roomi-fields/grillhouse/consommateurs. Once the imports are rewritten, play npx grillhouse maj again, then npm install: the first pass saw no import of the package, and the second declares it in the dependencies of each package whose code now imports it, a replayed update changing nothing else.
  3. A test bench that builds a toy repository by copying the project's scripts/ loses the frame with it: give the toy a link to the project's node_modules, which carries the package, and read nothing under .claude/grillhouse/, which the migration 0.23.2 removes (its fichiers.txt included).
  4. In a copy of the repository made for the migration (a git worktree), git submodule update --init first: a guard that reads a submodule (the reference of an engine) is red while it is not checked out.
  5. npm run verifier -- --gardes.

[0.24.0] - 2026-10-24​

Added​

  • Each fact a sheet carries holds its piece, checked in the copy (grillhouse-3uv.95.10): in BPScript 320.9 (2026-10-22/23, frame 0.22.2), a question born of a line read wrong (native.ts:234, a « sac de sous-grammaire » that does not exist) was copied by five agents, none re-reading it, up to the owner (decided by Romain, grill of grillhouse-3uv.95, decision 5). As a code review cites the line it judges and a handover is trusted but verified, every finding, question and stop of a sheet now carries its piece, in one format that lirePiece of scripts/resultats.mjs reads: <file>:<line> or <file>:<line>-<line> (as SARIF's region) from the root of the copy, then what it shows, or $ <command> and its output on the lines after. The schemas require it on the reviewer's findings, on the questioner's and the explorer's questions, on a BLOQUÉ or a BESOIN of the testwriter and the developer and on the reviewer's question; a sheet without it, or with a piece in neither form, is refused. The circuit gives lireFiche the copy, where each file piece's file must stand and hold its line: a piece not found refuses the sheet, asked again once like any other lack; a line of the reviewer's conformity is checked the same way. A stop of a status, or of the reviewer's question, goes up with the sheet's piece, and the verdict at the ticket names each finding's piece; a finding kept open from one review to the next keeps its piece, which the next agent's instruction carries. The common charter says in one sentence, and the skills of the explorer, the questioner, the testwriter, the developer and the reviewer each say, that a fact taken up from another agent is re-read at its piece before anyone builds on it.

  • The reviewer judges every element the lot adds or changes against the architecture (grillhouse-3uv.95.7): in BPScript 320.9 (2026-10-22/23, frame 0.22.2), the architecture held by the reading enclosure, which 0.24.0 opens (Romain keeps the writing enclosure against the drift he saw, « des tas d'interfaces non respectées, les paquets qui vont lire directement dans les autres »), while the reviewer's « cadre » pass was free and judged what it chose to read; Romain (grill of grillhouse-3uv.95, decision 2): « il faut que le relecteur valide vraiment la conformité à l'architecture de tout ce qu'il y a de nouveau/changé ». As API Extractor has its report and its diff read line by line, and a mature review asks a word on every changed file, the circuit now computes the elements of the lot (scripts/elements-du-lot.mjs): each function, class, type, interface, enum, constant at the top of a module and export the lot adds, changes or removes against the copy's HEAD, with its package, its file:line and whether its package exports it, from TypeScript's language service of references-par-les-types.mjs (its declarations and its entry's exports, leService), the text of each declaration before the lot (git show) and after it (a changed text is a changed element) and the diff of the API reports (an export that changes only in its report is an element of it); a changed source the service does not read is named apart, with why (no tsconfig.json reads it, or the service could not run), for the reviewer to survey. The reviewer's instruction lists them; its sheet holds conformite, one line per element, oui or non, the rule it cites (document CADRE, INTERFACE or ARCHITECTURE, and its reference), a new export its entry in the INTERFACE, and its piece. The sheet's schema refuses a line without its document or its reference (scripts/resultats.mjs), and the circuit a sheet that misses an element or judges one out of the list (conformiteDuLot); a « non » is a blocking finding for its recipient (role, composant), which sends the lot back. As a review unticks « viewed » on the files changed since, a bounded review marks each element: to judge again when the difference touches it, else taken up with its line before, which the sheet still carries. The verdict at the ticket carries a section « Conformité ». The reviewer's skill opens on this pass, the second instruction template and the package's architecture say so.

  • The package publishes the functions a project's guards import, by named entries (grillhouse-3uv.95.1): BPScript, at the frame 0.22.2 of BP 320.9, runs four guards of its own that import the frame's functions by the address of its copies under scripts/ (trancher of dette.mjs in verif-un-seul-etage.mjs, matieres of consommateurs.mjs in verif-matiere-de-test-unique.mjs, horsCadre of consommateurs.mjs in verif-portes.mjs and generation-des-paquets.sh, a function that lives in paquets.mjs since 0.23), and the migration 0.23.2 removes those copies, so each guard would break at the update (decided by Romain, grill of grillhouse-3uv.95, option A). As eslint/use-at-your-own-risk publishes ESLint's tools, the package's exports now carry @roomi-fields/grillhouse/dette (trancher), @roomi-fields/grillhouse/consommateurs (matieres) and @roomi-fields/grillhouse/paquets (horsCadre), each pointing at the module that carries the function, without a re-export, with its declaration of types beside it (scripts/<module>.d.ts). A test packs the package, unpacks it in a project of trial, imports each entry by the package's name, calls it and checks its types; the package's architecture names every entry, and a test refuses an entry that comes or goes without that text. A project acts: each guard imports the entry, e.g. import { trancher } from '@roomi-fields/grillhouse/dette'.

  • grillhouse maj brings a project's texts to the circuit of 0.24.0, and a guard keeps the former circuit out of the frame's (grillhouse-3uv.95.11): BPScript, at the frame 0.22.2 of BP 320.9, keeps two texts its agents read that describe the circuit 0.24.0 removes: its guide of the issue tracker (docs/agents/issue-tracker.md, the template's bytes of 0.22.2: « 0 Exploration; 1 Ouverture … 2 Composants, for each component … the Arbitrage de l'arrêt (regulateur ⇄ questionneur) ») and, in every project born of the template of 0.22.x or 0.23.x, the rubric « Ce qui monte au superviseur » of its CLAUDE.md (« Le fonctionnel que le régulateur ne tranche jamais seul »), which the questioner's instruction carries; the migration 0.23.2 keeps the guide as the project's own. As a codemod of @turbo/codemod rewrites what its version changes and names what it cannot, the migration 0.24.0 « circuit simplifié » (scripts/migrations/0.24.0-circuit-simplifie.mjs) rewrites the paragraph of the former template in that rubric into the template's of 0.24.0 (« Une question qu'aucun geste du circuit ne tranche monte au superviseur, avec sa pièce. Il monte au responsable le fonctionnel, qu'il ne tranche jamais seul : »), the project's list kept, and replaces a guide of the issue tracker that holds the bytes of the template of 0.21.0 to 0.22.6 or of 0.23.x by the template's; a rubric or a guide the project modified that still names a removed role, and a copy of the regulator or of the technical referent left under .claude/agents/ or .claude/skills/ (one the migration 0.23.2 could not know as the frame's), is named with what to do, not written, the exit code non-zero. No version of the update wrote a setting of a role in .claude/settings.json or under grillhouse of the package.json, and the migration writes neither. Once the update and its regeneration are done, it names, never rewrites, each line of a tracked file that still calls a script of the frame at its former address under scripts/, with its file:line and the subcommand, the hook or the entry that replaces it (the migration 0.23.2 rewrites only the root npm scripts), as a report « reste au projet » that holds back neither the version nor the exit code, as @next/codemod and ng update report what they leave (grillhouse-3uv.95.11.1: on a copy of BPScript, the search played before the update named 45 files the update rewrote right after, its 40 turbo.json, its commit-msg hook, its settings and its .dependency-cruiser.cjs, and a line of history, pitmaster/SUIVI.md:363, held back the version), and a modified copy of a removed role is named once, by 0.24.0. The common charter now names the steps of the circuit, the gestures the circuit makes and the question that goes up; the supervisor's skill and the README name the reviewer's line of conformity per element; the guide of the issue tracker names the authors of the sessions as the circuit sets them. The guard of the removed roles (tests/unit/roles-renommes.spec.ts) also refuses, in the frame's texts and code, the steps of the former tree (« 0 Exploration », « 1 Ouverture », « 1.1 Relevé », « 2 Composants », « 2.3 Code », « Arbitrage de l'arrêt »…), its loop by component, its table of the stops, its rounds tour n/4 and its options (--reponse, --decision, --admettre).

Changed​

  • The bilan separates the night, the owner's wait and the supervisor's (grillhouse-3uv.95.9): in BPScript 320.9 (2026-10-22/23, frame 0.22.2), the bilan's « attente humaine » mixed 500 min of night, Romain's wait and the supervisor's, and its questioning counted 51 decisions changed for 20 (decided by Romain, grill of grillhouse-3uv.95, decision 5). As the lead time of DORA separates the wait for review from the work, each wait, from an end of a run on a stop to the run that answers it, now goes to who must answer its question, the qui of its montee (attente du responsable or attente du superviseur; an end without a question, at 75 among them, names the supervisor, who replays it), but its part in the night: the hours a project declares in its package.json, grillhouse.plageDeNuit ({ debut, fin }, local time, 23 h – 8 h by default), counted nuit. The bilan keeps murHorsNuit and perduHorsAttentes, and its text opens on the wall time, the wall time out of the night spent waiting, the time lost and the time lost out of the waits. The rounds of questioning are gone: the circuit keeps the questions the questionneur asked (questions, in place of a constant tours: 1), and the bilan counts the questions asked, the plans an answer changed and the questions left open. A step's result is no longer the next step's of its name kept within the gap: the checks of 3.1 followed within 2 s by the final pass counted two final passes. The project's CLAUDE.md template, the supervisor's skill, the package's architecture and STRUCTURE.md say so.

  • The circuit regenerates the references d'office, the frame's generated files and its known debt among them (grillhouse-3uv.95.8): in BPScript 320.9 (2026-10-22/23, frame 0.22.2), 292 min went around references the circuit did not regenerate, 163 of them waiting for the owner's word to regenerate by hand the index of the interfaces, the ceiling of the words and the fingerprint: the circuit regenerated only a final pass whose every red was a reference's (every), so a red of a reference mixed with any other was never regenerated; the index of the interfaces, the turbo.json of the packages and the API reports, which the frame generates itself, were declared nowhere; the ceiling of the words was counted down by hand (decided by Romain, grill of grillhouse-3uv.95, decision 5). As Bazel's genrules and --update-snapshots, a generated file is written again by its command, then the circuit replays only what depends on it: a final pass with a red of a reference regenerates the references it names, however many other reds stand beside it, then plays the final pass restricted to what the regeneration changes; each red of the pass before in a package that pass does not play again stands, and a regeneration that changes nothing plays no pass, its reds standing; the reds that remain go each to its owner, the developpeur or a question, with no stop of their own. The frame's generated files and its debt are references of the circuit in every project (REFERENCES_DU_CADRE of scripts/circuit.mjs), each written again by its generator and judged by the frame's guard (index-interfaces, turbo-des-paquets, the API reports by the rules rapport-api and partie-generee that interfaces-contre-code now gives the refusals npm run api lifts), their difference read by the reviewer without the plan naming it; a reference of the project still stops at « references » when the plan does not name its change. A ceiling never rises: a guard of the debt now writes each key inscribed above what it finds as a note of its SARIF (a-elaguer), and the circuit lowers the debt from those notes (node dette.mjs --abaisser <notes>), its guards not played again, or by the command of the project's reference that covers grillhouse-dette.json, though the pass is green; a lot beyond a ceiling stays red. The circuit does not read the exit code of a generator of the frame, which also judges the reds it leaves (npm run api ends at 1 beside any other red of its guard, which stopped the regeneration, the case of BP 320.9): it judges the regeneration by what it writes, then by the restricted pass that follows, and stops on a real failure alone (the command not found, or killed by a signal); the public commands keep their verdict. The step 4.2 now stands on the board of every project.

  • One circuit per ticket: one testwriter and one developpeur for the whole ticket (grillhouse-3uv.95.6): in BPScript 320.9 (2026-10-22/23, frame 0.22.2), the circuit played the sixteen components of the title one after the other, each with its own testwriter, proof, developpeur and checks; 118 min went to green steps played again, a type changed in a provider broke its readers one session at a time, and a blocking finding of the reviewer on exemplar was lost six times across the relaunches. As a merge request (one author, a series of tests and code, a CI on the whole, a review), the circuit now launches one testwriter and one developpeur for the whole ticket, each in the envelope of every package of its plan, then the final pass and the reviewer on the whole. The steps are 1 Plan · 2 Tests · 2.1 Preuve du rouge · 3 Code · 3.1 Contrôles · 4 Passe finale et relecture (4.1 Passe finale, 4.2 Régénération des références, 4.3 Relecture) · 5 Intégration. --depuis <testwriter|developpeur> plays the whole ticket again from that step; --etendre <paquet> adds a package to the plan, then resumes the step under way. A blocking finding goes straight to the agent it names and stays open, kept in the circuit's state, across every stop and relaunch until the reviewer judges it lifted or accepts the lot, as an unresolved thread of a review; a run that starts over starts without one. The section « Ce que les composants d'avant publient » gives, for each package of the plan, what its providers publish to it. The comments at the ticket read Circuit · <step> : …. The testwriter and the developpeur read the code index (codegraph explore, codegraph_explore, rtfm_search, rtfm_expand). The board shows the new steps, and a circuit's line its subject alone. The bilan counts by step and by role.

  • The plan is the explorer's, questioned once (grillhouse-3uv.95.5): in BPScript 320.9 (2026-10-22/23, frame 0.22.2), the questioning of the plan took 132 rounds of questions for 29 criteria of which 2 were useful, and the useful questions (who builds what, in what order, by which grammar) were never asked: they belonged to an exploration before the plan (decided by Romain, grill of grillhouse-3uv.95, decision 4). As the author of an RFC writes it after surveying what exists, a review reads it once, the author answers once and what stays open goes to who decides, step 1 of the circuit is now « 1 Plan », the explorer's and the questioner's: the circuit launches the explorer out of the envelope, on Sonnet, under rights of its own that write no file and nothing at the ticket (scripts/droits.mjs); it surveys the components by npx grillhouse composants-affectes <ticket> and ends on its sheet (scripts/resultats.mjs): the criteria, the packages to touch, as a title names its components, and its open questions, each with its piece. A package the repository does not hold, or one package named twice, makes the sheet out of conformity. The circuit writes the plan at the ticket: the packages as the title's components, the one list the envelope of every later session writes (GRILLHOUSE_ENVELOPPE); the criteria already written stay as they are, the owner's decision, and the sheet carries only the criteria the plan adds, numbered after them, each writing starting again from the description before the plan (to change or remove a criterion written, the explorer asks an open question); the open questions in a section « Questions ouvertes ». A plan the supervisor extends (--etendre) has passed, neither written nor questioned again. The questioner reads it once; on its questions, its disagreement as one, the explorer's session is resumed once and answers each question, CHANGE or GARDE, its sheet the plan as it becomes. What stays open (the plan's own questions, and each question left without an answer) goes up to the supervisor at « questionnement » (22), the open questions as its piece; nothing open, the plan passes and the circuit goes to the tests. The panel shows « 1 · Plan · explorateur ⇄ questionneur » in place of « 0 · Exploration » and « 1 · Ouverture » with its sub-steps 1.1 and 1.2, a ticket whose plan is under way or stopped standing there. The explorer's skill, the questioner's, the supervisor's, the instruction templates (two new ones for the explorer) and the headers of the modules say so.

  • The circuit makes the mechanical gestures itself, and a real question goes up to the supervisor (grillhouse-3uv.95.4): in BPScript 320.9 (2026-10-22/23, frame 0.22.2), the circuit launched 45 sessions of the regulator and 22 of the technical referent on its stops; the questioning of their decisions refused 34 right decisions for their form, and 14 stops that went up to the supervisor were gestures a rule settles. As a CI applies its rules (retry, regenerate, skip a job without object) and calls a person only for what no rule settles, the circuit now makes the gestures that the list of the steps writes (GESTES of scripts/etapes.mjs), with no session, each written at the ticket and in the log with its rule (Circuit · … · geste): a command at 75 played once more, the end at 75 (a-repasser), a red sent to the developer of the component that owns it, a developer's sending to a testwriter, the regeneration of the references, a developer with nothing to deliver judged by his component's checks. Every other stop ends the circuit on a question (MONTEES): the circuit's state carries question (the stop, the fact, its piece, the question, and who must answer it, superviseur, or responsable for the reviewer's question on a real word of the language), the ticket a line Circuit · … · question. The supervisor answers by --reprendre (with --contexte), --depuis, --etendre <composant> (the plan gains that component before its first reader, its title written, the run played again from its testwriter) or --arreter (the circuit ends on his word, its state kept). The questioning of the plan reads it once: its questions, or its disagreement, go up to the supervisor at « questionnement », and --reprendre lets the plan pass as it is then. The panel shows a stopped circuit under its step after « ⤷ Question · superviseur » or « ⤷ Question · responsable », its card opening on the question; 1.2 Questionnement names the questionneur alone. The integration and the guard of the consumers read the supervisor's arbitrage alone (a « ## Arbitrage » comment and its verdict).

  • An agent reads the whole copy and writes only the packages of its plan (grillhouse-3uv.95.3): in BPScript 320.9 (2026-10-22/23, frame 0.22.2), the reading enclosure caused most of the losses: the parent of the component emptied in every worktree, the neighbours shown by their published parts alone, the paths their tests read mounted one by one, the indexes hidden, while the writing enclosure and the guards are what held the architecture (decided by Romain, grill of grillhouse-3uv.95, decision 1). As the visibility of Bazel and the module boundaries of Nx refuse a dependency while the code stays readable, and as bwrap --ro-bind / --bind opens in writing only what it binds, the envelope now receives the plan's packages (plan({ paquets }), enveloppe.mjs <copie> <paquets> <rôle>, lancer.sh --paquets, the components of the title as the circuit gives them): the whole copy is read-only and in sight, its indexes included, each package of the plan comes back in writing (a path no package holds writes the root, the whole copy), with .beads and Turborepo's cache; .git stays read-only, the shared test material is written by the testwriter alone, and the sealed home is unchanged. GRILLHOUSE_ENVELOPPE carries the list (path.delimiter, as NODE_PATH), and each of its readers reads it so: the guards judge every component of the plan. A write out of the plan fails at the mount, and the agent's lock stops its session (Claude Code's continue: false), naming the file's package and the plan; its mark reaches the circuit (<ticket>.hors-plan), which ends at the new stop « hors-plan » (24), for the supervisor, with no regulator: he extends the plan or refuses. The emptied directories and their sealing, the published parts (PUBLISHED, the files field and the traces of a neighbour), the mounts of grillhouse.lit, the guard of the crossing links and the hidden indexes are gone, with their tests; cheminsLus moves to the survey of the components, its only reader, and enveloppe/composant.mjs becomes enveloppe/paquets-du-plan.mjs. The common charter, the package's architecture, the skills, the agents' instruction and the headers of the modules say so.

Removed​

  • The step that a declaration of the project shows (grillhouse-3uv.95.8): the declaration of a step (scripts/etapes.mjs) and the board's declarations, which hid 4.2 from a project without grillhouse.references; the stop of a regeneration that changes nothing, or of a pass after it red again on the references, whose reds now go each to its owner.

  • The loop by component of the circuit (grillhouse-3uv.95.6): the step 2 Composants and its per-component sub-steps (parComposant, sur), the gesture rouge-d-un-autre-composant, the component of a finding and of a sending (composant of the reviewer's and the developpeur's sheets), --depuis <agent> <composant>, the state's composant, composants, renvois, atteints and dernier, the component of the register's and the sheets' entries, and the board's alternating line (alterne, the component's rank n/N), with their tests.

  • The survey of the components the circuit played again, and its admissions (grillhouse-3uv.95.5): the step 1.1 Relevé des composants, the stop « composants-manquants » (21), verifierLeTitre, --admettre of composants-affectes and its record <ticket>.composants.json, and the board's witness of the survey; composants-affectes stays the explorer's tool. The step 0 Exploration joins the plan.

  • The regulator, the technical referent and what served them (grillhouse-3uv.95.4): their agents, skills, rights, sheet schemas and instruction templates; the table of the stops and the regulator's decisions (--reponse, --decision, the stop « question », code 18), the questioning of a decision and the referent's answers to the questioning of the plan; the change of the plan by a decision and its versing into the ticket's description; etat-du-circuit.mjs; the block « Arbitrage de l'arrêt » of the panel and the arbitrage's category of the bilan. A guard (tests/unit/roles-renommes.spec.ts) refuses their names in the frame's texts and code.

Fixed​

  • The frame's own checks no longer take the machine while a project's circuit waits (grillhouse-3uv.95.2): in BPScript 320.9 (2026-10-22/23, frame 0.22.2), 208 min of the circuit's wait for the lock of the machine went to the npm run verifier of the frame's agent copies, one lock serving both alike. As the job server of GNU make serves its own build and Bazel's --experimental_local_test_priority orders the tests that wait, a measure now has a rank: one played in the frame's own repository (its workspaces hold @roomi-fields/grillhouse in development, its agent copies included) is of the second rank, a project's of the first. A measure of the first rank that waits names itself beside the lock (<lock>.premier-rang/, one file per waiting process, a dead one's file dropped); a measure of the second rank does not take the lock, even free, while one of the first waits. The wait says its rank and whom it waits for, the holder and the measures of the first rank that pass first; its bound (60 min, GRILLHOUSE_ATTENTE_MACHINE_MS) is unchanged.

  • grillhouse maj takes the frame's copies off a project in 0.22.x (grillhouse-3uv.84.6.1): the trial of 84.6 (2026-10-23), a copy of BPScript at 0.22.2 brought to 0.23.0 (npm install -D @roomi-fields/grillhouse@0.23.0, then npx grillhouse maj, exit 0), turned red at npm run verifier -- --gardes: every copy stayed in place and kept running beside the package, 47 entries under scripts/, 12 skills under .claude/skills/, 7 agents under .claude/agents/, and .claude/grillhouse/; the copy of the guard of the index of the interfaces (0.22.2) judged late the index the update had just written with the package, the project's skills and agents hid the plugin's, the npm scripts frontieres and interfaces still ran a copy, and yaml, which only the copies imported, stayed a dependency (dead code). As a codemod of @turbo/codemod removes what a version replaces, the migration 0.23.2 « copies du cadre » reads the list the former update wrote (.claude/grillhouse/fichiers.txt) and its fingerprints (empreintes.json, the SHA-256 of each file's bytes, as 0.22.2 computed them): each listed file at its fingerprint (or at it before the migration 0.23.0 of Vitest rewrote its import of the base) goes, a directory left empty with it, and so does a file the former generator of the packages' turbo.json wrote under a listed directory that is no workspace any more (scripts/vitest-config/turbo.json), then .claude/grillhouse/ whole; a file the template of a project holds (tsdoc.json, docs/agents/issue-tracker.md) is the project's and stays, a gap from the plan of the ticket; a copy the project modified stays, named on the error stream with git rm <path>, with each npm script that runs it, the exit code non-zero (a migration returns what it leaves to the project as { aFaire }), and while one stays the list and the fingerprints stay and the project keeps the version it recorded, so that the next grillhouse maj names it again. Each root npm script that ran a removed copy by node scripts/… or bash scripts/… runs its subcommand (grillhouse frontieres, grillhouse index-interfaces); one that names a copy no subcommand replaces is named. A dependency only the removed copies imported, which the package declares itself, is named with npm uninstall, never removed. The table of the subcommands lives in scripts/sous-commandes.mjs, which the command and the migration import. On the files of the trial as the update of 0.23.0 left them, the migration removes 104 copies and the generated turbo.json, keeps none as modified, leaves no scripts/, rewrites the two scripts and names yaml, jsonc-parser, @microsoft/tsdoc-config and @microsoft/api-extractor-model. A project acts: npx grillhouse maj.

Migration​

For a project in 0.22.x or 0.23.x:

  1. npm install -D @roomi-fields/grillhouse@0.24.0, then npx grillhouse maj (in 0.22.x, the npm script grillhouse:maj still runs the former copy: call the package's command), then npm install for the tools it adds.
  2. grillhouse maj plays each migration newer than the version the project recorded (grillhouse.version; none in 0.22.x): from 0.22.x, those of 0.23.0 (the session hooks, the base configuration of Vitest, the marketplace, the charter imported) and 0.23.2 (the frame's copies under scripts/, .claude/skills/, .claude/agents/ removed at their fingerprint, the npm scripts that ran them rewritten); then 0.24.0 (the rubric « Ce qui monte au superviseur » and the guide of the issue tracker, above). Last, once the update and its regeneration are done, grillhouse maj reports « reste au projet », with its file:line, each line of a file git tracks in the project (node_modules and the changelogs aside) that still calls or names a script of the frame at its former address under scripts/ (node scripts/<script>, $VAR/scripts/<script>, path.join(…, 'scripts', '<script>')), with what replaces it: its subcommand (grillhouse <sous-commande>), its git hook (grillhouse hook <nom>, which the update places) or its named entry (@roomi-fields/grillhouse/dette, /consommateurs, /paquets); it rewrites none, the project's scripts being its own, and this report holds back neither the version nor the exit code. What a migration leaves to the project is written on the error stream, the exit code non-zero, and the project keeps its recorded version until nothing is left.
  3. By hand, what the update names and what no migration can know:
    • Each line of « reste au projet » calls the subcommand, the hook or the entry it gives; horsCadre comes from @roomi-fields/grillhouse/paquets (it left consommateurs.mjs in 0.23).
    • A file of the frame reached by its path that has no subcommand nor entry (a reporter of Vitest under scripts/vitest-config/) has none to reach: the base configuration (@roomi-fields/grillhouse/vitest-config) carries the frame's reporters for every configuration that extends it.
    • knip.json: the entries and the project files of the root workspace that name the former copies (scripts/*.mjs, scripts/enveloppe/*.mjs) match nothing once they are gone; remove them.
    • A copy of a role removed before 0.22, which no list of copies names (.claude/skills/integrateur/), stays: git rm -r it. A text of the project's own that names a removed role (the regulator, the technical referent, the integrator) is the project's to rewrite: the circuit commits the lot, and a question goes up to the supervisor.
  4. npm run verifier -- --gardes.

[0.23.1] - 2026-10-23​

Fixed​

  • The release publishes by trusted publishing, without a token (grillhouse-3uv.84.3.2): the release of v0.23.0 failed at its publication, ENEEDAUTH: the repository's secret NPM_TOKEN, from 2026-05-27, no longer authenticated anyone, as the owner's other packages had left it on 2026-09-04 for trusted publishing. As @roomi-fields/notebooklm-mcp publishes: the runner proves its identity to npm by OIDC (id-token: write), under Node 24, whose npm (11.5.1 or later) speaks OIDC, so no token is stored; the package's trusted publisher on npmjs.com names this repository and release.yml. CONTRIBUTING.md, STRUCTURE.md and the header of sortie.mjs say so.

[0.23.0] - 2026-10-23​

Changed​

  • The common charter arrives whole, imported by the project's CLAUDE.md, and keeps what every agent applies (grillhouse-3uv.84.8): the finding of 84.7: the session start wrote the common charter (19 KB) on its output, past the cap Claude Code puts on a hook's output (10,000 characters, docs « Hooks »), so a session received a preview of its first 2,000 characters and a path it was not asked to read. The owner decided (2026-10-23) that the charter is revised (« si Anthropic a fixé une limite, il y a une raison »): it keeps what every agent applies (7 KB), the circuit of a ticket goes to the supervisor's skill, the detail of the tools to the package's architecture (packages/grillhouse/docs/ARCHITECTURE.md, which the package now publishes). As Claude Code loads a CLAUDE.md and its imports whole, the charter of a project imports it from the package installed, Les règles du cadre : @node_modules/@roomi-fields/grillhouse/charte.md (the template's, which grillhouse init writes), and Grillhouse's from its source, @mods/grillhouse/charte.md; the migration 0.23.0 « charte importée » brings the import to a CLAUDE.md that lacks it (the former import @.claude/grillhouse/charte.md and the sentence of the plugin become it, else the line is added at its end). The hook of the session's start no longer writes the charter, nor substitutes ${CLAUDE_PLUGIN_ROOT} in it, and the hook SubagentStart is gone: a subagent loads CLAUDE.md and its imports as the session does. The charter names the meta-frame as the file beside it, the charters of a project at node_modules/@roomi-fields/grillhouse/METACADRE.md (mods/grillhouse/METACADRE.md in Grillhouse). A trial session (claude -p, a configuration of its own, Claude Code 2.1.309) in a new project, the packed package installed under its node_modules ignored by git, quoted the charter's last rule and gave the meta-frame's path. The tests that read the charter read each rule at its new address. A project acts: npx grillhouse maj.
  • The frame arrives in one piece: the package npm is its plugin (grillhouse-3uv.84.7): the frame came in two pieces, the package @roomi-fields/grillhouse for the scripts and the plugin grillhouse@roomi-fields, published apart from mods/grillhouse of this repository, each with its version; BP 325 showed what two pieces do: on 2026-10-22, BPScript's frame read 0.22.2 while its plugin was 0.22.6, and the copy of BP 325 had run its plugin at 0.20.3 since 2026-10-21. The owner decided (2026-10-23) « le cadre doit arriver en un seul morceau », in place of the grill's decision 3, then, the same day, that the plugin stays published under roomi-fields, its marketplace, and that what is a project's own is handled locally, never published by project. As a package of ESLint carries its plugin, the package is now the plugin: its prepack copies the whole plugin at its root (manifest, skills, agents, hooks of Claude Code, panel, common charter and meta-frame, its tests and configuration of TypeScript left out), since a source npm of a marketplace has no subdirectory, and keeps the template under cadre/; its manifest takes the package's version there, the manifest in the repository carries none, and the release raises the package alone. npm pack holds it, and claude plugin validate passes on the unpacked package (Claude Code 2.1.309); a trial session loaded it from a marketplace of a directory, its twelve skills listed and the meta-frame's path resolved. A project declares the marketplace roomi-fields (roomi-fields/claude-plugins) and enables grillhouse@roomi-fields, which the template carries and grillhouse maj writes; the marketplace of a project's own (grillhouse-<projet>, written by an earlier state of this branch) goes, with its declaration and its plugin, by the migration 0.23.0 « place de marché du projet ». The session start names again the plugin loaded at another version than the package installed in the project, with the command that aligns the one behind; a plugin whose version is not x.y.z compares nothing. The entry of the marketplace roomi-fields passes to the source npm, { "source": "npm", "package": "@roomi-fields/grillhouse" }, at the first publication of the package, a gesture of the owner in that repository (npx grillhouse sortie --entree-du-marche prints it, CONTRIBUTING.md §5). The meta-frame lives in the plugin, mods/grillhouse/METACADRE.md: the charter and the skills name it ${CLAUDE_PLUGIN_ROOT}/METACADRE.md, which Claude Code resolves in a plugin's skills and the hook of the session's start in the charter it writes; the circuit reads it, and the agents' instructions, at the plugin's root. The common charter, the headers of the modules, CONTRIBUTING.md (§5), STRUCTURE.md, the README and the charters of the project say so. A project acts: npm install -D @roomi-fields/grillhouse@<version>, then npx grillhouse maj.
  • The frame is a package with one command, grillhouse <sous-commande>, in a repository of three directories (grillhouse-3uv.84.1): the frame reached each project as copies at scripts/…, called by their path from eight kinds of callers (npm scripts, hooks of Claude Code and of git, skills, rights, the night, the mod, the guards), so it could not move a file without rewriting every project (decided by Romain, grill of grillhouse-3uv.84, rounds 1 and 2). As Turborepo's repository holds packages/turbo and its examples apart, the repository now holds packages/grillhouse/ (the package @roomi-fields/grillhouse, a workspace: its scripts and its tests, which Turborepo plays as a package's task), mods/grillhouse/ and templates/projet/ (the example application, its package.json, configurations and tests, its README and models, which npm run new places at the root of a new project); the root is the frame's private repository, its workspaces packages/* and packages/grillhouse/scripts/vitest-config. The package's bin is grillhouse (bin/grillhouse.mjs): one subcommand per script a caller launches, named after it (maj for grillhouse-maj.mjs), run in the working directory, the project's; an unknown one exits 2 with the list. The npm scripts (npm run verifier is grillhouse verifier, npm test is grillhouse tests), the skills, the rights of the roles, the hooks of the roles, the guards, the mod and the messages (npx grillhouse turbo-des-paquets --ecrire…) name the subcommand; a script finds its neighbours by its own directory, and the project by the working directory. The night's line of the crontab becomes cd <root> && node_modules/.bin/grillhouse nuit. The git hooks keep naming a script's path until grillhouse-3uv.84.5 moves them.
  • The push of a tag publishes the package on npm, under the one version of the package and its mod (grillhouse-3uv.84.3): the version lived in .claude/grillhouse/VERSION, a file copied into each project, and nothing compared it with the mod a project runs; on 2026-10-22, after BP 325, BPScript's frame read 0.22.2 while its mod, installed for it, was 0.22.6, and the copy of BP 325 had run its mod at 0.20.3 since 2026-10-21, with no session start saying so. As Changesets and the tools' repositories publish on the npm registry from the CI at each tag, with a token of the repository, under one number per release: .claude/grillhouse/VERSION is gone, the version is the version of packages/grillhouse/package.json (the package, no longer private, published public with its command and its scripts), which npx grillhouse sortie <x.y.z> raises with the mod's plugin.json; the push of a tag v<x.y.z> plays the CI on its commit (ci.yml, a reusable workflow), then, once it is green, checks that the tag names the version (npx grillhouse sortie --verifier-etiquette), publishes the package with the repository's secret NPM_TOKEN (with provenance) and the GitHub release. The session start of a project names the frame's mod installed for it at another version than its package, with the command that aligns the one behind (claude plugin update grillhouse@roomi-fields --scope <its scope>, or npm install -D @roomi-fields/grillhouse@<the mod's version>); a frame still copied into a project, without the package's package.json, compares nothing. The report of the update names the version of the source's package. The headers of the modules, CONTRIBUTING.md (§5), STRUCTURE.md and the README say so.
  • The frame's plugin carries its skills, its agents, its hooks of Claude Code and its common charter; the update copies no file (grillhouse-3uv.84.2): the update copied the skills, the agents, the charter and the scripts into each project from a list (.claude/grillhouse/fichiers.txt), recorded their fingerprints (.claude/grillhouse/empreintes.json) to name a drift, and merged the frame's hooks and status line into the project's .claude/settings.json; since 84.1 those hooks named paths that no longer exist (decided by Romain, grill of grillhouse-3uv.84, round 1, question 3, and round 2, question 7). As a plugin of Claude Code carries the components of a tool and is updated by its marketplace, and as Husky's hooks run before the project's tools, the plugin grillhouse@roomi-fields (mods/grillhouse/) carries the skills (skills/, /grillhouse:<nom>), the agents (agents/, named bare or grillhouse:<rôle>, each preloading its skill grillhouse:<rôle>), the common charter (charte.md) and the hooks (hooks/hooks.json, beside the mod's module): each runs node "${CLAUDE_PLUGIN_ROOT}/hooks/crochet.mjs" <sous-commande>, Node alone, which runs grillhouse <sous-commande> of the project's package (node_modules/.bin/grillhouse), its input, outputs and exit code passed on; without the package, the session start says « lance npm install » and the other hooks exit without effect. The common charter reaches each session by the hook of its start, written first, and each subagent by SubagentStart; the project's charter no longer imports it. A role is known by the plugin's agents ($CLAUDE_PLUGIN_ROOT/agents/<rôle>.md) in the session start, the structure guard and the ticket of a subagent, by the circuit's roles (ROLES of droits.mjs) in the launcher, and the board and the register read grillhouse:<rôle> as <rôle>. A role's session keeps the frame's plugin enabled, the others off, and turns off the project's own skills; Claude Code's skillOverrides reaches no skill of a plugin. The mod knows a project of the frame by its package.json, which declares @roomi-fields/grillhouse. The list, the fingerprints, --ecarts, the merge of the settings, the knip entries of the copied scripts and their guards and tests are gone; the update never writes .claude/settings.json, and runs the generators by the project's command. The status line stays a setting of the project (grillhouse ligne-etat): a plugin of Claude Code sets no statusLine.
  • The frame's git hooks follow Husky's model: prepare runs grillhouse hooks, and each hook calls grillhouse hook <nom> (grillhouse-3uv.84.5): the hooks named a script of the frame by its path (node …/scripts/un-commit-par-ticket.mjs), which 84.1 moved into the package, so a project's hooks broke at each move of the frame; BPScript's commit-msg still runs exec node "$(git rev-parse --show-toplevel)/scripts/un-commit-par-ticket.mjs" and its pre-push …/scripts/branche-de-nuit.mjs (read on 2026-10-22), and the update placed nothing over a hook that already carried the frame's mark (decided by Romain, grill of grillhouse-3uv.84, round 2, question 7). As Husky's prepare places hooks that call the tool and do nothing when it is missing: grillhouse hooks (scripts/crochets.mjs, which the update also calls) places commit-msg and pre-push in the folder git reads, beside Beads' sections, and rewrites in its place each line of the frame of a former version (its comment … (Grillhouse):, a line naming a guard's script or the frame's _gh_… variables; exec node …/scripts/un-commit-par-ticket.mjs included); each hook runs node_modules/.bin/grillhouse hook <nom> (scripts/crochet.mjs, the guard of that hook), and without the package installed lets the commit or the push go on, silent. The template's prepare is grillhouse hooks && npm run build, and the update writes grillhouse hooks at the head of a project's prepare, a prepare of its own kept after it. The subcommand crochets becomes hooks; un-commit-par-ticket and branche-de-nuit, which only the hooks ran, are gone; npx grillhouse setup no longer places the hooks (its npm install runs the prepare); the session start names a hook whose lines are of a former version as absent. The headers of the modules, the common charter, STRUCTURE.md and the README say so.
  • grillhouse init creates a project from the template, and grillhouse maj brings a project to the package installed, migrations included (grillhouse-3uv.84.4): a project was born of a copy of Grillhouse's whole repository (npm run new, setup.sh), and the update fetched a checkout of Grillhouse's main branch and handed itself over to its script, whatever the version npm installed; BP 325 showed a project whose copies and package spoke two versions. And the package published by 84.3 worked nowhere but in Grillhouse: it declared no dependency and imported @grillhouse/vitest-config, a package never published (the finding of 84.3), and the circuit read the agents' instructions and the meta-frame above its own directory, where an installed package has none (the finding of 84.2). Now npx @roomi-fields/grillhouse init <dir> [prefix] copies templates/projet/ (which holds the settings, the charter, the configurations and the example application), declares the package, prepares the project (git, Beads, CodeGraph, the plugins, npm install) and writes what the update writes, as create-turbo does; grillhouse maj takes no source: it plays the package's migrations newer than the version the project recorded (grillhouse.version), in their order, each replayable without effect, as @turbo/codemod migrate does, then writes what the frame writes, read in the package's template. The status line stays a setting of the project (the owner's decision A, on Husky's model): init writes it and maj keeps it; the migration 0.23.0 removes from a project's settings the frame's session hooks, which the plugin carries since 84.2, and another brings its imports of @grillhouse/vitest-config to @roomi-fields/grillhouse/vitest-config, the base configuration the package now exports. The package declares what its scripts import (jsonc-parser, yaml, semver, API Extractor and its model, the TSDoc configuration loader; Vitest and TypeScript as peers) and carries the template, the meta-frame and the agents' instructions under cadre/ (its prepack); a night test installs the packed package in a fresh project and plays grillhouse verifier there; the boundaries check takes a JavaScript source a package exports as its own source, and a declaration or a JSON file as no entry. new-project.sh, setup.sh, the subcommands new-project and setup, the npm scripts new and setup, --source, GRILLHOUSE_SOURCE and the cache checkout are gone. A project acts: npx grillhouse maj once the package is installed.

[0.22.6] - 2026-10-22​

Fixed​

  • The CI of 0.22.5 is green again: the numbering of the files of the circuit's working directory (3uv.94) reads a file name by a regular expression the guard of free text did not list; it is listed, as reading a file name, never a comment or a log.

[0.22.5] - 2026-10-22​

Fixed​

  • The working directory of the circuit lives as long as its ticket: during BP 325 (2026-10-22), a reviewer's session, launched out of the envelope, outlived its killed circuit, and lost the circuit's working directory (its instruction, its statements, the file of its result) as soon as another pass swept it as an orphan base, its owner gone. As the workspace of a pipeline of Jenkins or GitLab, cleaned at the end of the pipeline and never by a neighbour, the circuit's working directory is now the ticket's, .claude/worktrees/<ticket>.travail beside its copy: no sweep touches it, a circuit relaunched on the ticket takes it up again (its files numbered after those it finds), the queue removes it at the ticket's closure, and scripts/retirer-copie.sh removes it with the copy, so that a ticket closed without integration (a final stop, an abandon) loses both by one command; the integration removes the copy with --garder-travail, since the circuit still runs. The results and the progress of the circuit's passes stay in the base of its run, removed at its end and swept when orphan. The common charter, the supervisor's skill, the headers of the modules and STRUCTURE.md say so. (grillhouse-3uv.94)

[0.22.4] - 2026-10-22​

Fixed​

  • The trials live under the base of their pass, removed at its end and swept when orphan: on 2026-10-22, during BP 325, /tmp (a tmpfs) was full at 100 % of its files (1 044 112 of 1 048 576) and a command failed; 1 912 trial directories over 2 h old were removed by hand (trace- and lectures- from the tests of BPScript's corpus; circuit-, integration-, enveloppe-, sous-modules-, nuit-, retirer-copie-, pre-push-nuit-, grillhouse-maj- from the frame's tests, roots a killed run never removes), Vitest's own /tmp/<nanoid>/ssr, and 18 835 of the 20 630 directories of /tmp/claude-1000 came from the envelopes of the trial copies, which kept the scratchpads under a /tmp written in their code. As Bazel gives each test its temporary directory (TEST_TMPDIR) under the base of its run and cleans the sandboxes a killed run leaves, a pass now opens a base, <tmp>/grillhouse-<genre>-XXXXXX/ with its owner (process and PID namespace) and t/, which it names in TMPDIR to what it starts, and removes it at its end, green or red; opening a base sweeps the bases whose owner is gone in the same PID namespace, and never touches a living one (scripts/vitest-config/base-de-passe.mjs). A plugin of the base configuration of Vitest opens the base of each run in its main process, before Vitest makes its own temporary directory, so a project's tests that write under os.tmpdir() write there without changing their code; npm test and npm run verifier open theirs, which Turborepo passes on (TMPDIR joins the root's globalPassThroughEnv, which the update of the frame writes); the circuit, the integration and the envelope keep their working directory in one, and npm run verifier the file of its changes since the last green (grillhouse-changements-, 24 left in /tmp by killed passes). The envelope keeps the scratchpads where Claude Code keeps them, under CLAUDE_CODE_TMPDIR or the temporary directory of the launch. The common charter, the headers of the modules and STRUCTURE.md say so. (grillhouse-3uv.93)

[0.22.3] - 2026-10-22​

Changed​

  • A reference also names the guards that judge it: in BPScript 320.4 (BP 325), a ceiling of the words exceeded reddens its test, which the reference names, and the project's guard verif-mots-de-librairie (task //#gardes), whose finding aims at the faulty file of code, not at the ceiling; the final pass then held reds that were not the references' alone, 3.1 did not run, and the supervisor regenerated by hand. As rustc --bless ties a judgement to its expected outputs, a reference of grillhouse.references is now { nom, commande, fichiers, tests, gardes }: gardes (optional) names the project's guards that judge it, by the name their SARIF finding carries (its guard, ruleId, or its rule, regle); a finding of one of them is the reference's, whatever file it aims at. A guard that writes no SARIF stays a red of its task, which no reference holds: it writes its findings by ecrireSarif (scripts/resultats.mjs) under the name the declaration gives. The common charter, the skills of the supervisor and the regulator and the header of scripts/circuit.mjs say so. (grillhouse-3uv.92.13)

Added​

  • A red night gives, for each red task, the command that looks for its culprit commit: the night's ticket wrote only « Commits à chercher (git bisect) : .. », and whoever read it had to find the red task in the log, then write the bisect command. As a monorepo tool gives a verdict per target and git bisect run replays the red target alone, npm run verifier writes its red tasks (<package>#<task>, one per line, a task à repasser none of them) to the file GRILLHOUSE_ROUGES names, and scripts/nuit.sh adds for each one git bisect start <head> <last green> && git bisect run npx turbo run <task> --filter=<package> (--filter=// for the root), with no second reading of Turborepo's summaries. The headers of both scripts and STRUCTURE.md say so. (grillhouse-3uv.56.2)

[0.22.2] - 2026-10-22​

Changed​

  • A reference is declared by patterns and by the tests that judge it: in BPScript 320.4 (BP 325), the fingerprint of the v2 is a directory of 617 files (packages/995-tools/src/empreinte-v2/<scène>.json), whose list changes with each scene added, 262 of them changed by 320.4; fichiers compared only exact paths, and the red of the final pass came from the test file that judges it (packages/995-tools/test/empreinte-v2.test.ts), which the declaration could not name. As the inputs of Turborepo and rustc --bless, which ties a test to its expected outputs, a reference of grillhouse.references is now { nom, commande, fichiers, tests }: fichiers holds paths, directories or glob patterns (*, **, read by path.matchesGlob of Node), tests the test files that judge it; a red of the final pass in one of its tests, or on a file its fichiers cover, goes to the regeneration of 3.1, and each file the regeneration changes must be covered by a reference, else the stop « references » as before. The common charter, the skills of the supervisor and the regulator and the header of scripts/circuit.mjs say so. (grillhouse-3uv.92.12)

[0.22.1] - 2026-10-22​

Fixed​

  • An automatic pass shows its time since its start, and a frozen one the time since its last sign: the owner read ⏳ Mesure · BPScript · 52/160 · 25 s after 20 min of a pass, the time since the last test file done, which falls back to 0 at each file (Romain, 2026-10-22). As Bazel's counter of actions, the line of a measure and the line of a ticket at an automatic step now give the time since the start of the pass (scripts/avancement.mjs reads it from the pass); ⚠ figée <durée> past 5 min without a sign keeps the time since the last sign.

[0.22.0] - 2026-10-22​

Fixed​

  • A final pass of a copy measures itself against the copy's last green: in BPScript 320.4 (n° 15), the final passes of the copies measured themselves against main's last green (28 to 296 files changed) and played 46 packages, since 000-forms changed; a copy's green, kept in the one file of the repository, was replaced by the next copy's or main's: 11 passes, 94 min. As vitest --changed <ref> and Bazel measure against the last green build of the same branch, the last green is now kept per branch (<git common dir>/grillhouse/dernier-vert/<branche>.json, scripts/dernier-vert.mjs): a pass measures itself against its branch's last green when it counts, else against main's (the branch of the main tree), and a final pass relaunched plays what changed since the copy's green alone; a detached HEAD (the queue's replay onto main) reads and keeps main's. The line of the pass names the branch whose green it measures against. The whole final pass before the integration is unchanged. The former dernier-vert.json is no longer read: main's first pass after the update is complete, and so is a copy's while neither it nor main has a green. The common charter, STRUCTURE.md and the headers say so. (grillhouse-3uv.92.9)
  • The commit message is written once, from the final state: in BPScript 320.4, the message of 5efb563 said eight times that the fingerprint of the v2 changes, gave two contrary ceilings (548 → 547 and 547 → 546) and phrases out of date (« rougissent jusqu'à leur migration », « l'intégrateur la met à jour »): the circuit stacked the deviations of every sheet, one line each. As a change merged on Gerrit carries the one description of its last patch set, each deviation of a sheet now names its sujet beside its texte; the message carries the title of the ticket, the criteria of the plan, then a paragraph per subject, once, with the value of the last sheet that carries it (messageDuLot). A red that a later component of the ticket closes goes in the developpeur's handover, no longer in ecarts, since the final pass is green before the commit. The header of scripts/circuit.mjs, the sheet's schema and the skills of the developpeur and the reviewer say so.
  • The bilan counts right the sessions, the supervisor's wait, the regulator and the final passes: in BPScript 320.4 the bilan gave 69 sessions (68 launched by the circuit, the 69th a referent the supervisor launched), 1.7 min of wait for the supervisor (23.8 measured from each stop to its answer), counted lost all the regulator's 40 min, half of which served, and put the 94 min of final passes among the automatic steps. As the bilan of a pipeline composes its measures, each item by its rule, the circuit now keeps with its results the launch of each session (lancement, its role and its session id) and each end of a run on a stop (montee): the bilan counts the sessions the circuit launched, and the supervisor's apart (seances.horsCircuit, by role, with their cost, out of the categories); the wait runs from each end on a stop to the first session or step of the run that answers it, no longer from a regulator's MONTE, even one its questioning reversed, to the next comment or turn; a regulator's session takes the category of what its decision gives, without effect when the session or step after its arbitrage is, work kept otherwise, and the referent's answers for the plan go with the questioning; the final passes have their own line, kept, those without effect or replayed apart. The bilan no longer reads the ticket's comments; the line « Passes finales » and the category « régulateur » are gone. The headers of scripts/bilan.mjs and scripts/circuit.mjs, the supervisor's skill and STRUCTURE.md say so. (grillhouse-3uv.92.10)
  • The rights of the regulator and the reviewer hold the real form of their commands: in BPScript 320.4, the regulator's bd comments add of a multi-line arbitrage was refused twice in three (a line opening on #), one MONTE and 9 min of the supervisor's wait; its state of 33 k tokens passed the limit of Read, its fall-back on python3 was refused 13 times, taking down the reads of bd chained to it; its instruction promised reads of git it held no right for (6 refusals); the reviewer met 9 refusals of form. The rights of 0.20.0 were checked on their patterns, never on the form a session runs. As an orchestrator writes what its judge decides and a tool gives a dedicated view in place of a raw file (kubectl describe, gh run view): the regulator's arbitrage and the criterion it adds are fields of its sheet (arbitrage, critere), which the circuit writes at the ticket (Circuit · … · regulateur : arbitrage — …, read as settled by scripts/consommateurs-arbitres.mjs and the integration) and at the end of the description, numbered; a criterion that does not go to a testwriter first, or an arbitrage on a MONTE, is refused; the regulator writes nothing at the ticket. It reads the state by node scripts/etat-du-circuit.mjs <état>, a summary bounded to 20 000 characters (step, component, stop, last reds, files), in place of the raw file; the regulator and the reviewer hold git -C <copie> status|diff|log|ls-files|grep, which their skills name. tests/unit/droits.spec.ts plays each command a role's skill names in its written form (its placeholders filled as a session fills them) against its real rights, by the rules of Claude Code that 320.4 measured (a chain judged command by command, a line in # in quotes, a cd out of the copy, a variable in the path of a read, a read out of the copy without Read). The skills of the regulator and the reviewer, the regulator's instruction and the headers say so. (grillhouse-3uv.92.7)

Changed​

  • A regulator relaunches several components in one decision: in BPScript 320.4, the red of the ceiling of 040 (64 > 59) stood in the first final pass, but was relaunched only after the third, 20 min lost: the regulator's sheet carried a single depuis, one component per relaunch. As GitLab's « Retry failed jobs » retries every failed job at once, the sheet's depuis is now a list of one or more components of the title, each with its agent (testwriter or developpeur) and its contexte; the circuit plays them again in the order of the title, each from its step with its own context on its line CONTEXTE (renvois, as after a RENDU), then the components after them it has not carried through, then a single final pass. The admission control judges each component: one out of the title, named twice, or a developpeur before his testwriter refuses the whole decision. The top-level contexte belongs to RELANCE --reprendre alone. The regulator's skill, its instruction and the headers of scripts/circuit.mjs and scripts/resultats.mjs say so.
  • A role's session ends with its sheet, its background tasks with it: in BPScript 320.4, a developpeur launched in the background a loop until … sleep 5; his sheet was given at 21:37:14, but claude -p waits for its background tasks, and the session ended at 21:46:43, when the task reached its limit: 9.3 min lost. As a job of GitLab or Jenkins ends with its main command, the settings of every role's session (scripts/droits.mjs) now turn off the background tasks of Claude Code (env, CLAUDE_CODE_DISABLE_BACKGROUND_TASKS): the Bash tool has no run_in_background, and the session ends once its sheet is given. The skill of each role of the circuit says it waits in the foreground for what it launches, as the common charter does; the header of scripts/droits.mjs says so. (grillhouse-3uv.92.6)
  • The envelope of a package lets its agent write that package alone: in BPScript 320.4 (n° 13), only packages/ was emptied, so libraries/ and spec/ stayed writable for every agent; the developer of 900-driver edited libraries/alphabets.bpsl, and the circuit saw « aucun changement de 900 » (sans-livraison). As a sandbox of Bazel or of Nix opens in writing only what the action declares, the envelope of a component that is a package now mounts the copy read-only and its package alone in writing; a write elsewhere fails on « Read-only file system », which the agent sees. The shared test material for the testwriter, the session's files, the tickets base and Turborepo's cache keep their rights; where Turborepo writes at the root of the copy (.turbo) is a directory proper to the session. A folder of the root is written by the component that owns it, and what the tests declare they read stays read-only: no new implicit right. A component that is no package keeps the copy written. The header of scripts/enveloppe/enveloppe.mjs and the skills of the developpeur and the testwriter say so.
  • The survey of a ticket's components follows what packages declare they read, not the types they carry: in BPScript 320.4 (0.20.3), the survey gave 15 components missing from the title, 13 of them carriers (« type ReadTree rendu par parse, reçu par bind, transporté par 900-driver ») or producers named by a « Reçoit R3 » of a CADRE.md, beside 13 words « sans interface qui les publie » (zx, v, the faults to create); the supervisor set the 15 aside at once (« porter n'est pas lire »), 050-emitter and 900-driver with them, and 995-tools, whose grillhouse.lit declares libraries, was not found: 6 min lost, and an arbitration sent to 030-binder before both joined the title. As a graph of declared dependencies (the deps and data of Bazel, the implicitDependencies of Nx), a reader is now a package that reads: by the types, a package that receives a type a carrier returns is a reader only when its code reads that type's content, and the producer of a type the carrier receives never is; by the architecture, only the « Rend » of a CADRE.md names readers; a package whose grillhouse.lit covers a path the ticket writes, or the folder of a component it names, is a reader (« Par les chemins lus »); a word that names no top declaration nor path of the repository is no longer listed « sans interface ». Replayed on the description of 320.4 as it stands, the readers by the types lose 010-parser, 020-loader and 060-encoder, the 13 words leave, and 995-tools is found, with 060-encoder and 990-corpus, which also read libraries; the count of components does not fall yet: 010-parser, 020-loader and 150-renderer-osc still come by the names they read (BASE_FORMS, BoundObject, range), and seven packages by the Rend of 070-deriver, which place, a word of the language, resolves to.
  • A symbol internal to a package leads the survey to no reader: replayed on the real description of BPScript 320.4 (BP 325), the survey still found 19 components; place, a word of the language the ticket writes, resolved to a function internal to 070-deriver, whose CADRE.md « Rend » brought 7 packages (080-aligner to 150-renderer-ui). As « find all references » of TypeScript's language service and of rust-analyzer, which starts from a symbol the published interface of a package exports, a word of the ticket now leads to readers only when it names a symbol the entry of a package exports (exports of its package.json): an internal symbol brings no reader, by the types nor by the « Rend » of its CADRE.md, and not its own package, which the ticket names when it changes it. The carriers of an internal symbol, and the reading of the content of what they return, leave with it. The readers of an exported symbol stay: 010-parser (BASE_FORMS), 020-loader (BoundObject) and 150-renderer-osc (range) are real readers (the owner, 2026-10-22). Replayed on the same description, the survey finds 11 components, 070-deriver and the 7 left out. The headers of the two scripts, the explorateur's skill, README and STRUCTURE say so. (grillhouse-3uv.92.11)
  • A developpeur's sending to a testwriter keeps the findings of the other components: in BPScript 325 (BP 320.4, n° 12, ~9 min), on a RENDU that named 000, 030, 040 and 995, 000's developpeur sent his red to his testwriter; depart replaced renvois with 000's key alone, the findings of 030, 040 and 995 were skipped, and the second review found them « non levé ». As a queue of jobs grows and is never replaced, the sending now keeps the renvois of the developpeur's component and of the components after it, each played after it with its findings, the target's own findings for its developpeur included. The header of scripts/circuit.mjs and the developpeur's skill say so. (grillhouse-3uv.92.3)

Added​

  • A step regenerates the project's references on the whole copy: in BPScript 320.4, the fingerprint of the output (npm run empreinte:v2 -- --mettre-a-jour) and the ceiling of the words (verif-mots-de-librairie --abaisser) count the whole copy, which no envelope shows (548 in the envelope against 547), and no step played them: they alone made the final passes 5, 7 and 9 red, 45 min lost, until the supervisor regenerated them by hand. As rustc --bless, jest -u and cargo insta accept, a project now declares its references in its package.json, grillhouse.references (each { nom, commande, fichiers }), and a final pass red on their files alone goes to step 3.1, Régénération des références, which the circuit leads itself: each command runs on the whole copy, out of the envelope, under the lock of the machine, then the final pass restricted to what it changed (green after a whole pass, it counts as whole). The lot carries the files regenerated, and the reviewer reads them with the rest, the step's report among the circuit's. A reference changed that the ticket's description names neither by its name nor by one of its files, a file no reference declares, a command in failure, a regeneration that changes nothing or a pass red again on them stops at « references » (23), the copy restored, for the regulator. Without the declaration, the step never runs, and the board shows its line under 3 only for a project that declares it. The common charter, the skills of the supervisor and the regulator, and the headers of the circuit, the list of the steps and the board say so. (grillhouse-3uv.92.1)

[0.21.0] - 2026-10-21​

Changed​

  • The context of a relaunch --depuis follows the whole chain of its component: in BPScript 325, --depuis testeur packages/995-tools --contexte … gave its developpeur only the report of the proof, « CONTEXTE : aucun », and he kept what the owner had just set aside: 5 min lost, 23 min counting what followed. depart gave the context to the first step alone, as its report, and the line CONTEXTE said « aucun » under --depuis. As a retry of GitLab CI plays the jobs after it with the same variables, the context now stands in renvois (kept in the state) and on the line CONTEXTE of each agent of the component played again, its testwriter then its developpeur, no longer as the first step's report; a component after it does not receive it, and the developpeur still starts on a red of the proof. The gestures of the table that play a component again (a developpeur's sending to a testwriter, a component added before --reponse) carry their text the same way. The header of scripts/circuit.mjs and the regulator's instruction say so.
  • The agent of step 2.1 is the testwriter: the owner chose an English name, shorter and clearer (2026-10-21). The agent and skill testeur are now testwriter, without an alias: the step, its stops (renvoi-au-testwriter), the sheets (role testwriter), the locks, the envelope, the rights, the board, the common charter and the skills name only testwriter, and the circuit writes its sessions under the author testwriter <composant> and reads the line Agent : testwriter. The update of a project removes the former agent .claude/agents/testeur.md and skill .claude/skills/testeur/.
  • The testwriter removes a file of its tests by a gesture its rights permit: in BPScript 325, at 14:29 the testwriter could not remove a test file, python3 refused three times as the common charter's os.remove asked, while the same removal had passed at 14:02 by node; 2.5 min and a stop that went up to the supervisor. As a role holds the rights of what its skill asks, the charter now names a node script of the scratchpad (rmSync of node:fs) on a path named and read, the testwriter's skill names it (node $TMPDIR/<script>.mjs), and its rights allow it (scripts/droits.mjs); python stays refused to a role that writes.

Fixed​

  • A nested trial writes its results in a directory of its own: in BPScript 325, the toy tests of a trial (deux-lancements) played a nested Vitest that inherited GRILLHOUSE_RESULTATS and wrote its report in the results directory of the proof that played it; the proof counted them as 5 reds, and the developpeur was launched twice on nothing. As Bazel gives each test its own outputs directory (TEST_UNDECLARED_OUTPUTS_DIR), a setup file of the base configuration (scripts/vitest-config/resultats.setup.mjs) names for each test file's processes a directory of their own, <dossier>/essais/<process>-<token>/, which no reader of the run reads; the reporters of the run keep its own directory. Without the variable, nothing changes. The header of the base configuration and STRUCTURE.md say so.
  • A finding of the reviewer blocks or remarks, and only a blocking one sends the lot back: in BPScript 325, the reviewer required that the frozen v1 packages stay dated dependencies with a bench, and the owner answered « non car la V1 ne change pas elle est gelée »; the chain of the finding refused cost 18 min, about 38 with what followed, while only a finding that put a criterion in question could stop a sending back. As Conventional Comments mark a comment blocking or not, and as Google's review guide asks for nothing the change does not need, each finding of the reviewer's sheet now carries its genre, bloquant or remarque; a blocking finding names in regle the criterion of the plan or the rule of the frame it holds, and the sheet's schema refuses one without it, a RENDU without a blocking finding and an ACCEPTÉ with one. The circuit sends back the blocking findings alone; the remarks reach the ticket with the verdict, no agent; the list remarques is gone. The reviewer's skill applies to its own findings the rule of the real need: a case only possible never becomes a blocking finding. (grillhouse-3uv.91.2)
  • The owner's decision enters the plan, which every agent reads: in BPScript 325 the regulator never read Romain's answer, kept in the comments only: its instruction did not carry it, two reads of the comments were refused (joined to a python3 in a command of the dontAsk mode), a third read the description alone, and it ordered a bench Romain had just ruled out (~15 min lost). As an RFC amended or an ADR, Romain decided that the plan carries the decision, not the answer shared to all (2026-10-21). On --reponse after a question of the regulator, a fresh session of the technical referent pours the answer into the plan (a criterion added, removed or made precise, the title), the circuit writes it (bd update), and a plan changed is surveyed again and questioned, the referent answering in its own session, before the regulator resumes; an answer that changes no criterion is said at the ticket, and the regulator resumes with no questioning. The regulator's instruction carries the plan, the reviewer judges on it, and neither seeks a decision in the comments; the context of a relaunch carries the stop, never a decision of the owner (a component the title gained on an answer starts at its testwriter with the stop as its report). A twelfth template, the technical referent's on the supervisor's answer. The common charter, the skills of the regulator, the technical referent, the supervisor and the reviewer, the templates, the README and the header of the circuit say so.
  • A decision of the owner given in session enters the plan, the circuit stopped then resumed: in BPScript 325, Romain gave his decision when he questioned the supervisor at 13:53, out of any stop « question »: it stayed in the supervisor's conversation and in a comment, never in the plan; the regulator did not read it (~15 min), and the reviewer judged without it. The path of an answer (--reponse) covered only the answer to a stop « question ». As GitLab CI cancels a pipeline a new one makes redundant, and Zuul the jobs of a change superseded, circuit.mjs <ticket> --decision "<texte>" now stops a circuit running on the ticket (the state names its process, processus) and the session it led, said at the ticket; then the technical referent pours the decision into the plan (the twelfth template, made common to an answer and a decision), the circuit writes it and the questionneur questions it, and the run resumes where it was: the components the change reaches that it had passed (the survey of the components on the lines it adds or removes, as at the opening) play again from their testwriter, the plan changed as their report, never the decision; a decision with no effect on the plan is said at the ticket, and the run resumes as it was. At a stop that waits for --reponse, or once the lot has reached the integration, --decision is refused. The supervisor's skill says that every decision of the owner on a ticket goes by the circuit, never by the context of a relaunch nor by a comment alone; the common charter, the technical referent's skill, the README and the header of the circuit say so. (grillhouse-3uv.91.7)
  • The proof of the red plays the tests of the lot alone, and a forgotten expected green does not play it again: on BPScript 325 the proofs took 27.2 min of a 90 min ticket; each one played every test of 995-tools (5.2 min), since its package was named whole and a file its tests read without importing it had changed, and each of three forgotten verts_attendus played the whole proof again, 11 min lost. As test-driven development runs the test it has just written to see it red, the proof now runs npm test -- --force <files>, the test files the testwriter's lot adds or changes in the component, HEAD's version of each beside it, played for real (a run of the same command replayed from Turborepo's cache, the checks' own, writes no report); the other tests of the component play at its checks, and the final pass keeps its scope. A component with no file of the lot (a reader whose provider changed a type) still plays its packages whole, where its existing reds launch its developpeur. As Turborepo replays a task whose inputs did not move, a proof on the same tree (the copy's fingerprint) is not played again: a testwriter relaunched who changes no file, his sheet alone completed, is judged on the results of the proof already played. The header of scripts/circuit.mjs and the skills of the testwriter and the regulator say so.

[0.20.3] - 2026-10-21​

Changed​

  • The wait for the lock of the machine is bounded, names its holder, and stops at once on a deadlock: a full pass hung 40 min, the machine at rest, because a test ran a npm run verifier that waited for the lock of the machine held by the very pass that played it, each waiting for the other without a word (Romain, 2026-10-21). As flock -w and a database's lock timeout, the wait now has a bound, 60 min (ATTENTE_MACHINE_MS of scripts/verrou-de-machine.mjs, longer than the longest full pass measured: 21 min for the frame's, 35.5 min for a final pass of BPScript 320.3, a wait for rest included; GRILLHOUSE_ATTENTE_MACHINE_MS names another, in ms); the bound reached, the measure stops at « à repasser » (75), the holder named: its process, working directory, command, and since when it holds the lock. A lock held by an ancestor of the waiting process (its parent, its parent's parent…) is a deadlock: the wait says so at once and stops, red (1), since the descendant lost the mark of the taking (GRILLHOUSE_MESURE_TENUE), a defect to correct, which playing under the ancestor's lock would hide. The wait says it waits, and whom for, when it begins and then every 30 s, so that a log shows the pass is not frozen. npm run verifier ends on the stop's code and the circuit's heavy passes read it as theirs. The common charter and the module's header say so.
  • An automatic pass shows its progress in figures, and a frozen one is seen: a pass froze 40 min, the machine at rest, and nothing on the board showed it. As Bazel's counter of actions « [1 234 / 2 000] » and the steps of a CI, every automatic pass now plays under a progress directory (GRILLHOUSE_AVANCEMENT, which globalPassThroughEnv now names and the generator adds; scripts/avancement.mjs): a reporter of the base configuration writes, at each test file done, the files done and planned of its task (scripts/vitest-config/avancement.reporter.mjs, written atomically, one record per task of Turborepo); the reading adds them, the plan of each run (turbo run … --dry=json) counts done the files of a task replayed from the cache, and, while every task has not started, the total of the previous pass of the same kind stands when it is greater (kept per repository in <git common dir>/grillhouse/avancement.json). The circuit names the directory of each pass in its state (the proof, the checks, the final pass, the verification of the integration, the queue) and the start of the survey of the components; the queue reads the CI with gh run view --json status,conclusion,jobs every 10 s instead of gh run watch, and writes its steps done over planned. The board shows 87/123 · il y a 8 s on the ticket's line at an automatic step (in place of the loops' counters when room lacks; the time alone at 1.1), ⚠ figée 12 min · 87/123 in red past 5 min (FIGEE), and a npm run verifier out of a ticket, named beside the lock of the machine, at the head of AGENTS (⏳ Mesure · <dépôt> · 51/123 · 3 s); the pane measures again every 10 s while such a line shows. Asked by Romain (2026-10-21). The common charter, the README and the headers say so.

[0.20.2] - 2026-10-21​

Changed​

  • The board names 1.2 « Questionnement » and shows the stops that go to the supervisor as his: the line of 1.2 was cut to the pane's 52 columns (1.2 · Questionnement du plan · questionneur ⇄ réf…), and a stop of the opening, which the circuit ends on for the supervisor with no regulator, stood under « ⤷ Arbitrage de l'arrêt · régulateur ⇄ questionneur » (Romain, 2026-10-21). The sub-step 1.2 is now « Questionnement », and a step of scripts/etapes.mjs may declare the short form of who works there on the board's line (quiCourt, read by quiDe): 1.2 shows questionneur ⇄ référent, the role keeping its whole name, « référent technique », everywhere else. The table of the stops gains its first two lines, composants-manquants (21) and questionnement (22), gesture superviseur; the board reads in it the stops that go to the supervisor and shows them under their step after « ⤷ Arrêt · superviseur », with the counters of their step (tour 4/4). The common charter, the skills of the regulator, the technical referent and the questioner, the README and the tracker's guide say « 1.2 Questionnement ».
  • A pass measures itself against the last green: a full npm run verifier red on one wrong test of 2 643 (the test, not the code), corrected, played again whole: 13 min for one test, since Turborepo plays the whole test:vitest of a package once one of its files changes. As vitest --changed, jest --onlyChanged and Bazel's cache by test target, npm run verifier keeps the tree of its last pass green on every package, per repository (<git common dir>/grillhouse/dernier-vert.json, scripts/dernier-vert.mjs), and, when that green's commit is an ancestor of HEAD, each package Turborepo plays again plays the tests Vitest relates to the files changed since it (Vitest's related, fed with the difference between the green's tree and the working tree, which --changed <ref> cannot read on an uncommitted lot); a package whose inputs did not move replays from the cache, the guards and the builds play as before, and the changes reach Vitest in a variable no hash counts (GRILLHOUSE_CHANGEMENTS, which globalPassThroughEnv now names beside GRILLHOUSE_RESULTATS; the generator adds it and the check refuses a root without it). A change Vitest's graph cannot see plays the package whole, the reason written (scripts/vitest-config/changements.mjs): a file removed, the frame's base configuration, the repository's or the package's configuration (package.json, package-lock.json, turbo.json, vitest.config.*, tsconfig*.json, its setup files), a path its tests declare they read (grillhouse.lit, now read at the root of a repository without packages too: Grillhouse declares the scripts its tests run), the code of a package it depends on (read built), and a file of the package no module can be (data, templates, shell scripts, documents). Without a green that counts, the pass is complete; npm run verifier -- --tout and --force (the night) play every test for real. The circuit's proof and checks (npm test under its mark, GRILLHOUSE_DEPUIS_LE_VERT) and its restricted final pass measure themselves the same way, a file named always played: a lot that changes one test plays that test. Decided by Romain (2026-10-21): « si c'est le test qu'on corrige y'a 0 raison de rejouer les autres tests, dans tous les cas ». The common charter, the project's CLAUDE.md, the READMEs and the headers say so.

[0.20.1] - 2026-10-21​

Changed​

  • A package's tests may declare they read a neighbour's code: in BPScript 320.3, the tests of 995-tools read packages/900-driver/test (capture scripts) and packages/000-forms/src/tables.ts, which the envelope now shows read-only, but the check refused a declared path holding code. As Bazel's data takes any file, grillhouse.lit and a trace's lit now take a path of code: the reader's test:vitest hashes it, so it replays when the path changes, and the path stays an input of its own package's build; only a path of data alone is still left out of that build. The check no longer refuses a declared path holding code. The grill skill, the tester's skill, the common charter, the README and STRUCTURE say so.
  • AGENTS shows every step of the process, empty ones included: since 0.20.0 the board's AGENTS section showed only the steps that held a ticket, and the owner, seeing step 3 alone, could not read the flow. It now shows every step of scripts/etapes.mjs in its order, each on its line « number · title · who »: an empty step in the discreet tone, a step with a ticket as a title with its tickets under it; a step with sub-steps folds while none of them holds a ticket (the next entry).
  • The survey of a ticket's components reads the types and the architecture: on the description of BPScript 320.3 before its run, the survey by the names missed 020-loader, whose sceneWritten (internal) writes the object of the scene into the Registry that load returns and 900-driver carries to 030-binder; it now finds it twice, by the types (« type Registry rendu par load, reçu par bind, transporté par 900-driver ») and by the architecture (« CADRE de 030-binder, Reçoit R3 »), in 5.5 s (1.4 s before), 15 components found, 8 of them unneeded by the run (4 before: 010-parser, 060-encoder, 150-renderer-audio and 150-renderer-ui join 090-ranker, 100-resolver, 140-scheduler and 990-corpus). As « find all references » of rust-analyzer and of TypeScript's language service, a new module, scripts/references-par-les-types.mjs, resolves each element the ticket names (a member Type.member and a function internal to a package included) in one language service over the components' tsconfig.json, a workspace import read back to its sources, and finds its references in the other packages; an internal declaration leads to the published exports of its package that reach it, and these to the functions of other packages that return a type they receive or receive a type they return, when one package references the other or a third references both. Each reader says by what (« appel de », « référence à », « type … rendu par …, reçu par … »). The survey also reads the items of « Reçoit » and « Rend » of the CADRE.md of the packages that declare an element; it keeps the survey by the names and the declared consumers, and a survey by the types that cannot run (no tsconfig.json, an error) says so and stands on the names. The explorateur's skill founds its decisions on CodeGraph, TypeScript's language service (by the survey) and the architecture documents, and searches the references by the types and by the architecture (Romain, 2026-10-21). sorties of scripts/frontieres.mjs is exported for it; README and STRUCTURE say so.
  • The steps of the circuit become its tree, with its loops, folded where nothing runs: the owner read the circuit in ten flat steps where a sub-step 2.1 Questionnement stood apart, chosen for a reason of the code (one loop per step), and the steps run for each component did not show they belong together. As a pipeline of GitLab CI shows its stages and their jobs, scripts/etapes.mjs now holds the tree of a ticket: 0 Exploration; 1 Ouverture (1.1 Relevé des composants, 1.2 Questionnement du plan, questionneur ⇄ référent technique, tour n/4); 2 Composants, for each component of the title (composant n/N): 2.1 Tests, 2.2 Preuve du rouge (essai n/3), 2.3 Code, 2.4 Contrôles (essai n/3); 3 Passe finale; 4 Relecture (tour n/3, back to 2 for the components named); 5 Intégration (5.1 Commit, 5.2 File : main, poussée, CI). « auto » replaces « automatique ». A step carries as many bounded loops as it needs, each by its key, which keys its count in the circuit's state (boucles: tests, code, relecture, arret, questionnement); the arbitrage of a stop (régulateur ⇄ questionneur, arrêt n/3) stands out of the sequence, under the stopped step. The sub-step 2.1 Questionnement and the numbering 1 to 10 are removed. The circuit writes its stops at the ticket in this form (« arrêt controles à 2.4 Contrôles »), and the regulator's instruction names the step so (« 2.3 Code »). The board's AGENTS section folds a step with sub-steps (▸) while none holds a ticket and unfolds it (▾) once one does, its empty sub-steps dimmed; a stopped ticket stands under its step after a line « ⤷ Arbitrage de l'arrêt · régulateur ⇄ questionneur », which unfolds the step, and no longer recalls the step it comes from (· de 5 Code). The common charter, the skills of the supervisor, the regulator, the questioner and the technical referent, the README, STRUCTURE and the tracker's guide say so.

[0.20.0] - 2026-10-21​

Changed​

  • A questioner asks its questions of the plan and of the regulator's decisions before anyone acts: in BPScript 320.3, four errors of judgement no mechanical rule catches cost the run: 5 decisions of the regulator wrong on the substance (one restored what criterion 1 removes), a developer who judged « intended » a defect of 030-binder, 5 findings of review visible long before the first review, and 040-checker named in criterion 13 and absent from the title; the owner observes that two to four questions of his, by intuition where a proposal seems unclear (« je n'ai pas compris », « illustre par un exemple »), find the right solution nine times out of ten. A new role agent, the questionneur (agent, skill, sheet, rights), is that look which did not write the proposal, as Amazon's bar raiser, a cockpit's challenge and response and the devil's advocate of a design review: it decides nothing, proposes nothing, writes no file and nothing at the ticket (no tool of writing, every write of bd refused), and reads the code by the index. Its instruction, a new template of consigne-agent.md, carries the proposal, the métacadre, the project's rubrics « Comment on arbitre » and « Ce qui monte au superviseur » (the common charter is in its context by CLAUDE.md), the ticket and the survey of its components, and no list of questions. Its sheet is issue QUESTIONS (each question with what it aims at: flou, intention, référence, règle, critère), AUCUNE or DÉSACCORD. The circuit leads the rounds, never side by side, as the sub-step 2.1 Questionnement of the list of the steps (its loop tour n/4 on the board), which numbers no step again: before the first tester, after the survey of the components, the plan, which the technical referent defends in a fresh session (a role the circuit now launches, its sheet reponses and the titre or description the plan becomes, which the circuit writes to the ticket by bd update, the survey then played again); and each decision of the regulator before the admission control, the regulator answering in its own session, resumed, the decision it ends on the one applied. Each answer changes the proposal (CHANGE, what it becomes) or keeps it (GARDE, why); the questioner reads it by resuming its own session; four rounds at most; the end is a sheet without question. A disagreement, or a fourth round still questioned, goes up to the supervisor: the new stop questionnement (22) for the plan, which --reponse lets pass from the first tester, never questioned again while its title and description stand; the regulator's question (18) for a decision, its session kept, its answer not questioned. The whole exchange is at the ticket (Circuit · … · questionnement), and the bilan counts the rounds, the proposals changed and those sent up, the questioner's time in a category of its own, kept. The supervisor's skill has his own plan questioned by the sub-agent questionneur before he gives it to the owner, answering in his own session. Measured cost: the questioner's first instruction is 9.2 KB on this ticket's own description (3.8 KB of it the description; 2.7 KB the métacadre), its schema 0.6 KB; a ticket gains one questioner session and, when it asks, one session of the technical referent on its plan, then one questioner session per decision of the regulator (the regulator answers in its own); each round past the first resumes a session. The charter, the skills of the supervisor, the regulator and the technical referent, the README and STRUCTURE say so.

  • A written policy of the stops, the regulator's decision checked before it is applied: in BPScript 320.3, 19 stops launched 19 sessions of the regulator for 22 decisions: 12 right, 5 relaunches identical to the one before, 5 wrong on the substance (three developers launched before their tester, a MONTE on « 995-tools out of the title » while the title named it, a relaunch against criterion 1), and 11 a mechanical rule would have taken. The list of the steps (scripts/etapes.mjs) now holds the table of the stops, TABLE_DES_ARRETS, as Zuul and GitHub's merge queue write their bounded retries: each kind of stop, its gesture and the case of 320.3 it settles. The circuit applies a mechanical gesture itself, written at the ticket as Circuit · … · arbitrage : <kind> → <gesture>: the same stop come back with nothing new (the copy and the description unchanged) ends for the supervisor; « à repasser » ends at 75; a red of another component goes to that component's developer, never to the one under way; a developer's sending plays the tester; a component added to the title before --reponse plays from its tester, with no regulator resumed. Findings to settle and what the table does not settle go to the regulator. Its decision passes an admission control on the state: a component out of the title, a developer before his tester, anything but a relaunch from a tester after a criterion was added, a false fact, or the same RELANCE with no new fact is refused, the session asked again once with the reason (a seventh template of consigne-agent.md), then the stop goes to the supervisor. The regulator's sheet carries faits (au-titre, hors-titre, rouge-de, sans-changement, sous-charge, with their component), which the circuit checks. Replayed on 320.3, 4 to 6 sessions of the regulator remain out of 19. The regulator's skill, the supervisor's, the circuit's header and the common charter say so.

  • The queue waits for no CI that does not exist, and the reviewer reviews the commit message and ranges the flagged words: in BPScript 320.3, the queue waited 120 s for a run of a CI the project does not have and wrote « CI non lue »; the commit 106c32c named none of the 10 deviations its criterion 15 required, the reviewer having written them as remarks under an ACCEPTÉ; a word the project's vocabulary guard flagged went up to the supervisor, then the owner, 2 h 30 late (about 15 min and one session more), the owner's answer being « c'est l'agent qui inspecte les résultats des tests qui doit faire ça ». As GitHub's required checks name what a merge waits for, scripts/integration/file.mjs now reads, in the commit it pushes, the workflows of .github/workflows that run on a push to the branch grillhouse.poussee.commit names (their on and its branch filters as GitHub reads them, by yaml, now one of the frame's tools); with none, it says so to the ticket in one line and waits for nothing; a workflow it cannot judge (a paths filter, a file it cannot read) counts as one that runs. As Gerrit reviews the commit message as code, the reviewer's skill puts each deviation a criterion requires at the commit into its ecarts, never into remarques; it ranges each word a vocabulary guard of the project flags on a line the lot touches: a legitimate use goes to the project's register of exceptions, in the lot, by a finding to the agent who writes it; only a real word of the language written in the code goes up to the owner, by the reviewer's new question, which stops the circuit at « besoin » before the commit, the answer reaching the next reviewer in its CONTEXTE. The reviewer neither looks for nor files a ticket: the circuit files the discoveries of its sheet. (grillhouse-3uv.89, L7)

  • After a review sent back, the circuit replays only what the fix changed, and the next review reads only the difference: in BPScript 320.3, the three rounds of review cost about 210 min: each played again the steps or the checks of every component (49.5 min of checks of components no finding named, 31 min for 900-driver alone) and the whole final pass; the second and third reviews read the whole lot again; a finding for the developer of 030-binder was lost because the proof of its component had no red (18 min, 2.04 $, one round more); the testers and proofs of three components already proven played again after 040-checker entered the title (29.1 min, 4.22 $); and the guards' findings on another package made the checks of the component under way red (12.4 min, 5.10 $). On a RENDU the circuit now plays only the components the findings name, then the final pass restricted to the packages the fix changes and their dependents, as Bazel plays the targets a change affects: the circuit keeps the lot each review read as a commit on the lot before (Gerrit's patch sets; git commit-tree of the copy's tree, its HEAD and index untouched), and the pass runs npm run verifier -- --filter=...[<lot read>...<lot now>] --filter=//, which Turborepo 2.11.8 reads from the merge base of the range; a single [<commit>] of the working tree is read against HEAD, which a trial repository showed. The whole final pass plays once before the integration, when it has not played on the lot accepted. The next review receives the command of the difference between the two lots, the files it changes and the findings before it; it judges each one lifted or not (a new field of its sheet, suivi, written with the verdict) and keeps what lies outside the difference for its remarks (grillhouse-3uv.86). A component's checks play its own packages and the findings of the guards on its own files; the others, a finding without a file included, wait for the final pass. A developer a finding names is launched whatever the proof finds. The state keeps atteints, each component the circuit carried through (a proof without a red for its developer, a delivery, green checks), in place of the one mark atteint, and verifie, the tree of the lot the last whole pass verified. The bilan reads the results the circuit keeps (<ticket>.fiches.jsonl: each sheet, each proof's and check's outcome, each stop) and the authors and times of the comments, never the lines Circuit · …, and the guard of free text covers it. npm run verifier with filters plays the time witnesses of the packages they choose alone. The reviewer's skill and template, the regulator's and the developer's skills and the common charter say so.

  • The components of a ticket are fixed at its opening: in BPScript 320.3 (2026-10-20), two components joined the title on the way, each by a stop that went up to the supervisor: 040-checker, named in criterion 13, whose test read the value the ticket removed, red at the first final pass (~16.5 min), and 020-loader, a provider of the path (2.5 to 17 min). A new module, scripts/composants-affectes.mjs, surveys a ticket as the « affected components » of a design document: for each element its Architecture section and its criteria name between backquotes, its provider (the component whose INTERFACE.md publishes it) and its readers (the consumers that interface declares, the components whose code imports it, the tests of other components that name it and import the provider), with the components the text names itself, then the title's list, the provider first. The explorateur runs it on the draft of a realisation ticket (--description <file>), whose title names the readers the ticket changes and whose Architecture says the survey; a component it finds that the ticket does not change is admitted out of the title with its reason (<ticket> --admettre <component> --raison <text>, kept beside the copy, a line at the ticket). The circuit runs it again before the testeur of the first component: a component it finds, the title misses and no admission covers stops it at once, before any session and without a regulator, at the new stop composants-manquants (21), the missing components at the head of its report; the supervisor adds it to the title, or answers why it stays out (--reponse), which the circuit writes at the ticket and keeps beside the copy. The stops and their codes move to the list of the steps (scripts/etapes.mjs). On the description of 320.3 before its run (1.4 s on BPScript), the survey finds 040-checker, by its name in criterion 13, and misses 020-loader, whose data reaches 030-binder through 900-driver, never by an import nor an interface; it also names four components the run did not need: 140-scheduler (criterion 13) and, by Level, 090-ranker, 100-resolver and 990-corpus.

  • Each role session receives the rights its skill names and the context of its role alone: in BPScript 320.3, every session started on ~50 k tokens before its instruction (the skills of every installed plugin, 27 KB; the supervisor's memory, 20 KB; the user's global instructions, which order to commit and push; a codegraph context of up to 29 KB), 4 agents relayed the session start's false « pas encore renseignés » for the packages their envelope hides, 47 calls were refused (the reviewer's git -C … diff, bd list; the regulator's every read of a 12.5 MB log, blind in 13 sessions of 19), the developers and testers edited 61 times by python3, sed -i or cat >, against 2 Write and 1 Edit, a tester ran npx vitest for 707 s, and the write locks of the agents' definitions never ran (a ticket's copy is a folder Claude Code has not trusted, where those hooks do not run). A new module, scripts/droits.mjs, gives each session the circuit launches (lancer.sh for the tester and the developer, the circuit for the reviewer and the regulator) its options from one table: --setting-sources project,local (the user's CLAUDE.md, hooks, account skills and servers out), --settings on the command line (the permissions drawn from the commands its skill names, the change of its author refused; for a role that writes, editing by script, the test tool run directly and the reading again of the ticket its instruction carries refused, and its locks as hooks: verrous/verrou.mjs, and verrous/commande.mjs, new, which refuses a shell redirection to a file of the repository; the automatic memory off; Claude Code's skills, every other skill of the project and every plugin off), --tools (no Edit or Write for the reviewer and the regulator; no Agent, Workflow, web), --strict-mcp-config --mcp-config (codegraph and rtfm for the reviewer alone). A guard, tests/unit/droits.spec.ts, fails on a command a skill names that no permission covers, and on a permission no command names. The skills now say it: the tester and the developer read their ticket in their instruction, never by bd; a file is written by Write or Edit; the reviewer reads the lot by git -C <copie> diff; the regulator reads the log by grep -n and tail -n, never whole; a role's definition says that its agent loads its skill on its first turn, since --agent preloads none. The regulator's instruction carries the stop's reds read in the structured results, each with its component (those of the stop's component and the ones before it, or every one at the final pass), apart from a reason that no longer repeats them. The session start and the structure guard say nothing to a role agent (agent_type of the hook's input). The register writes a session under the main tree of the directory it opened in (CLAUDE_PROJECT_DIR), not its shell's last directory, where git stops at a mount of the envelope (the 995-tools session of 320.3 written under packages/990-corpus/test/scenes). Measured on a trial copy of the frame, the context of the first turn falls from 32.8 k to 11.5 k tokens for the tester, 32.4 k to 12.6 k for the reviewer, 31.4 k to 10.9 k for the regulator.

  • One heavy measure at a time on the machine, the time witnesses alone, one supervisor per project, and the envelope shows what a component's tests declare they read: in BPScript 320.3, 9 final passes out of 9 met « à repasser » (CPU pressure 85–97 %) and ~25 min went to waiting for rest and replaying whole tasks (11 min 24 s for one test); 74 of the 121 min of final passes ran under a npm run verifier of the frame on the same machine, the rest under the load of the pass itself (66 tasks side by side); two supervisors of BPScript ran together and opened the same discovery twice; and 995-tools, whose tests read packages/900-driver/test and packages/000-forms/src/tables.ts, got 43 reds from its envelope over 12 sessions (55 min). Every npm run verifier and every heavy pass of the circuit (the proof, the checks, the final pass) now take the lock of the machine, one file of the user's cache shared by every repository (~/.cache/grillhouse/mesure-lourde.lock, scripts/verrou-de-machine.mjs), as GNU make's job server: a second measure waits for the end of the first and says whom for, a lock whose process is gone is taken over, and a child of the holder (the final pass under the circuit) plays under its lock; it replaces the supervisor's unwritten rule « une mesure lourde à la fois ». The pass bounds its tasks side by side to half the cores (--concurrency, which an argument replaces). A test file that imports mesurerAuRepos is a time witness: the pass leaves the witnesses out, then plays them in a pass of their own, one task and one file at a time, as Bazel plays a test tagged exclusive (GRILLHOUSE_TESTS carries the choice, temoins: 'hors' then 'seuls'); « à repasser » stays for a load that comes from elsewhere, and a delay past in an unmarked test still gets it. The session start takes a lock of the repository for the session (.git/grillhouse-superviseur.lock, scripts/superviseur.mjs), as Zuul has one scheduler; a second live session receives « Un autre superviseur tient ce dépôt » and the skill pitmaster says to tell the owner and launch no circuit; an agent's copy and a role's session take none. The envelope of a component shows, read-only, each path its grillhouse.lit and its traces' lit name in a sibling it hides. The base configuration gives each test file a lock of the machine of its own (machine.setup.mjs). The common charter, the skills of the supervisor and of the tester, the charter's commands and STRUCTURE.md say so.

  • Each ticket gets its bilan in figures, written by the circuit: the analysis of BPScript 320.3 (where 460 minutes and 54.93 $ went) was made by hand, from the register, the ticket's comments and the log. A new module, scripts/bilan.mjs, now computes it, as a blameless post-mortem of Google SRE opens on its figures and BuildBuddy measures a build from its events: from the register (each session's latest line and turns, the lines of the steps the circuit leads), the lines Circuit · … · of the ticket and the circuit's state, the wall time and its categories (work kept in the lot, relaunch without effect, regulator, wait for the supervisor, automatic steps with the final passes, replay of steps already green, time between steps), the sessions by role, the steps by title, the stops by kind, the tokens, the cache reads and the cost. The circuit writes it at each of its ends, integre or a stop handed to the supervisor, in one short comment Circuit · <composant> · bilan : …, keeps it in .claude/worktrees/<ticket>.bilan.json, and compares it with the project's bilan before, or with nothing; the board's card of the ticket opens on its key figures (time, share lost, sessions, cost). node scripts/bilan.mjs <ticket> prints it again, --garder keeps it as a base. A register line whose project is a folder of the main tree counts in its project.

  • Each session the circuit leads ends on a sheet, and the circuit reads nothing else: in BPScript 320.3 (2026-10-20), 8 relaunches of a tester came from the form of a line « vert attendu » alone, and two sendings to a tester were lost because the line « Agent : testeur » was read only at the start of a line. The tester, the developer, the reviewer and the regulator now run with claude -p --output-format json --json-schema <schema of the role>, and the circuit reads their sheet in structured_output: status (FAIT, BLOQUÉ with its reason, BESOIN with its question), the developer's sending to a tester, the tester's expected greens (file from the root, full name of the test or the whole file, reason), discoveries (filed closed by the circuit), deviations to name in the commit (its body), the reviewer's verdict and findings (which the circuit writes at the ticket for the human), the regulator's decision. A field exists only where a reader reads it; the schemas live in one module, scripts/resultats.mjs. A session without a sheet that conforms is resumed once with a short instruction, then the circuit stops at sans-fiche (12, formerly sans-passation). The lines STATUT :, Agent :, vert attendu :, the regulator's last line and the one-line final answer « passation au ticket » are gone, with their readers; the handover at the ticket stays, for the human. The tester's and developer's instruction is 191 bytes shorter (8 065 → 7 874 on one example); claude receives the schema beside it (1.0 to 1.5 KB). A guard (tests/unit/circuit-sans-texte-libre.spec.ts) refuses any regular expression of the circuit that is not listed with what it reads.

  • The checks read the results of Turborepo, Vitest and the guards, never the end of a log: in BPScript 320.3, the red of the guards was given to the component under way (16 sessions, 12.4 min, 5.10 $), and the 60 last lines of a log hid the real red behind the noise of a time witness (~44 min). Each command of the proof and of the checks now runs with its results directory (GRILLHOUSE_RESULTATS, passed through by the root's globalPassThroughEnv, which turbo-des-paquets.mjs writes and checks): Turborepo's summary (--summarize), Vitest's JSON report, and the guards' findings in SARIF 2.1.0 (ruleId the guard, file and line, level, message, its package and its kind, to fix or to settle), written by the frame's guards through the known debt and by a project's guards through ecrireSarif. Each red belongs to the component that holds its file; a red without a file (a project's guard without SARIF) waits for the final pass, where no component owns it. The report a developer receives names his own reds first, test or finding, file and message.

  • The board shows each ticket, at each instant, at its numbered step: the owner could not read where a ticket stood in its process; the board numbered the roles of the agents (0 to 5), and the steps the circuit leads itself (the proof, the checks, the integration, the queue) had no number and stood in a role's block. One list, scripts/etapes.mjs, now numbers the ten steps, the automatic ones included, as GitLab CI or Zuul name each stage of a pipeline: 1 Exploration, 2 Arbitrage, then for each component 3 Tests, 4 Preuve du rouge, 5 Code, 6 Contrôles, then 7 Passe finale, 8 Relecture, 9 Intégration, 10 File : main, poussée, CI; the circuit, the board, the common charter and the skills read it. AGENTS lists the steps that hold a ticket (« 5 · Code · développeur »); a ticket in a circuit stands at the step of its state, its subject and, every other 5 s, its component under way with its rank among the title's (030-binder 3/5), and from its second pass the counter of its step's bounded loop, declared with the step (essai 2/3, tour 2/3, arrêt 2/3); a ticket at the regulator recalls the step it comes from (· de 5 Code), and a stopped ticket's card says its step, its stop and its reason. The key grillhouse.roles of package.json no longer orders the board.

  • The agents of step 2 are named after what they settle: arbitre did not say it settles a design question, nor chef-de-chantier that it settles a stop of the circuit. They are now referent-technique (« référent technique ») and regulateur (« régulateur », the railway regulator, the build sheriff of Chromium), agents and skills, without an alias; the circuit writes the regulator's decision as Circuit · … · regulateur : …, its session under the author regulateur, its state key regulateur, and its arbitrage under « ## Arbitrage du régulateur ». The update of a project removes the former agents and skills.

  • One line « vert attendu » covers a whole adapted test file: in BPScript (vbwf.320.2.4.5.1), the tester wrote one line vert attendu : <test> — <reason> per test left green, most with the same reason (an existing test file adapted to a changed type): up to 14 KB per handover, and nine sessions of the tester served only to add these lines. A line vert attendu : <file> — <reason>, the file's path from the root as the proof names it, in bold or in code or neither, now justifies each green test of a test file HEAD holds; it excuses no red of the file, and on a new file it justifies nothing, which the proof's report says for that file. The lines per test stay valid, and the two forms combine. The report counts these greens among the justified ones, each naming the line of its file. The tester's skill and the first template of consigne-agent.md say so.

  • A tester or a developer who says a red is out of his reach stops the circuit at once: in BPScript (320.2.4.5.1, si61.8), the most frequent stop was « sans-livraison »: a developer relaunched up to three times on a red he could not lift (in the tests, the shared test material, a file out of his envelope, a decision out of his role), then the circuit read the failure from an unchanged component and launched a site manager to find out why. The handover of the tester and of the developer now ends on a status line, STATUT : FAIT, STATUT : BLOQUÉ — <reason> or STATUT : BESOIN — <question>, read as the line Agent : is, in bold or in code. A BESOIN stops the circuit at once at the new stop besoin (20), and a BLOQUÉ at the new stop hors-portee (19), the reason or the question at the head of its report, with no session more; the site manager is launched on them, as on any stop. A developer's BLOQUÉ with the line Agent : testeur <component> is the sending to that tester, as before; FAIT, or no line, keeps the circuit as it was. The instruction of the tester and the developer, their skills and the site manager's say so.

  • A relaunch of an agent on its step resumes its session, save the last: each relaunch of the tester after a refused proof, and of the developer after red checks, was a fresh session, which read again its whole instruction, its skill and the code for one new line of report. The first session of an agent on a step now opens under a session id the circuit sets (lancer.sh --seance, claude's --session-id), kept in the state (reprise); its relaunches on the same step and component resume it (lancer.sh --reprise, claude's --resume) with a short instruction, the sixth template of consigne-agent.md: the ticket, its component, what changed, the new report of the proof or the checks, and the handover with its status line. The last attempt, the developer's on the strong model and the tester's third, stays a fresh and whole session, and so does a resumption that fails (a code other than 0, or no handover). The envelope already mounted the transcripts of the copy's working directory in writing over the real directory, so a resumption finds them; the register keeps one line per session, its latest end, so a resumed session counts once.

  • The last handover of an instruction is the one of the session's own role on its component: in BPScript (vbwf.320.2.4.5.1), a developer of 050-emitter received as « the last handover » 14 KB of « vert attendu » of the tester of 030-binder, and after a RENDU each agent received the whole verdict, the findings for the other components included, beside its own as its report. That handover was the last comment at the ticket that was not the circuit's, whoever wrote it. It is now the last handover of the session's author, <rôle> <composant>; for a developer whose component has no handover of a developer yet, the last of the tester of his component; « aucune » otherwise. The verdict no longer enters it: its findings for the component come as the report already.

  • The reviewer's instruction no longer carries the criteria: its skill reads the diff without the criteria for its first passes, and its instruction gave the ticket's whole description at its head. The second template of consigne-agent.md now names only the path of the claims file, where the circuit writes the description, and says to read it when the skill says so.

  • The queue writes under its own author, file: its comments (« Sortie de la file », « La file garde la branche », « CI rouge », « CI non lue ») and its changes of a ticket were written under git's user, the author of the supervisor and of the owner. scripts/integration/file.mjs now runs bd under BEADS_ACTOR=file, as the circuit writes its own lines under circuit; the circuit reads the queue's comments by their heading, as before.

  • The skills no longer ask for writings without a reader: the developer's final report went to the log alone, the circuit reading the ticket; the hours of a handover, which the developer's skill, the tracker's conventions and the supervisor's closing asked for, are measured by the register, which no agent declares; the tester « warned the supervisor », with no means to in the circuit. The final answer of the tester and the developer is now one line, « passation au ticket », the developer's handover carries what his report said, and the tester's question goes by its line STATUT : BESOIN — <question>.

  • Each session reads the ticket as it is at its launch, its notes included: in BPScript (si61.8), the description was read once per run of the circuit, so a criterion the site manager added (bd update -d) before a RELANCE in the same run never reached the next session; and the ticket's notes, where a blocked developer writes the state of his work, entered no instruction. The circuit now reads the description at the launch of each session of the tester, the developer and the reviewer (its claims file), and the first template carries the ticket's notes in a section « LES NOTES DU TICKET », absent without notes.

  • The section « Ce que les composants d'avant publient » gives each provider's line and the names declared for the component, the rest at its address: in BPScript (2026-10-20), the section the launcher adds to each new session of the tester and the developer weighed 36 to 46 KB as soon as a component had providers, 64 % of the instructions of vbwf.320.2.4.5.1, 89 % of those of si61.8; for 030-binder it listed 692 elements of 000-forms, 94 of them declared for it, though the check of the consumers refuses the use of any other. The section is now the first level of a progressive disclosure, as the skills of Claude Code, llms.txt or Aider's repository map: for each provider, its line from the index of the interfaces, the names its ## Consommateurs line declares for the component, without their sentence, and the address of the rubric « Rend » of its frame instead of its text (2.2 and 2.6 KB for 001-kernel and 000-forms, which most components read); every element with its sentence stays in docs/agents/index-des-interfaces.md (level 2), and its section in the provider's interface (level 3). A declaration of * names no element and says so. The section of 030-binder goes from 45.1 KB to 2.9 KB, that of 900-driver from 65.2 KB to 8.3 KB. The section of a copy of the whole repository (.) is unchanged, and the relecteur receives the new one by the same command (index-interfaces.mjs --publie).

[0.19.1] - 2026-10-20​

Fixed​

  • A ticket's whole card shows every row of its text while it scrolls: the card drew a spare row above its rule only once the engine's window had moved, so each arrow shifted every row by one, a row came and went, and the last row of the text fell out of sight. The spare row is now always drawn, and the text takes one row fewer, so the window shows it whole on either of its rows.

[0.19.0] - 2026-10-20​

Changed​

  • A time budget bench or a night test named in a targeted run plays: in BPScript si61.8, the threshold of a bench raised, npm test -- <the bench> played nothing (« No test files found », code 1), since the day's configuration leaves out every *.budget.test.* and *.nuit.test.*; the proof of the red of the circuit counted the bench a file that does not load and stopped, and the reviewer, who may not run Vitest himself, judged on the night's measure. As Bazel's target tagged manual, out of every pattern and built when named, a bench or a night test whose own file npm test -- <path> names now plays in its package, under the duration reporter of the day's configuration: a failure of duration under load gives 75, « à repasser », which the circuit's checks play again as before. A directory or a package named still leaves them out, and npm test without a path, npm run verifier and the integration do not change. The patterns of the day's exclusions live in scripts/vitest-config/cibles.mjs, which the base configuration and the night's include read. The charter, the template's commands and the skills of the testeur and the reviewer say so.

Fixed​

  • A ticket's working time counts the steps its circuit leads itself: in BPScript si61.8, 47 min passed from the owner's go to the close, and the board showed 8 min for the ticket: it counted only the turns of the agents' sessions, and the steps the circuit leads with no agent, the proof of the red, the checks of each component, the final pass (npm run verifier), the integration and the queue, 33 min of the 47, counted nowhere. The circuit now writes each of these steps to the register of finished agents at its end, as a session's line (the role circuit, its ticket, step and component, its start and end, no tokens), and names the step under way in its state (mene); the board counts them, the step under way up to now, in the working time of the ticket, its line, its card, its chantier and the totals of the day and in all, out of the turns of its agents, so that an instant counts once. A line of the circuit is no passage of a role of the flow and shows in no block; the tokens do not change.
  • A test file changed no longer replays the builds and tests of every package depending on its package: in BPScript (si61.8), one test file of 030-binder changed made two npm run verifier take 33 min of 47; ~14 of them replayed the tests of its whole descent, 900-driver on the critical path. The build of each package hashed every file of its package ($TURBO_DEFAULT$), while its build compiles src only. The generated turbo.json of a package with a tsconfig.build.json now gives its build what it reads: the root's build inputs, its package.json, its tsconfig.build.json and what it extends in the package, <dir>/** per directory it includes (a listed file, its directory: test/fixtures.ts of the shared test material keeps test/**), and the same for each configuration a tsc of its build script compiles. A package without a tsconfig.build.json, whose build script runs another command than tsc (vite build, node copier.mjs), whose reads are unknown, or whose configuration the generator cannot read through, keeps Turborepo's default: it never gives a stale cache. The update of the frame regenerates the turbo.json of each package; the project has nothing to do.
  • A submodule no longer keeps the tests out of the cache in every copy: in BPScript (si61.8), the root test:vitest hashed $TURBO_ROOT$/vendor/bp3-engine/**, whose .git, in a copy, is a file naming that copy: each new copy changed the hash of every test, and the cache never served. Beside each input of the root's turbo.json (any task, or a global dependency) and of a package's that can reach the .git of a submodule .gitmodules declares, the update of the frame now writes its exclusion, !$TURBO_ROOT$/<path>/.git, the rest of the root's file kept; grillhouse:gardes refuses a root input still lacking it. The project has nothing to do.

[0.18.3] - 2026-10-20​

Fixed​

  • A red night's alert stands whole on its line: « La nuit est rouge depuis la nuit du 2026-10-16 » passed the 52 columns of the board, which cut its date. The alert now reads « Nuit rouge depuis le 16/10 ».

[0.18.2] - 2026-10-20​

Fixed​

  • A red night's alert gives the night it turned red, never a commit: since 0.16, the night names the night in the title of the ticket it opens, but a ticket opened before kept its title, « La nuit est rouge depuis 839dbb0 », and the board's alert showed that commit. The board now writes the alert of a red night from the date its ticket was opened, the night's date, whatever its title names.

[0.18.1] - 2026-10-19​

Fixed​

  • A file that vanishes while a guard walks the repository no longer stops the guard: npm run verifier plays the guards beside the tests, and Vite writes then removes vitest.config.ts.timestamp-<n>-<hash>.mjs beside a configuration of Vitest; in BPScript 320.2.4.5.1 the guard of the consumers listed that file, read it once it was gone, and stopped on ENOENT: the final pass was red without a fault, green again at the next one. The guards that walk the repository (the consumers, the faults of the interfaces, the data a package declares) now share one walk, parcourir of scripts/consommateurs.mjs, which passes over a file or a directory gone before it reaches it, reads a file listed tolerantly, and never lists Vite's temporary files.
  • --depuis <étape> <composant> plays in full the components after it that the circuit has not reached yet: in BPScript 320.2.4.5.1 the proof of the first component stopped; RELANCE --depuis developpeur spec then played only the checks of the nine components after it, never worked, and the reviewer sent the lot back: a whole pass lost. The state now keeps atteint, the last component the circuit has carried to green checks; a component after the one --depuis names plays its checks when the circuit has reached it, else its whole circuit, testeur, proof, developer and checks. The same rule holds for a RENDU of the reviewer and for a developer's sending to a tester.

Changed​

  • A question of the chef de chantier goes up to the supervisor: on MONTE, the circuit wrote « question du chef de chantier au responsable »; both questions of BPScript 320.2.4.5.1 were the supervisor's. The circuit, its header, the README, the skills of the supervisor and of the chef and the chef's instructions now say that the question goes to the supervisor, who answers himself what is his (the frame of the ticket, an arbitrage) and carries to the owner the functional and what the charter keeps for him; --reponse gives the chef the supervisor's answer, which may carry the owner's.
  • A changed type migrates at once the shared test material that reads it: in BPScript 320.2.4.5.1 a type changed in 000-forms broke the shared test material, which only the tester writes, and the developers of the components after it ran on that red for nothing. The tester's skill and first instruction now say that, when the ticket changes a type or a name of its component, the tester migrates in the same session the shared test material that reads it; the tests of the components after it, out of its envelope, go to their own tester.
  • The ticket's Architecture settles the consumers it names: the guard scripts/consommateurs-arbitres.mjs asked a settled « ## Arbitrage » comment for each new line of « ## Consommateurs », even for names the section « ## Architecture » of the ticket, born of the owner's word, already fixed: in BPScript 320.2.4.5.1 two questions went to the supervisor for nothing. A new line now passes too when the ticket's Architecture (its description, bd show <ticket> --json, from ## Architecture to the next heading of its level) names its consumer and each name it declares, word for word, * between backquotes.

[0.18.0] - 2026-10-19​

Fixed​

  • A verdict is the reviewer's comment, never an agent's handover that opens on RENDU: the circuit and the integration took for a verdict any comment whose first word was ACCEPTÉ or RENDU; in BPScript 320.2.4.5.1 a developer's handovers began with « RENDU 000-forms … », the circuit counted four reviews instead of two and stopped at « relecture-arret ». Each comment at the ticket now carries its author: the circuit launches each session with BEADS_ACTOR naming its role (testeur <composant>, developpeur <composant>, relecteur, chef-de-chantier), which the envelope passes on, writes its own lines as circuit and the reviewer's verdict as relecteur; a verdict is a comment of the author relecteur whose first word is ACCEPTÉ or RENDU, in the circuit, the integration and the board. The rights of every session refuse bd's --actor, -a/--author and the variable BEADS_ACTOR, so that no agent changes its author. A project installs this version between two tickets: the verdicts of a ticket in progress were written without the author relecteur.

Changed​

  • A red the developer leaves in a component's tests goes straight to its tester: a change of type broke the existing tests of a component; the developer, who writes no test, was relaunched up to three times on that red, then the circuit stopped at « sans-livraison » and the chef de chantier relaunched the tester. The developer's handover may now carry the line Agent : testeur <composant>, a component of the title already played or its own: the circuit plays that component again from its tester, the handover as its report, then the components after it, as a chef's RELANCE --depuis testeur <composant>, without relaunching the developer nor stopping. The same sending twice in a row without green checks between them stops at « sans-livraison », for the chef.
  • A test the tester adapts carries its « vert attendu » from its first session: nine tester sessions only added the lines « vert attendu » for existing tests rewritten to a changed type, green by nature on the present code. The tester's skill and instruction now say that such a test carries its line vert attendu : <test> — <raison> in the first handover.
  • A component without tests goes straight to its developer: a component of documentation alone saw three tester sessions without a test, then a stop at « preuve » and a chef. A component no package with a script test:vitest lies in or holds (the rule by which npm test -- <chemin> refuses a path) now skips the tester and the proof: the circuit writes Circuit · <composant> · testeur : aucun test … at the ticket and launches its developer, then its checks.

[0.17.4] - 2026-10-19​

Fixed​

  • A circuit's line on the board shows its ticket's working time and tokens again: since 0.16.5, a ticket in a circuit stands on one line, which showed only where the circuit is, or its stop; the time and tokens its agents spent, which its line under the running role carried before, were gone. The line now shows them after its step or its stop, as every other ticket's line does.

[0.17.3] - 2026-10-19​

Changed​

  • An answer of the chef de chantier in no form of decision is asked again once: the circuit ended on its stop and woke the supervisor, who then did the chef's work. It now resumes the chef's session once, with its whole context, asking for its decision in one of its forms; only a second answer in no form ends the circuit on its stop. A session in error is not asked again.

[0.17.2] - 2026-10-19​

Fixed​

  • The chef de chantier's decision may follow its reasoning: the circuit read the decision from the first line of the chef's answer only, and a chef that wrote its reasoning first, then RELANCE --reprendre and its CONTEXTE, ended the circuit on its stop, « sa réponse ne suit aucune forme de décision ». The circuit now reads the last line in a form of decision, with the CONTEXTE line after it, the reasoning before it left out; the chef's skill and instruction say the decision ends the answer.

[0.17.1] - 2026-10-19​

Changed​

  • The chef de chantier's CONTEXTE speaks to the one agent it relaunches: a chef relaunched the developer of one package with a context that also planned the work of the next package, which that developer cannot write. The chef's skill now says that the context carries only what the relaunched agent does in its component; work for another component goes to the ticket, in the chef's arbitration, where that component's agent reads it.

[0.17.0] - 2026-10-19​

Changed​

  • The circuit settles its own stops with a chef de chantier session: on a stop other than 0 and 75, the supervisor launched a chef de chantier subagent, which relaunched the circuit in the background and stayed parked until its end; each relaunch woke the supervisor with a notice that the chef waited on its own work. The circuit now launches the chef itself, as it launches the reviewer: the chef's final answer is its decision (RELANCE --reprendre, RELANCE --depuis <testeur|developpeur> <composant> with an optional CONTEXTE : line, or MONTE : <question>), which the circuit writes at the ticket and applies in the same process. A question ends the circuit on the new stop question (18), the chef's session kept; circuit.mjs <ticket> --reponse "<texte>" resumes that session with the owner's answer. An unreadable decision, or a chef session in error, ends on the original stop; the stop that comes back after three RELANCE in a row ends the circuit. The supervisor launches the circuit once and is woken only by the end of the lot, a question, or a stop the chef did not settle; the board shows the circuit in block 0 while the chef decides, and the question at the head of its card. A project updates its supervisor's habits: no chef subagent any more, --reponse after the owner's answer.

[0.16.5] - 2026-10-18​

Changed​

  • A circuit's ticket stands on one line of the board, in its role's block: it was drawn under « circuits » on its line, a second line for its step, a third for a stop's reason, and again under the role that ran in it. It now stands once, in the block of its step's role (the testeur's for the tests and their proof, the developer's for the code and the checks, the reviewer's for the review and the integration) with its step, attempt and component, or, stopped, in the site manager's with its stop and code; the reason of a stop opens its card.

[0.16.4] - 2026-10-18​

Fixed​

  • A finding addressed to the root component reaches it: the line Agent : developpeur . lost its . with the punctuation that ends the line, and the circuit stopped at « relecture-arret » on a finding with no recipient. The root . is now kept.

[0.16.3] - 2026-10-18​

Fixed​

  • A resumed developpeur whose lot is delivered goes on to the checks: after a stop at the developpeur's step, --reprendre launched it again, and a session that found its lot complete changed nothing and stopped the circuit at « sans-livraison ». The first session of a resumption, on a component that already holds changes, now goes on to the checks, which judge the lot.
  • Every read of bd has room for a long ticket: the circuit's reads were fixed in 0.16.1, but the guard of the arbitrated consumers, the queue, the integration, the write locks, the one-commit-per-ticket hook and the board still read bd within the 1 MiB a child process returns by default; past it, the guard of the arbitrated consumers failed in the final pass. Every call of bd now gives its output 256 MiB, and a test refuses one that does not.

[0.16.2] - 2026-10-18​

Fixed​

  • /grillhouse answers at once on a large project: the command waited for the board's measure, some seconds on a large project, twice when a refresh was running; past the 10 s a hook is given, Claude Code skipped it and printed « no command.run hook answered it ». The command now opens the pane and answers, and the board is measured behind it.

[0.16.1] - 2026-10-18​

Fixed​

  • The circuit reads the comments of a long ticket: past 1 MiB, the read of the ticket's comments failed in silence, and the circuit saw no handover after a session that wrote one (« sans-passation »); it now reads up to 256 MiB, and a failed read stops the circuit with bd's message.
  • The proof's comment at the ticket stays short: it holds the reds and what refuses the proof; the justified greens and their reasons, which made a comment of about 100 KB on a lot of 300 tests, go to the whole report, .claude/worktrees/<ticket>.preuve-<n>.md, which the comment names. The developpeur's instruction receives the same short text.

[0.16.0] - 2026-10-18​

Added​

  • The meta-frame and the common charter: METACADRE.md states the six intentions every rule serves and how a rule is written; .claude/grillhouse/charte.md holds the rules shared by every project, which each project's CLAUDE.md imports.
  • The grill: the grill skill initialises a project (structural survey, owner's decisions, charter, architecture, frame, interfaces, lexicon) and settles every structure decision; a hook sends a structure question to it.
  • The roles: the supervisor (pitmaster), the site manager (role 0), the explorer, the arbiter, the tester, the developer and the reviewer, each a project agent under its write locks (scripts/verrous/).
  • The tickets: Beads holds the tickets; each ticket is created under its mother, carries numbered acceptance criteria and one delivery, and a hook refuses a second commit for a closed ticket.
  • The envelope: a role agent works in a bubblewrap envelope that shows its component and only the published parts of the others (scripts/enveloppe/).
  • The controls: the boundaries of the code (dependency-cruiser), the written interface against the code (API Extractor, TSDoc), the declared consumers of each interface, dead code (knip), out-of-frame packages, all played by npm run grillhouse:gardes.
  • The known debt: a project records the findings of the controls in grillhouse-dette.json; a control then refuses only a new finding.
  • Turborepo: npm test and npm run verifier run the build, the controls and the tests through Turborepo and its cache; each package's turbo.json is generated, and a package declares the data its tests read and the traces it writes.
  • The verification: npm run verifier plays every control and every test, names each red, and replays at rest a time verdict taken under load (« à repasser »).
  • The integration queue: the integration commits a lot on its ticket's branch, and a queue brings the branch to main and reads the CI of the commit it pushes (scripts/integration/).
  • The circuit: one command (scripts/circuit.mjs) leads each component of a ticket from the tester to the developer, then the reviewer, then the integration; a fresh site manager settles each stop.
  • The night: scripts/nuit.sh plays every suite, the night tests and the time benches, and pushes its green commit to the night branch; a red night opens a ticket that names it.
  • The frame's update: npm run grillhouse:maj brings a project's frame files (.claude/grillhouse/fichiers.txt) to Grillhouse's last version, with its hooks, scripts, plugins and generated files.
  • The board and the pane: npm run tableau measures the project's state (chantiers, agents, tickets, working time); the Grillhouse mod shows it in a pane beside the transcript, and the status line shows the chantier in progress.
  • Shared submodules: a working copy reads a submodule of the main repository, read-only (grillhouse.partage).
  • The version of the frame: one version for the frame and its mod, in .claude/grillhouse/VERSION, which each project receives, so it knows the version it has; the mod's plugin.json carries the same, and a test refuses a gap. The report of npm run grillhouse:maj names it (« Cadre 0.16.0 (commit …) »). Grillhouse's release (scripts/sortie.mjs, Grillhouse's own) raises it, dates this changelog and tags the release commit locally.

Changed​

  • The tests run under Turborepo: the home-made cache of suites and builds and its launcher are gone.
  • A realisation ticket names its components, provider first, and the circuit launches one agent per component.

Removed​

  • The integrator role: the circuit launches the reviewer and integrates the lot.

Fixed​

  • The package.json of the shared test material is the tester's: the tester's skill gave every package.json to the developer, whom the lock refuses in that package; it now says what the lock does, the material's package whole to the tester, another package's package.json to the developer.
  • The report of the checks names where they played: the final pass reads « hors enveloppe, sur la copie entière », a component's checks name their component and their scope, so a developer no longer takes a real red for an envelope's.
  • The site manager runs the circuit as it is: its skill prescribes the command alone, without redirection or chained echo, so the task ends on the circuit's own code.