3 Punkte von GN⁺ 2023-07-21 | 1 Kommentare | Auf WhatsApp teilen
  • Strukturen oder Code, die ursprünglich unbedeutend oder nur vorübergehend wirkten, können mit der Zeit eine systemtragende Rolle übernehmen; deshalb sollten vor Änderungen auch die aktuellen Abhängigkeiten geprüft werden
  • Chesterton's Fence ist ein nützliches Prinzip: Vor dem Entfernen sollte man verstehen, warum etwas überhaupt errichtet wurde. Wenn man jedoch nur auf die ursprüngliche Absicht schaut, kann man später entstandene Rollen übersehen
  • Bei der Renovierung eines Badezimmers im Haus erwies sich ein wie ein Hindernis wirkender vertikaler Ständer als teilweise tragend für die Last des Obergeschosses, nachdem sein ursprünglicher Zweck als Schranktrennwand weggefallen war und fehlerhafte bauliche Änderungen erfolgt waren
  • Auch in komplexen Computersystemen sind Änderungshistorie und Designdokumente nur der Ausgangspunkt; man muss zusätzlich betrachten, wie eine Komponente aktuell in das System integriert ist
  • Wer alte Komponenten entfernt oder verändert, ohne sowohl die historischen Designgründe als auch ihre heutigen verborgenen Rollen zu prüfen, kann unerwartete Ausfälle verursachen

Was Chesterton's Fence übersehen kann

  • Chesterton's Fence steht für die Idee, dass man vor dem Ändern oder Entfernen von etwas zuerst verstehen sollte, warum es geschaffen wurde
  • Bei menschengemachten Dingen wie Zäunen oder Türen ist es sehr wahrscheinlich, dass es einmal einen Grund gab, warum jemand sie für nützlich hielt
  • Selbst ein Design, das völlig sinnlos wirkt, kann bedeuten, dass die Person, die es ändern will, einen Aspekt des Problems übersehen hat
  • Allerdings kann diese Sichtweise dazu verleiten, sich nur auf die vom ursprünglichen Erbauer beabsichtigte Rolle zu konzentrieren und dadurch später entstandene neue Abhängigkeiten zu übersehen

Zufällig entdeckte Lastabtragung bei einer Haussanierung

  • Als vor einigen Jahren ein Badezimmer im Haus neu gebaut wurde, gab es einen vertikalen Ständer, der die Arbeiten behinderte
  • Dieser Ständer war ursprünglich Teil einer Schranktrennwand, und diese Funktion schien nicht mehr gebraucht zu werden
  • Aus der Perspektive von Chesterton's Fence hätte sein Entfernen unproblematisch gewirkt, tatsächlich war er im Lauf der Zeit jedoch zu einem tragenden Bauteil geworden
    • Durch andere fehlerhafte bauliche Veränderungen hatte dieser Ständer begonnen, einen Teil der Last des Obergeschosses zu tragen
  • Man muss also nicht nur prüfen, warum etwas ursprünglich geschaffen wurde, sondern auch, welche zusätzlichen Rollen es später übernommen hat

Lehren für komplexe Computersysteme

  • Beim Ändern komplexer Computersysteme tritt dasselbe Problem immer wieder auf
  • Es ist weiterhin nützlich, die Änderungshistorie zu betrachten, die ursprünglichen Designdokumente zu lesen und zu verstehen, warum eine bestimmte Komponente so gebaut wurde
  • Sicher wird es aber erst, wenn man auch betrachtet, auf welche Weise diese Komponente derzeit im System verbunden und genutzt wird
  • Komponenten übernehmen mit der Zeit leicht zusätzliche Rollen, die von ihrem ursprünglichen Zweck abweichen
  • Sichere Änderungen beginnen damit, die frühere Designabsicht und die heutige tatsächliche Rolle gemeinsam zu prüfen

1 Kommentare

 
GN⁺ 2023-07-21
Meinungen auf Hacker News
  • Endlich fühlt es sich so an, als gäbe es einen Namen dafür
    Ich mache viel Support für Steuerungssysteme, und es ist nicht selten, dass PLC-Code, der irgendein physisches Gerät auf ungewöhnliche Weise behandelt, unbeabsichtigte Probleme verursacht
    Ich wiederhole oft den Satz: „Jedes Mal, wenn man ein elektrisches/mechanisches Problem mit Software behebt, wird ein Gremlin geboren“
    Selbst wenn ich die eigentliche Ursache eines Bugs entdecke oder eine programmierte Einschränkung finde, die ich entfernen möchte, lehne ich das immer ab, bis ich weiß, warum dieser Code existiert. Kein Code ist ohne Grund hineingeraten, also muss man zuerst herausfinden, warum ein Timer oder Override nötig war
    Oft ist es erfreulich, wenn es Code ist, der ein Problem gelöst hat, das es längst nicht mehr gibt; aber häufig wurde der Code auch eingebaut, um einen Unfall zu verhindern, und durch Personalwechsel ist der ursprüngliche Zweck verloren gegangen. Ohne Dokumentation wird man sehr vorsichtig, die Arbeit anderer einfach zurückzudrehen
    Es geht auch darum, Kolleginnen und Kollegen zu vertrauen. Normalerweise tut niemand etwas völlig grundlos; wenn Code da ist, sollte man davon ausgehen, dass er einen Zweck hat, und darauf vertrauen, dass er anfangs ausreichend geprüft wurde. Wenn dieses Vertrauen zerbricht, wird jede Entscheidung schwierig

    • Deshalb hinterlasse ich bei jeder nicht ganz offensichtlichen Codezeile immer einen Kommentar dazu, warum sie so ist
      Wenn der Grund mit etwas außerhalb der Codebasis zu tun hat — Betriebssystem, Dateisystem, Datenbank, HTTP-Endpoint, Hardware —, kommentiere ich das zu 100 %, sofern es nicht bloß ein einfacher API- oder Library-Aufruf ist
      Wenn ich wegen eines Rate Limits eines anderen Dienstes ein sleep einbaue, schreibe ich dazu, wer es verlangt, welche Grenzwerte nach damaligem Wissensstand gelten, falls ich es nicht genau weiß, dass es „eine Vermutung ist, aber zu funktionieren scheint“, und wie das System aussehen kann, wenn man darüber liegt
      Wenn ich für eine Kleinigkeit, die auch mit dem Dateisystem machbar wirkt, eine Datenbank verwende, weil in dieser Umgebung der nötige Zugriff auf das Dateisystem unter Last wegen ausufernder Systemaufrufe Ressourcen erschöpft, hinterlasse ich einen Kommentar
      Auch Workarounds für Bugs in weit verbreiteten Libraries, die Ubuntu in LTS-Releases nicht behebt, sind ein Fall für Kommentare. Ich habe wirklich viele Kommentare nach dem Muster geschrieben: „Ich weiß, dass das unschön ist, aber hier ist der Grund“
      Ich kommentiere auch, wenn ich Code schreibe, der in großem Maßstab nicht gut funktionieren wird, weil es mir gerade zu lästig ist, ihn skalierbar zu machen, und es nach aktueller Einschätzung auch nicht nötig ist. Vielleicht dient das eher dem Schutz des eigenen Stolzes, aber es geht in die Richtung: „Ich weiß, dass hier die ganze Datei in den Speicher gelesen wird, aber es ist ein seltener und planbarer Batch-Job, und die Dateien sollen klein sein, also ist das okay. Wenn der Speicher knapp wird, zuerst hier nachsehen. Wenn das in einen On-Demand-Aufruf geändert werden soll, neu schreiben“
    • Das klingt für mich einfach nach der üblichen Logik von Chestertons Zaun
      Der Punkt des Artikels ist, dass das allein nicht reicht. Man muss nämlich auch wissen, was sonst noch auf der Annahme aufgebaut wurde, dass dieser Code existiert
    • Der gruseligste Kommentar, den ich tief in einer Allen-Bradley-PLC gesehen habe, war dieser:
      „Ich weiß nicht, warum dieser Rung nötig ist, aber lösch ihn und finde es selbst heraus“
      Ich habe ihn nicht angerührt und es auch nicht herausgefunden
    • Ein Teil davon ist auch kulturell bedingt
      Elektro- und Maschinenbauingenieure haben Software historisch weniger ernst genommen als elektrische und mechanische Systeme, und als Folge entsteht in von EE/ME dominierten Engineering-Kulturen leicht chaotischer Code
      Selbst unter Leuten, die nach außen hin Professional Engineers sind, ist inakzeptabel unreife Softwaretechnik immer noch verbreitet
    • PLC-Arbeit werde ich wohl nie wieder machen
      Undokumentierter Code ist eine Sache, aber meistens ist es vor 30 Jahren maßgefertigte Hardware, sodass es nicht einmal Schaltpläne für die Anlage gibt, an der man arbeitet
  • Ich hatte etwas Ähnliches
    Vor ein paar Jahren habe ich ein altes Haus gekauft, und die früheren Eigentümer hatten seit den 1960ern das meiste selbst gemacht
    Eine Zinkrinne war vermutlich jahrzehntelang undicht und hatte einen Teil der Dachkonstruktion beschädigt; getragen wurde das Dach von Holzpaneelen, die in den 70ern angebracht worden waren, um die Innenseite zu verkleiden. Mit anderen Worten: Diese Holzpaneele trugen tatsächlich Last
    In diesem Haus habe ich noch viel mehr entdeckt. Zum Beispiel war am Dachrand die Breite der Dachziegel zu knapp; statt zusätzliche Ziegel zu kaufen, hatten sie es mit Zement und Scherben zerbrochener Keramik-Blumentöpfe aufgefüllt

    • Wenn man ins frühe 20. Jahrhundert zurückgeht, wurde die Außenverkleidung diagonal angebracht und verhinderte in hohem Maß, dass sich das Gebäude verwindet
      Heute erwarten wir, dass Gipskarton und Sperrholz diese Rolle bei Erdbeben und Stürmen übernehmen
      Wenn man sieht, wie ein Haus bis auf das Ständerwerk entkernt und neu aufgebaut wird, wird man einige zusätzliche Aussteifungen sehen. Nicht, damit die Wände nicht einstürzen, sondern damit sie rechtwinklig und eben bleiben, bis die Wände wieder aufgebaut sind
    • Meine Garage fühlt sich genauso an
      Auf den ersten Blick sieht es aus, als hätte jemand das Garagentor gerammt und stark verbeult, aber bei genauerem Hinsehen hängt das Dach gerade so an der Schiene, an der das Tor befestigt ist, und steht kurz vor dem Ende
      Anfangs wollte ich nur die Enden der Sparren anstückeln und das Garagentor ersetzen, nach dem Motto: Auf der anderen Seite hat das früher auch jemand so gemacht, also wird es schon funktionieren; inzwischen glaube ich, dass das ganze Dach neu muss
      Wirklich Sorgen macht mir die verdächtige Verkabelung im gesamten Keller. Relativ neue Leitungen, alte stoffummantelte Leitungen und Isolierband, das sie zusammenflickt, sind bunt gemischt. Zum Glück scheint keine der Leitungen Last zu tragen
    • Bis zu lasttragender Farbe sind es nur noch ein paar Schritte
    • Ich hatte einmal ein Haus mit sehr starkem Termitenschaden, und der Bauunternehmer nannte das strukturellen Stuck
  • Dieser Beitrag und fast alle Kommentare scheinen das eigentliche Problem zu verfehlen. Der Kern ist zu wenig Tests.
    Software unterscheidet sich von allen anderen Produktionsmitteln dadurch, dass man Änderungen tatsächlich testen kann, bevor sie in der Realität wirksam werden.
    Wenn es gute Tests gibt, ist es egal, was die Absicht war oder ob für diese Funktion neue Verwendungen oder neue Nutzer entstanden sind. Man behebt etwas, lässt die Tests laufen, und sie sagen einem, ob die Änderung gut ist.
    Mit guten Tests braucht man keine Software-Archäologie, keine abgeklärten Veteranen, die jeden Riss kennen, keine Wunderkinder, die komplexe Systeme im Kopf modellieren, keine umfassenden Anforderungsdokumente und keine vorsichtigen Rollout-Systeme, die Teile der Nutzerschaft zu Versuchskaninchen machen.
    Mit guten Tests könnte man ein System sogar zufällig verändern und aufhören, sobald eine Verbesserung herauskommt. Genau so, wie Google berichtet hat, dass KI Verbesserungen beim Alignment „entwickelt“ habe.
    Trotzdem werden Testentwickler höchstens halb so gut bezahlt, Testabteilungen sind vergleichsweise klein, QA wird in einen festen und knappen Zeitplan gepresst, und technische Helden mit QA-Hintergrund gibt es kaum. Vielleicht, weil die Arbeit abgeleitet und reaktiv wirkt.

    • Selbst wenn Tests das Verhalten prüfen, für das der Code entworfen wurde, kann es sein, dass andere Systeme sich auf das verlassen, was der Code tatsächlich tut.
      Man entfernt ungenutzten Code samt Tests, obwohl er in Wahrheit noch verwendet wird.
      Nach einer Änderung schlägt ein Test fehl, aber weil der Test fragil ist, passt man ihn an die neue Situation an; später stellt sich heraus, dass irgendetwas vom alten Verhalten abhing.
      Tests sind großartig, und in hinreichend in sich abgeschlossenen Systemen können sie ausreichen. In größeren Systemen braucht man manchmal aber auch Telemetrie oder stufenweise Rollouts.
    • Tests haben einen bestimmten Geltungsbereich. Sie decken den Bereich ab, für den der Code verantwortlich sein soll, aber wahrscheinlich nicht alles, was im Lauf von Monaten oder Jahren der Nutzung inzwischen von ihm erwartet wird.
      Ursprünglich war der Code dazu gedacht, die Mehrwertsteuer einer Einkaufsliste zu berechnen, wurde aber nach und nach zu einem Mittel, um den Mehrwertsteuer-Cache nach Produktkategorien zwangsweise zu aktualisieren, und kann in Kontexten aufgerufen werden, die anfangs niemand erwartet hatte.
      Dasselbe gilt für Kommentare. Sie behandeln die ursprüngliche Absicht und Nebenwirkungen, aber nicht, wo diese Methode oder Klasse viel später verwendet wird oder was sie tatsächlich zu tun begonnen hat.
      In einer idealen Welt würden Kommentare aktualisiert, wenn sich die umgebende Welt ändert, aber in der Praxis passiert das fast nie, solange sich der interne Code nicht mitändert.
    • Wer an sehr langlebigen Projekten gearbeitet hat, weiß, dass Tests oder gut finanzierte QA organisatorische Probleme nicht verhindern.
      Tests verrotten in der Regel. Es wirkt, als hätten auch Tests ein Verfallsdatum, und irgendwann beginnen einige Tests zu sterben.
      Abhängigkeitsprobleme, veränderte API-Erwartungen, Sicherheitsupdates, abgelaufene Konten und Zugangsdaten, Änderungen an Maschinen-Endpunkten und Zuständen vermischen sich so, dass Testergebnisse nicht mehr auf die Korrektheit des Programms hinweisen.
      Der Grenznutzen, einen einzelnen kaputten Test zu reparieren, ist meist sehr gering, weshalb man ihn oft einfach abschaltet oder ihn dazu zwingt, „bestanden“ zu melden, obwohl es eigentlich ein Fehler sein müsste.
      Nach 10 oder 20 Jahren wiederholt sich das so lange, bis sich schnell „Tests, denen man tatsächlich vertraut“ und „Tests, für deren Reparatur oder Aufräumen man zu beschäftigt ist“ trennen.
      Welche Tests gut oder schlecht sind, wird zu Stammeswissen, das durch Job- und Rollenwechsel verschwindet, und irgendwann wird der ganze Haufen aus „Tests, die lügen, dass es funktioniert“ und „Tests, bei denen niemand mehr prüft, ob ein Fehlschlag wahr ist“ selbst zufällig tragend.
    • Der Anfang wirkte wie eine Wiederholung des Optimismus testgetriebener Entwicklung, sprang dann aber plötzlich zu Testabteilungen, was wenig konsistent ist.
      Besser wäre es zu sagen, dass Programmierer Tests schreiben, sie zusammen mit dem Code aufbewahren und im Build-Prozess automatisch ausführen sollten.
      Aber auch richtig betriebene testgetriebene Entwicklung kann meiner Ansicht nach gutes Design und gute Praktiken nicht ersetzen. Nicht einmal eine sehr einfache Spezifikation lässt sich durch Tests ersetzen.
      Wenn nur spezifiziert ist, dass f(S) einen String zurückgibt, der an sich selbst angehängt wurde, ist es schwierig, allein mit offensichtlichen Tests, die f als Blackbox behandeln, zu verifizieren, dass f korrekt ist. Auch formale Spezifikationen sind wichtig.
      Man kann ein paar Stellen stichprobenartig prüfen, aber wenn ein einzelner magisch falscher Wert katastrophal wäre, zeigen Tests das nicht.
      Man kann Software-Archäologie, erfahrene Veteranen, Wunderkinder, die Systeme im Kopf modellieren, umfassende Anforderungsdokumente und Rollout-Systeme, die einige Nutzer zu Versuchskaninchen machen, satirisch betrachten, aber all das sind Reaktionen darauf, dass Software schwierig ist. Und Software ist wirklich schwierig.
    • Die Unterscheidung zwischen Testentwicklern, Testabteilungen und QA-Teams ist für die meisten Softwareorganisationen selbst schon fast ein Luxus.
      In der Regel müssen Softwareteams die Qualität ihrer eigenen Arbeit direkt verantworten und können Probleme nicht über das Organigramm hinweg weiterreichen.
  • Dass ein zunächst unwichtiger Stud später Last trägt, kann ich nachvollziehen, aber aus meiner Erfahrung wirkt es wie ein Zeichen für faules Design.
    Zumindest beim Bau von Software kann man erkennen, dass man gerade versucht, einen Teil des Hauses auf einem dekorativen Stud abzustützen; und wenn man sich dann entscheidet, es einfach so zu lassen, statt eine bessere neue Struktur zu schaffen, macht das das Entwicklerteam später ziemlich unglücklich.
    Ich stimme dem Text zu, aber es ist deutlich angenehmer, an einem Ort zu arbeiten, an dem man erwarten kann, solche Entdeckungen nicht allzu oft zu machen.

    • Bei Dingen, die „du“ gebaut hast, magst „du“ das wissen, aber in meiner Laufbahn habe ich sehr viel häufiger mit Dingen gearbeitet, die andere gebaut hatten, und musste sie umbauen.
      Der Punkt des Textes ist weniger, dekorative Studs nicht als tragende Elemente zu verwenden, sondern zu erkennen, dass jemand vor deiner Zeit genau das getan haben könnte.
      Das ist sogar noch konservativer als die grundlegende Interpretation von Chestertons Zaun, und selbst diese grundlegende Interpretation wird von vielen als zu einschränkend abgetan.
      Für mich trifft der Text ins Schwarze. Programmiersprachlich gesprochen habe ich tatsächlich erlebt, dass ich eine „dekorative“ Leiste entfernt habe und mir daraufhin die Decke auf den Kopf gefallen ist.
    • Ist es immer Faulheit im negativen Sinn? In Software gibt es keine scharfe Trennlinie zwischen „dafür gebaut, Last zu tragen“ und „dafür gebaut, Gipskarton zu befestigen“.
      Ob ein System robust ist oder gefährlich nicht skalieren kann, hängt vom Kontext ab.
      Man kann jederzeit Gedankenexperimente machen wie: „Was, wenn das Sales-Team doppelt so groß wird und Kunden so schnell wie möglich verkauft und onboardet, bis wir 100 % des Marktes haben?“ Und selbst unter solchen Bedingungen kann es in Ordnung sein, eine Datenbank wie eine Message Queue zu verwenden.
      Wenn das Entwicklerteam dadurch gelitten hat, war es ein Fehler: Die Wartung war schwierig, oder der Betrieb wurde zur Hölle.
      Aber dekorative Studs in Software als tragende Elemente zu verwenden, führt nicht zwangsläufig dazu. Es gibt viele Systeme, die unauffällig und zufrieden ihren Zweck erfüllen und dabei die Monate sparen, die eine „richtige“ Lösung gekostet hätte.
    • Nehmen wir an, man schreibt defensiven Code. Man fügt einer Funktion Behandlung für ungültige Eingaben hinzu.
      Der restliche Codebestand schickt niemals ungültige Eingaben, also ist dieser Zweig toter Code und trägt keine Last.
      Dann kommt irgendwann ein Bug hinein, der ungültige Eingaben schickt, und dieser Zweig verarbeitet sie pflichtbewusst und erholt sich davon. In diesem Moment wird der Zweig zu einem lasttragenden Zweig.
    • Ich dachte einmal, wir betrieben einen unwichtigen Service ganz ordentlich, und stellte bei einem Ausfall fest, dass ein anderes Team begonnen hatte, sich für eine geschäftskritische Funktion darauf zu verlassen – in einer Situation, in der eigentlich nichts hätte passieren sollen.
    • Häufiger habe ich allerdings gesehen, dass solche Dinge passieren, weil man es tatsächlich nicht weiß.
  • Mein liebstes Beispiel für ein „versehentlich lasttragendes“ Artefakt, das ich gesehen habe, war ein falsch konfiguriertes sudo.
    Für den Befehl find war passwortloses sudo erlaubt, sodass über -exec beliebige Codeausführung als Root leicht möglich war; mehrere wichtige Support-Skripte des Produkts waren so geschrieben, dass sie genau das nutzten.
    Im Grunde war das lasttragende Rechteausweitung.

  • Vor einigen Jahren haben wir unsere Küche umgebaut.
    An einem Ende der alten Küche verlief ein großer Träger, der bei einem Umbau vor unserem Hauskauf hinzugefügt worden war, um ein zweites Stockwerk zu tragen. Um die Küche zu erweitern, mussten wir ihn entfernen.
    Als wir die Decke öffneten, stellte sich heraus, dass dieser Träger etwa zwei Fuß rechts von der Stelle lag, an der er die Wand im Obergeschoss hätte tragen sollen.
    Am Ende haben wir es korrigiert und den Träger in die Wand im Obergeschoss verlegt, und alles ging gut. Als ich aber nach der ursprünglichen Position fragte, sagte der Bauunternehmer sinngemäß:
    „Da gab es jemanden, der es richtig machen wollte, und jemanden, dem es egal war. Qualität richtet sich am Ende nach der niedrigsten Einstellung.“

  • Ein Vorteil von Software gegenüber physischen Systemen ist, dass man die Absicht im Code leicht mit Kommentaren und Typen dokumentieren kann, um sie klarer zu machen.
    Gerade in dynamischen Sprachen wie Python ist das nicht perfekt, hilft aber enorm.
    Die Entsprechung eines lasttragenden Studs könnte ein Hackathon-Projekt sein, von dem niemand dachte, dass es je in Production landen würde.
    Tatsächlich besteht ein großer Teil unserer Arbeit darin, etwas zusammenzuhacken, bis es gerade so läuft, und dann zur nächsten Sache überzugehen.

    • Genau. Wegen genau solcher Probleme wurde in Luft- und Raumfahrt sowie Verteidigung Systems Engineering eingeführt.
      Denn Wartungsplanung muss wissen, welche „Last“ jedes austauschbare Teil oder jede Baugruppe trägt.
      Heutiges Systems Engineering hat sich leider sehr weit vom ursprünglichen Ziel entfernt, aber so war die ursprüngliche Idee.
      Einer der Gründe, warum Systems-Engineering-Abteilungen heute relativ wenig Macht haben, ist, dass Finance in die Wartungsplanung eingezogen ist. Bestandsabschreibungen sind brutal, und „was halten wir als Ersatzteil vor?“ ist zumindest meiner Erfahrung nach nur noch selten eine Entscheidung des Systems Engineering.
      Das Ergebnis ist vorhersehbar, wird aber teilweise dadurch ausgeglichen, dass die Standards des Wartungspersonals in der Luft- und Raumfahrt sehr hoch sind. Verglichen etwa mit Waschmaschinen-Reparateuren sind sie ziemlich beeindruckend.
      Natürlich würde Finance auch diese Standards gern um ein paar Stufen senken.
    • Wenn es absichtlich passiert, ist es leicht, so etwas zu tun.
      Aber ich bin immer wieder erstaunt, wie oft man Systeme sieht, in denen eine „dekorativ“ wirkende vorgelagerte Komponente in Wirklichkeit eine Geschwindigkeitsbegrenzung setzt, sodass der Rest durchdreht, wenn man sie entfernt.
  • Das erinnert mich an Fälle, in denen Nutzer einen Software-Bug unbewusst ausnutzen und ihn in ihren normalen Arbeitsablauf integrieren.
    Wenn man den Bug dann behebt, bricht der Arbeitsablauf, und es gibt Beschwerden.

  • Es hieß: „Es war leicht zu erkennen, warum er dort war. Er war Teil der Trennwand eines Schranks.“ Aber im Lauf der Zeit wurde er versehentlich lasttragend, und durch andere fehlerhafte Strukturänderungen half dieser Stud nun dabei, das zweite Stockwerk des Hauses zu tragen.
    Allerdings war offensichtlich nicht leicht zu erkennen, warum er dort war. Außerdem überzeugt mich nicht, dass er versehentlich lasttragend wurde.
    Es scheint durchaus möglich, dass man ihn aus Gründen, die dir falsch erscheinen, den damaligen Leuten aber nicht, absichtlich lasttragend gemacht hat.

    • Man konnte erkennen, warum er dort war.
      Nur sagt einem das Wissen, warum er ursprünglich dort war, nicht, was er heute tut.
  • Ein Postdoc der Physik, mit dem ich früher zusammenarbeitete, brachte manchmal ein Schild an Geräteaufbauten an:
    „Nicht berühren. Verborgene Gefahr.“
    Das Labor war voller kluger Leute, die gewohnt waren, etwas anzusehen und selbst vernünftig zu entscheiden, ob man es verändern könne.
    Dieses Schild war eine Warnung, dieses Urteil nicht zu vorschnell zu fällen.