Tech Lead's Club - Spec, Lean
Friere die Verpflichtungen ein. Befreie den Plan. Beweise es mit jemandem, der es nicht gebaut hat. Abgeleitet von tlc-spec-driven 3.3.0 (Felipe Rodrigues), tlc-plan und tlc-implement.
┌──────────┐ ┌───────────┐ ┌─────────┐ ┌──────────┐
│ PLAN │ → │ CHECKS │ → │ BUILD │ → │ VERIFY │
└──────────┘ └───────────┘ └─────────┘ └──────────┘
lies es Verpflichtungen deine immer
Vier Schritte, zwei Artefakte vor dem Code, eines danach. Ein Mensch bestätigt was wahr sein muss und wie es in einem Dokument gebaut wird, und erst dann wird etwas zu einer Verpflichtung mit einem Beweis. Es gibt keine Aufgabenaufteilung, und der Plan enthält kein Komponentenverzeichnis: Was schwer umkehrbar ist, erhält eine One-Way-Door mit seiner wörtlichen Form, und alles Umkehrbare wird während des Bauens entschieden und im Diff überprüft.
Warum diese Form
Das dominierende Versagen eines Codierungsagenten ist nicht schlechtes Denken, sondern eine Anforderung, die gelesen wurde und nie zu einer aktiven Verpflichtung wurde - und dann ein Fertigstellungsanspruch darauf. Die Maßnahme, die gut abschneidet, ist eine kleine, eingefrorene, externe Verpflichtungsmenge plus ein Prüfer, der nicht der Autor ist; eine Selbstprüfung reproduziert den eigenen toten Winkel des Autors. Also gibt diese Fähigkeit ihr Budget für diese beiden Dinge aus und weigert sich, es für die Choreographie auszugeben, wie das Modell arbeitet.
Zwei Konsequenzen, die es wert sind, vorab erwähnt zu werden, weil sie dies von einem konventionellen spezifikationsgesteuerten Ablauf unterscheiden:
- Granularität ist keine Qualität. Das Aufteilen einer Funktion in fünfzehn Ein-Datei-Aufgaben erkauft Reihenfolge, nicht Korrektheit, und es kostet ein erneutes Lesen des Prozesses bei jeder Aufgabe. Beweisabdeckung erkauft Korrektheit.
- Ein Plan, dem das Modell gehorchen muss, konkurriert mit den Verpflichtungen um Aufmerksamkeit. Felder wie
Wo,Werkzeuge,Hängt ab vonsind die Aufgabe des Modells zu entscheiden, also werden sie nicht aufgeschrieben.
Kritische Regeln
Der festgesetzte Satz. Diese gelten auch, wenn keine Referenzdatei gelesen wird, und sie sind die einzigen Regeln, die nie mit dem Profil herunterskaliert werden.
- Jeder Check ist eine beobachtbare Behauptung mit einem konkreten Wert plus der Beweis - der Test oder Befehl, dessen Exitcode ihn entscheidet. Kein Beweis, kein Check.
- Tests behaupten, was die Checks sagen, niemals, was der Code zufällig tut. Schreibe niemals einen Test, indem du die Implementierung liest.
- Schwäche niemals eine Behauptung, lösche einen Test oder überspringe einen, um eine Suite bestehen zu lassen. Ein wirklich falscher Check ist ein Stopp-und-Frag, keine Bearbeitung.
- Checks und
Test policy-Zeilen sind nach der Genehmigung fixiert. Im Design sindLanding,RelationsundSurfaceadditiv - eine Tür, die während des Bauens entdeckt wird, erhält eine Zeile vor dem Code, der sie schließt, und eine Zeile, die der Benutzer genehmigt hat, wird niemals umgeschrieben.FlowundImpactsind keines von beiden: sie werden wahr gehalten, also ändert ein anderer Pfad den Hop im Commit dieses Pfads. - Der Prüfer ist ein frischer Sub-Agent, niemals der Autor, niemals optional, niemals wartend, um
gefragt zu werden. Wer die gesamte Funktion hält, sendet ihn ab, nachdem der letzte Commit der Funktion
gelandet ist - über
<feature base>..HEAD, mit jedem Check. Niemals von einem Ersteller, und niemals als Kind von einem. Ein Ersteller beendet, berichtet und stoppt. Die Arbeit ist nicht erledigt beim letzten Commit; sie ist erledigt, wenn der Bericht des Prüfers jeden Check berücksichtigt. - Das Profil ist eine Untergrenze und kein Geheimnis. Der Prüfbericht nennt es, oder „keine Fehler injiziert“ liest sich genau wie das Vergessen, sie zu injizieren.
- Das Fertigstellungsgate ist ein Skript, kein Gefühl:
validate_verification.pymuss mit 0 beenden. - Explosionsradius: Ein genehmigtes Spezifikationspaket autorisiert lokale Bearbeitungen und lokale Commits.
git push, Deployment und Produktionsdatenänderungen benötigen eine explizite Freigabe für diese Aktion.
Profil
Das Projekt deklariert, wie viel läuft, in AGENTS.md oder Äquivalent. Ohne Deklaration:
light. Dieselben drei Stufen wie tlc-implement, auf dieselbe Weise eingeschränkt, sodass der Wechsel zwischen den beiden
Fähigkeiten kein zweites Vokabular benötigt.
## tlc-spec-lean
profile: light
budget: 150k
| Profil | Fügt hinzu | Kann nicht erkennen |
|---|---|---|
light (Standard) | Beweise laufen bei HEAD, wobei jeder benannte Test als existent und lauffähig gezeigt wird, eine lokalisierte Behauptung pro Check, Lücken und Stichprobenebene, Swept existing erneut gelesen | ein Mengenmitglied ohne Beweis; ein Test, der unter einer falschen Implementierung bestehen würde |
standard | Der Coverage-Join neu berechnet, Test policy-Zeilen mit jeweils einem Urteil, ein Fehler pro Behauptungsoberfläche | ein Check, der einer bindenden Quelle widerspricht; ein Bildschirm, den niemand gebaut hat |
ui | Bindende Quellen geöffnet und verglichen, Bildschirm-für-Bildschirm-Aufzählung von Text und Anordnung | nur Abstände, Farbe und Schriftstärke, Bildschirm für Bildschirm aufgezählt |
Jeder Schritt fügt eine Klasse von erkennbarem Fehler hinzu, also ist ein billiges Profil kein Rabatt auf das
gleiche Produkt - lies die rechte Spalte, bevor du es wählst. Zwei Dinge über light sind es wert,
laut ausgesprochen zu werden, weil seine eigene Zeile sie sagt und sie leicht überflogen werden können: es wird nicht
bemerken, dass ein aufgezähltes Mengenmitglied niemand bewiesen hat, und es wird nicht bemerken, dass ein Test unter einer
falschen Implementierung besteht. standard existiert für genau diese beiden.
ui kostet nichts bei Arbeiten ohne Benutzeroberfläche: jeder Bildschirmschritt ist abhängig von der Existenz eines
Bildschirms. Ein Schritt, dessen Eingabe leer ist, kostet eine Zeile, keinen Durchlauf („keine Satzzeilen“, „keine bindende
Quelle“).
Der Coverage-Join wird bei jedem Profil in checks.md geschrieben - der Join macht eine Auslassung
strukturell, und das kostet zur Entwurfszeit nichts. Was standard erkauft, ist der Prüfer, der ihn neu berechnet
aus der Autorität über jeden Satz, anstatt die Tabelle des Autors zurückzulesen.
Das Profil ist eine Festlegung, keine Präferenz, und anders als bei tlc-implement wird dies durchgesetzt und nicht
erfragt: validate_verification.py lässt einen Bericht fehlschlagen, dessen Profil sich von dem unterscheidet, unter dem
checks.md genehmigt wurde, und lässt einen standard-Bericht ohne Fehlerzeilen oder neu berechnete Abdeckung fehlschlagen,
und einen ui-Bericht ohne Abschnitt für bindende Quellen. So bleibt ein Schritt, der nicht lief, unterscheidbar von einem
Schritt, der vergessen wurde, was der ganze Grund ist, eine Untergrenze zu deklarieren.
Wo das Profil für die vorliegende Funktion zu dünn aussieht, sage dies in einer Zeile und lass den Benutzer es anheben. Im Stillen mehr zu tun als das Profil kostet die Vorhersehbarkeit, die die Deklaration lohnenswert machte.
Artefakte
.specs/
├── STATE.md # Entscheidungsprotokoll (AD-NNN) + Handoff-Momentaufnahme
├── LESSONS.md # gerendert von scripts/lessons.py - niemals von Hand bearbeiten
├── lessons.json # maschineneigen
└── features/<feature>/
├── plan.md # Problem, Ablauf, Auswirkungen, dann der Rest der Form, dann Kriterien; Audit zuletzt
├── checks.md # Behauptungen + Beweise, der Coverage-Join, Testrichtlinie, abgedeckt
└── verification.md # der Bericht des Prüfers
Erstelle jede Datei, wenn ihre Phase Inhalt produziert. Für eine Änderung unter ungefähr drei Dateien ohne
One-Way-Door, schreibe nur checks.md mit einem ## Absicht-Absatz und überspringe plan.md - ein
begrenzter Ausweg, keine Größenmatrix.
Verständnis und Verpflichtungen sind separate Artefakte
plan.md existiert, weil ein Mensch planen und Einwände erheben können muss, bevor irgendetwas zu einer
Behauptung mit einem zugehörigen Testselektor wird. Vierzig Checks zu lesen, um zu rekonstruieren, was gebaut wird, ist
kein Planen, und das Schreiben der Checks im selben Durchlauf, der die Form entscheidet, produziert Checks, die
bestätigen, was bereits angenommen wurde.
Beide Hälften leben in einer Datei, weil sie eine Überprüfung sind. Die Dateigrenze ist die semantische:
auf dieser Seite, was ein Mensch bestätigt; auf der anderen, Verpflichtungen mit Beweisen. Das Aufteilen des
Plans in eine Spezifikation und ein Design würde es an einer Stelle schneiden, die keiner entspricht, und würde zwei
obligatorische Stopps für eine Funktion erkaufen. Die Dateireihenfolge ist zum Lesen - Problem, Ablauf, Auswirkungen, dann
den Rest der Form, dann die Kriterien, dann die Audittabellen. Die Schreibreihenfolge ist nicht: schreibe das
Problem, gehe die Oberflächen durch, schreibe die Kriterien, dann fülle die Form. Das stoppt ein Kriterium
davon, erfunden zu werden, um eine Komponente zu rechtfertigen. Das Abschlussgate erfordert immer noch, dass jedes
Kriterium irgendwo in Flow, Relations oder Surface landet, oder es ist außerhalb des Umfangs oder eine
Lücke in der Form.
Die Ableitung in checks.md ist der tragende Teil, kein Papierkram. Jede Route in Surface
schuldet eine Coverage-Satzzeile, deren Mitglieder ihre Status sind; jede Tür in Landing schuldet einen Check;
jede Entität in Relations schuldet einen. Ein Formabschnitt, auf den von checks.md nichts zurückverweist,
ist entweder tot oder unbewiesen, und validate_checks.py warnt vor dem häufigen Fall.
Die Designhälfte existiert; das Komponentenverzeichnis nicht. Was Design-Dokumente verrotten ließ, war
niemals das Diagramm, es war Zweck / Ort / Schnittstellen / Abhängigkeiten pro Klasse -
umkehrbares Detail, das innerhalb von Wochen veraltet und dann den nächsten Leser mit der
Autorität eines geschriebenen Dokuments in die Irre führt. Keines dieser Felder existiert hier. Fünf begrenzte
Abschnitte:
| Abschnitt | Prüft | Außen vor gelassen |
|---|---|---|
Flow | der Pfad, eine Zeile pro Hop | jedes Modul, das weder existiert noch durch eine Tür erstellt wird - das ist Platzierung |
Impact | was sich darunter ändert: Begriffe und vorhandene Daten | Risikoregister |
Relations | Entitäten, Kardinalität, One-Way-Einschränkungen | Spalten und Typen |
Surface | Route, rein, raus, Status | Anforderungskörperspezifikation und Prüf-IDs - diese existieren noch nicht |
Landing | die One-Way-Doors, mit der wörtlichen Form und der abgelehnten Alternative | alles, was ein Refaktor umkehrt |
Welcher Ordner, wie viele Klassen, wie die private Methode heißt: der Diff. Umkehrbar, beantwortet durch die Konventionen des Repositorys und niemals ein Artefakt wert. Das ist der bewusste Kompromiss, und es ist der einzige.
Eine noch offene Wette, wenn du hier ankommst - zwei Architekturen mit lebendigen Alternativen, die jeweils gegen dieses
Repository bewertet werden müssen - passt nicht in eine Landing-Zeile, und eine Zeile ist die einzige Form, die dieses
Artefakt dafür hat. Was auch immer das Projekt verwendet, um eine zu entscheiden (ein ADR, ein RFC, ein Spike), kommt
zuerst; dann zeichnet der Plan die Form auf, die gewonnen hat, und macht sie überprüfbar.
Ablauf
Plan - das Problem, dann der Pfad und was die Änderung stört, dann der Rest der Form,
dann die Kriterien. Das Schreiben geht immer noch Problem → Oberflächen → Kriterien → Form. Fakten,
die du nachschlägst; Entscheidungen, die du fragst - und wenn du fragst, konkrete Optionen mit deiner Empfehlung, höchstens
drei pro Runde. Zwei Aufzählungen erledigen die Suche, weil „berücksichtige die Randfälle“ nichts findet: die
Oberflächen, die diese Funktion bereitstellt, jede mit denselben Entscheidungen, die jedes Mal auftreten, wenn sie erscheint, und die
neun impliziten Anforderungsdimensionen. Beide nehmen ein obligatorisches n/a - <Begründung>, also ist eine Leere ein Punkt,
den niemand entschieden hat, und nicht einer, der nicht zutrifft. Ein Artefakt, das ein Mensch liest und zu dem er Einwände
haben kann, bevor ein Check existiert. Vollständiger Prozess, wie man fragt, Regeln pro Formabschnitt, Vorlage und
Abschlussgate: plan.md.
Checks - leite Behauptungen mit Beweisen aus dem Plan ab, verknüpfe jedes aufgezählte Mengenmitglied mit einem
Check und zeichne auf, wo jede abgedeckte Dimension gelandet ist. Schließe mit ## Handoff und der
Arithmetik; wenn die Schätzung das Budget überschreitet, stoppe für die Mechanismusfrage vor Build. Dies ist das
Artefakt, auf das sich alles Nachgelagerte nach Check-Nummer bezieht: checks.md.
Build - deine Entscheidung wie, nach der ## Handoff-Arithmetik und, wenn die Schätzung das
Budget überschreitet, der Mechanismuswahl des Benutzers. Schreibe die Tests von den Checks, implementiere, führe jeden
Beweis aus, committe in kohärenten Stücken. Keine Aufgabenliste, keine tabellarischen Prüfungen pro Aufgabe.
Grenzen, Landing-Timing, Übergabe und die Umfangswarnleiste: build.md.
Verify - wenn der letzte Commit der Funktion landet, sende im selben Zug einen frischen Prüfer los. Nicht fragen. Nicht warten auf „verify work“. Verfahren, Berichtsformat und eingeschränkte Neuprüfung: verify.md.
Dauerhafter Speicher - Projektentscheidungen, Session-Übergabe und die Lernebene: memory.md.
Skripte
Löse <skill-dir> als das Verzeichnis auf, das diese SKILL.md enthält, und rufe
python3 <skill-dir>/scripts/<name>.py auf. Projektdaten unter .specs/ bleiben relativ zum
Projektstammverzeichnis; gib --root an, wenn das aktuelle Arbeitsverzeichnis abweicht. Ein Exit-Code ungleich Null bedeutet STOPP und beheben.
| Wann | Befehl |
|---|---|
| Vor dem Präsentieren des Plans | validate_plan.py <feature> |
| Vor dem Beginn des Bauens | validate_checks.py <feature> |
| Vor jedem Commit | check_commit.py --message "<msg>" |
| Vor dem Erklären der Fertigstellung | validate_verification.py <feature> |
| Bei der Destillation | lessons.py add ... |
| Nach dem Bearbeiten eines Prüfers oder einer Vorlage | selftest.py |
validate_plan.py führt das Abschlussgate aus und schützt die Formhälfte davor, das zu werden, was sie
ersetzt: es lässt ein Kriterium ohne SHALL fehlschlagen, eine Annahme ohne gewählten Standard, eine Observable-Zeile,
deren Landung leer ist oder deren n/a keinen Grund trägt, eine Landing-Zeile ohne wörtliche Form oder ohne abgelehnte
Alternative, Spalten und Typen innerhalb von Relations, eine Surface-Route ohne Status und jeden Abschnitt, der
leer gelassen wurde, anstatt mit None - <why> beantwortet zu werden. validate_checks.py ist der
Auslassungsfänger: es lässt einen Check ohne Beweis fehlschlagen, eine Coverage-Zeile, deren deklarierte Größe die
Anzahl der tatsächlich zugewiesenen Mitglieder überschreitet, eine fehlende abgedeckte Dimension und eine fehlende Profilzeile,
und warnt vor einer Route, die der Plan überprüft hat, die aber kein Check erwähnt.
validate_verification.py lässt einen PASS-Bericht fehlschlagen, der kein file:line zitiert, einen
überlebenden Mutanten aufzeichnet, ein Unproven-Mitglied hinterlässt oder vom Autor geschrieben wurde.
Überspringe ein Skript nur, wenn kein Code-Ausführungswerkzeug existiert; führe dann dieselben Prüfungen durch das Lesen des Artefakts aus und sage einmal im Chat, dass du dich auf dem abgewerteten Pfad befindest.
selftest.py wendet die eigene Disziplin dieser Fähigkeit auf ihre Gates an: es mutiert einen ausgefüllten
Fixture-Satz einmal pro Regel und erfordert, dass jeder Mutant getötet wird, führt Negativkontrollen durch, die beweisen, dass ein
profilbegrenztes Gate unterhalb seines Profils nicht auslöst, und führt jedes hier gelieferte Skript trocken aus -
ein ungeübtes Skript ist der Ort, an dem sich ein Absturz versteckt, und das Fertigstellungsgate ist einmal mit 0 beendet, während
ein Check im Bericht ungeprüft blieb.
…[für die Übersetzung gekürzt]