Dossiers .bl.org qui répondent
Un dossier est un fichier .bl.org. Il est la source, la page, la spécification exécutable et la feuille de réponses. Un petit serveur Beam Lisp (le kit, à côté de ce fichier) le rend avec la partition bl.doc.spans réelle, le publie sur le tailnet, et écrit chaque réponse donnée par le lecteur dans le bloc qu'elle répond. Pas de base de données, pas de deuxième copie : git diff montre ce qu'Othman a dit.
Exemple, à lire avant d'en écrire un nouveau :
~/projects/tiny-tools/mobile-app/dossier/pocket-harness.bl.org (renommé de baton.bl.org le 2026-10-31).
Un exemple orienté desktop avec bureaux et cycle de vie exécutable :
~/projects/knowledger-interface-review/docs/reports/interface-review-20261031/knowledger-interface.bl.org.
Le goût dont il descend : ~/code/undefine/omega/spikes/mobile/design-review/design-review.bl.org.
La boucle
- Recherchez d'abord. Appuyez chaque affirmation sur un chemin de fichier, une commande que vous avez exécutée, ou une source citée.
- Écrivez
NOM.bl.org(structure ci-dessous). Les cellules n'ont pas de#+RESULTSécrit à la main — laissezbl doc runles écrire. bl doc run FICHIER.bl.orgpuisbl doc run FICHIER.bl.org --check(exit 0 = cellules vertes et résultats à jour).- Regardez-le en largeur de téléphone avant de prétendre quoi que ce soit (voir Le voir).
- Publiez :
Le fichier d'environnement contientwork serve NOM --http auto --cwd ~/.claude/skills/bl-org-dossier/kit \ --env-file ~/.config/baton-dossier/service.env --ready-timeout 120 \ -- /etc/profiles/per-user/othman/bin/bl serve serve.bl -- /abs/path/NOM.bl.orgDOSSIER_OWNER=du login Tailscale du propriétaire ; seule cette identité peut répondre (Serve définitTailscale-User-Login; vérifié le 2026-10-31).DOSSIER_HANDLE=timinouest le nom que les réponses portent dans:by; un login (un email) n'est jamais écrit dans le fichier. Le serveur relit le fichier à chaque requête : modifier le.bl.orgne nécessite pas de redémarrage. Modifier le code.bldu kit le nécessite :work restart NOM. - Lisez les réponses :
Les réponses se trouvent sur l'en-tête du bloc :bl run ~/.claude/skills/bl-org-dossier/kit/answers.bl -- /abs/path/NOM.bl.org:answer B :at "2026-10-31 17:14" :note "…". Agissez dessus, mettez à jour le dossier (basculez le:statusd'une décision surdecided, déplacez un en-tête de roster vers DONE), et dites ce qui a changé.
Structure (le goût d'Othman)
Ouvrez avec la thèse, terminez par ce qu'il doit décider. Entre les deux, gagnez chaque section.
#+title:nomme la chose et sa promesse.#+subtitle:une phrase.#+kicker:où elle vit.#+status:honnête (Proposition · rien de construit encore).- En un souffle —
lede+stats. Deux courts paragraphes, quatre chiffres. - Définissez les mots —
termspour chaque nom sur lequel vous vous appuierez. Si une phrase comme "sans couture" porte la demande, décomposez-la en les différentes promesses qu'elle cache, et dites ce qu'elle ne signifie jamais (honest). - Jobs — un
jobpar moment d'utilisation, chacun avec la manière du produit de référence et une décision. - Écrans — blocs
screen, tirés du texte. De vrais noms, de vrais dépôts, de vraies machines issues de l'environnement réel — jamais de lorem ipsum. - Comment ça marche vraiment —
sequencepour tout ce qui traverse un fil ;graphpour la topologie ;rosettapour une idée à travers plusieurs systèmes. - Le modèle, exécutable — cellules Beam Lisp avec des
assertqui fixent les invariants de la conception. Le résultat imprimé sous chaque cellule est la preuve. - Antécédents —
matrix, sources listées, affirmations tierces étiquetées comme provenant de la documentation. - Décisions (
decision, avec les options rejetées visibles) → Questions (ask) → Roster (* TODO/DONEen-têtes avec:PROPERTIES::JOBS: :AREA: :PROTO:). - Le texte est court. Le placement et le poids portent l'état. Pas d'adjectifs marketing. Dites ce qui n'est pas vérifié.
Composants
Attributs d'en-tête : :key value ou :key "valeur citée". Les corps sont des langages de lignes ; lignes a | b | c sauf indication contraire.
| Bloc | Corps | Rendu |
|---|---|---|
lede | prose | grande ouverture sérif |
stats | valeur | étiquette | note | tuiles de statistiques |
terms | terme | signification | liste de définitions |
principles | titre | texte | cartes numérotées |
note / warning / honest (:title) | prose | encadrés (ardoise / argile / ocre) |
rosetta | première ligne = en-têtes | tableau aligné ; cartes sur téléphone |
matrix | première ligne = en-têtes ; cellules y, ~, n + mots optionnels | matrice de points avec légende |
job :id :title :codex :claude :decision :screen | la phrase JTBD | carte job + réponse |
decision :id :title :status proposed|decided | - [x] choisi, - [ ] rejeté, puis justification | carte décision + D'accord/À retravailler/Pas d'accord |
ask :id :title :options "A|B|C" | contexte | carte question + options |
screen :id :title :job :caption [:theme dark] | langage d'écran (ci-dessous) | maquette téléphone + réaction ; les écrans consécutifs forment une bande défilable |
desk :id :title :job :caption [:url] | langage de bureau (ci-dessous) | cadre d'appli desktop + réaction ; mêmes boutons de réponse que les écrans |
sequence :title | lanes a · sub | b · sub, a -> b : label (appel), a --> b : label (réponse), a => b : label (le moment clé), note a, b : texte, == divisor | SVG sur écrans larges, étapes numérotées sur téléphone |
graph :title | node id | label | sub | col,ligne | tonalité (you door station builder foreign), edge a -> b | label | style (baton solid dash none ; <->, -- aussi) | topologie SVG |
schema :id :title | non indenté entity @icône | glossaire ; indenté attr type | note. Types : text date, -> genre (réf), ->> genre (plusieurs), a > b / c (flux d'état), a, b, c (énumération) | cartes d'entités, les références pointent vers #entity-NOM, un compteur d'entités · attributs · états ; avec réponse |
procedure :id :title :makes | step @icône Titre | qui | nom · genre, … (produit ; un troisième · draft = le harnais le rédige au début de la tâche), check @icône Titre | qui | nom, … (conseil d'un vérificateur, agent ou personne), gate @icône Titre | qui | nom, … (attend un transfert) ; qui nomme un rôle ; les autres lignes sont de la prose | un rail d'étapes, les vérifications en pointillés, les portes en losanges ; avec réponse |
Un bloc schema ou procedure est aussi la source qu'une cellule peut compiler : bl doc run
passe le fichier dans (BeamLisp/argv), donc une cellule peut lire son propre bloc et le transformer en
attributs datom ou tâches (exemple : team-machine/design/work/WORK.bl.org, cellules spine, procedure).
Langage d'écran, un verbe par ligne : bar Titre | droite (< Titre ajoute un retour), sub, chips a* | b (* = sélectionné),
section Étiquette | compte, card tonalité | titre | méta | corps (tonalités turn approve run done fail idle),
ask, actions Primaire! | Simple | Calme? | Danger^, msg vous|agent | texte, tool étiquette | détail,
diff +12 −3 | chemin, code texte, strip tonalité | texte | bouton, row étiquette | valeur, banner warning|ok | texte,
dest icône | titre | corps, note, spacer, input placeholder | ↑,
lock heure | date + notif app | titre | corps | Action, Action (avec :theme dark),
sheet Titre — tout ce qui suit se trouve dans une feuille en bas de l'écran.
card tonalité | titre | méta | corps | @check! @x @next? — une cinquième colonne place des actions sous forme d'icônes sur la carte
(dites ce qui est nécessaire dans la carte, gardez les actions en icônes ; Othman trouve les lignes de boutons difficiles à analyser),
machine tonalité | @serveur nom | rôle | détail | droite (tonalités up busy asleep you),
search placeholder + pick @dossier nom* | détail | droite (un sélecteur de projet, * = choisi),
listen indice (micro + forme d'onde), heard transcription, intent @envoyer Verbe | cible | texte (voix),
choices A | B* | C (une question à choix multiples, * = sélectionné), reply placeholder (une réponse en texte libre avec micro et envoi).
Les faits secondaires sur pick et machine se fondent dans le texte ; les actions des cartes se placent sous les mots.
Langage de bureau — tous les verbes d'écran, plus les régions desktop et un document :
nav @home Accueil* | @matter Affaires (barre latérale, * = ici), crumb a › b,
head Titre | tonalité · Statut | Action! | Autre? (l'emplacement d'action, en haut à droite), meta a | b, tabs,
col doc|rail|main (colonnes ; doc dessine du papier ; répétez col main pour une rangée de cartes),
page Titre, para texte avec {+inséré+} {-supprimé-} {~proposé~} {!à vérifier!} ‹P-01› (puce source) ^1 (ancre de commentaire),
point tonalité | @icône genre | titre | corps | Option* | Option, comment 1 | qui | texte (même nombre que son ^1), opts A* | B.
Les lignes avant le premier col couvrent toute la largeur. Les bureaux utilisent la palette Warm Signal de Knowledger (lampe en mode sombre).
Icônes : @nom n'importe où dans une ligne d'écran ou de bureau dessine une icône linéaire — home matter library playbook people audit settings search plus send file word check x alert clock user bot chat comment link seal eye edit version diff filter more back next down up bell wait calendar scale flag play undo lock attach grid list board split spark. Préférez une icône à un mot pour désigner des types de choses.
Blocs avec réponse : ask decision screen desk job schema procedure. Chacun nécessite un :id unique.
L'Org simple fonctionne aussi : en-têtes avec mots-clés TODO et tags, tiroirs :PROPERTIES: (puces),
tableaux, listes, cases à cocher [ ]/[X], =code=, *gras*, /italique/, [[url][étiquette]], [[#screen-ID][étiquette]].
Cellules exécutables
#+begin_src beam-lisp :id lifecycle
(ns project.model) ; la première cellule nomme le namespace ; toutes les cellules le partagent
(defn advance [s e] …)
(assert (= … …)) ; un échec d'assert devient le résultat et --check quitte avec 1
{:what "la dernière valeur est la preuve imprimée"}
#+end_src
Uniquement #+begin_src beam-lisp en minuscules (majuscules ne s'exécute jamais). Modélisez les
invariants de la conception (un seul rédacteur, ordre des effets, couverture d'un mapping), pas des banalités.
Pièges Beam Lisp rencontrés en écrivant ceci (bl installé, 2026-10-31) :
pas dans le cœur — ffirst, reductions, spit, replace, format, parse-long, prn.
Utilisez File/read!, File/write!, File/rename!, String/replace, Regex/run|scan|split|replace,
erlang/binary_to_integer, (println (pr-str x)). Les arguments s'évaluent de droite à gauche.
Ne nommez jamais une fonction publique d'après une fonction du cœur. Les enfants Hiccup doivent être des seqs (map/for), pas des vecteurs :
(map identity v).
Le voir
chromium --headless=new --no-sandbox --hide-scrollbars --window-size=412,16000 \
--virtual-time-budget=5000 --screenshot=/tmp/d.png http://127.0.0.1:PORT/
nix shell nixpkgs#imagemagick --command magick /tmp/d.png -crop 412x1000+0+0 +repage /tmp/d0.png
Pages de plus de 16000 px : sauvegardez le HTML avec les section.parts précédentes cachées et capturez-le.
Vérifiez : largeur de téléphone en premier, chaque diagramme lisible, les deux thèmes, aucune cellule ✗ failed.
Le lire comme une application
Sur un écran large, la page est une application à deux colonnes sans modification du fichier : chaque
en-tête de niveau 1 devient une page dans une barre latérale (avec ses en-têtes de niveau 2 en dessous
lorsqu'elle est ouverte). Une section montre combien de réponses elle attend encore, un ✓ une fois
répondu, et un roster avec son DONE/total. Une section s'affiche à la fois, avec précédent/suivant
à son pied et ←/→ pour se déplacer. #all (« Document entier ») montre tout ; n'importe quel #ancre ouvre la section qui le contient. Sur un téléphone, les puces changent de section de la même manière. Écrivez les en-têtes de niveau 1 comme les pages du rapport et les en-têtes de niveau 2 comme leurs parties.
Langages de conception
Les maquettes peuvent porter le vrai langage de conception d'un produit. #+design: forest en haut d'un
dossier dessine chaque screen et desk dedans (un bloc peut le remplacer avec :design NOM,
ou s'en désister avec :design none) ; les lignes de maquette ne changent pas. Préférez le langage du produit
lui-même plutôt que la palette par défaut du kit quand il en existe un.
Un langage est un module littéraire, kit/dossier/design/NOM.bl.org, dont les cellules sont le
namespace dossier.design.NOM : tokens (clair et sombre), échelle typographique, rayons, ombres,
tokens de mouvement, et le CSS qui relie les variables de maquette du kit. Enregistrez-le dans
kit/dossier/design.bl. Le même fichier est sa page de spécimen, à travers quatre blocs qui se
représentent eux-mêmes à partir du module : #+begin_palette, #+begin_type, #+begin_shape,
#+begin_motion (chacun avec :design NOM, corps vide). Gardez une cellule parity qui vérifie
les tokens par rapport au CSS livré du produit ; le test du kit affirme qu'il n'y a pas de dérive.
Livré : forest — Nurturing Forest, l'équipe machine d'Ora (design/forest.bl.org,
publié comme le service forest-language).
Kit
kit/serve.bl (routes / /doc /rev /src /answers POST /answer), kit/answers.bl,
kit/dossier/{org,attrs,ui,page,answer,design}.bl (pur), kit/dossier/design/*.bl.org,
kit/style.css, kit/live.js.
Tests : bl test -p ~/.claude/skills/bl-org-dossier/kit kit/test/kit_test.bl.
Un nouveau composant = une fonction -h dans ui.bl, un cas dans block->h, du CSS, une aiguille dans le test.
Les réponses sont écrites par patch-line : seuls :answer :note :at :by changent ; chaque autre octet du fichier reste.
Le skill vit dans ~/projects/enchanted-skills/bl-org-dossier (le dépôt public
undefine-org/enchanted-skills) ; ~/.claude/skills/bl-org-dossier est un lien symbolique vers lui.
Il est partagé par chaque session qui utilise ce skill. Validez au fur et à mesure, une idée par
commit, et ne staginguez que vos propres fichiers (git status d'abord : une autre session peut être en train d'éditer). Un
work restart d'un service de dossier charge ce qui est sur le disque, modifications non commit incluses.
Gardez les réponses d'un lecteur dans leur propre commit dans le dépôt du dossier, ainsi git diff montre ce qu'ils ont dit.