Ist automatisierte Repository-Dokumentation vertrauenswürdig?
Automatisierte Repository-Dokumentation kann Code und Daten zuverlässig abbilden, wenn jede Aussage Belege, Umfang und Unsicherheit nennt.

Repository-Archäologie kann erstaunlich viel Dokumentation wiederherstellen, doch Absichten lassen sich nicht allein dadurch rekonstruieren, dass man mehr Dateien liest. Eine Modulübersicht, ein statischer Aufrufgraph, ein möglicher Datenentwurf und große Teile eines Batch-Abhängigkeitsgraphen sind durch Belege gestützte Ergebnisse. Bezeichnungen wie "Kunde", Aussagen darüber, wann ein Job gefahrlos neu gestartet werden kann, und Erklärungen für den Zweck einer Verzweigung bleiben Hypothesen, bis eine weitere Quelle sie bestätigt.
Diese Grenze ist wichtig, weil generierte Dokumentation auf beiden Seiten gleich überzeugend klingt. Ich habe erlebt, wie Teams ein sauber gezeichnetes Diagramm akzeptierten, ihre Neuentwicklung darauf planten und erst spät entdeckten, dass eine Scheduler-Regel oder ein dynamisch ausgewähltes Programm das entscheidende Verhalten enthielt. Die Lösung besteht nicht darin, Automatisierung abzulehnen. Jede generierte Aussage muss ihre Belege, ihre Methode und ihre bekannten Lücken mitführen.
Ein Repository belegt Struktur, aber keinen Zweck
Automatisierte Repository-Dokumentation ist vertrauenswürdig, wenn sie beobachtbare Struktur wiedergibt und genau angibt, wie diese beobachtet wurde. Dateien, Deklarationen, Importe, Build-Ziele, SQL-Verweise, JCL-Anweisungen und wörtliche Konfigurationsschlüssel hinterlassen überprüfbare Spuren. Ein Werkzeug kann sie erfassen, verbinden und auf die Zeilen verweisen, die jede Verbindung stützen.
Der Zweck ist etwas anderes. Eine Tabelle namens ACCT_MST kann Kundenkonten, interne Sachkonten oder einen vorübergehenden Abstimmungszustand enthalten. Der Name legt eine Deutung nahe, beweist sie aber nicht. Eine Routine namens VALIDATE kann fehlerhafte Eingaben abweisen, eine Berechtigungsregel anwenden oder nur Feldbreiten prüfen. Kommentare können helfen, doch veraltete Kommentare sind ebenfalls nur Inhalt des Repositorys und keine bevorzugte Wahrheit.
Für generierte Dokumentation verwende ich drei Vertrauensklassen:
- Beobachtet bedeutet, dass das Repository direkte Belege enthält, etwa einen Import, ein
EXEC PGModer eine Fremdschlüsseldeklaration. - Abgeleitet bedeutet, dass mehrere Beobachtungen eine Schlussfolgerung stützen, etwa die Gruppierung von Programmen in ein Abrechnungsmodul, weil sie Tabellen und Einstiegspunkte teilen.
- Ungeklärt bedeutet, dass das Repository die Frage nicht entscheidet, selbst wenn eine Deutung wahrscheinlich aussieht.
Jeder Knoten und jede Kante sollte außerdem ihren Ursprung als Pfad plus Zeile oder Anweisungsbereich nennen. Ohne Herkunft können Prüfer ein Parser-Ergebnis nicht von einer Vermutung des Modells unterscheiden. Ein generierter Satz wie "INVOICE schreibt in AR_LEDGER" ist nur dann nützlich, wenn ein Leser das zugrunde liegende INSERT, den Aufruf einer Stored Procedure oder den Schreibvorgang am Datensatz prüfen kann.
Die Unterscheidung verhindert auch einen häufigen Kategorienfehler: Vollständigkeit und Korrektheit sind verschiedene Dinge. Ein Parser kann jeden direkten Aufruf in den von ihm verstandenen Dateien korrekt finden und dennoch Aufrufe über Konfiguration übersehen. Sein Ergebnis ist innerhalb eines erklärten Bereichs korrekt, für das laufende System aber unvollständig. Die Dokumentation sollte beide Eigenschaften ausweisen, statt sie in einem vagen Vertrauenswert zusammenzufassen.
Die Modulübersicht braucht mehrere Arten von Kanten
Eine glaubwürdige Modulübersicht verbindet die Verzeichnisstruktur mit Belegen zu Abhängigkeiten und Datenzugriff. Oberste Verzeichnisse als Module zu behandeln, funktioniert nur in ungewöhnlich disziplinierten Repositorys. Alte Codebäume gruppieren Dateien oft nach Auslieferungspaket, Gewohnheit eines Autors, Ablageort von Copybooks oder einer Migration, die auf halbem Weg stehen blieb.
Beginnen Sie mit deklarierten Einheiten: Projekte, Pakete, Bibliotheken, Programme, Formulare, Stored Procedures, Batch-Jobs und Build-Ziele. Sammeln Sie dann typisierte Kanten zwischen ihnen. Sinnvolle Kantentypen sind imports, calls, includes, compiles_into, reads, writes, submits und generates. Behalten Sie den Typ bei. Eine gemeinsam verwendete Tabelle ist ein schwächerer Beleg für eine Modulgrenze als ein Build-Ziel, und eine textuelle Einbindung ist nicht dieselbe Beziehung wie ein Laufzeitaufruf.
Das erste Artefakt sollte ein maschinenlesbares Inventar sein, kein Bild. Zum Beispiel:
{"unit":"billing/post_invoice.cbl","kind":"cobol_program","declares":["POSTINV"],"includes":["ARREC"],"reads":["CUSTOMER"],"writes":["AR_LEDGER"],"evidence":["billing/post_invoice.cbl:18-146"]}
Erzeugen Sie Diagramme und Prosa aus diesem Inventar. Dadurch werden Änderungen prüfbar: Wenn ein Programm verschoben oder ein Parser verbessert wird, ändert sich zuerst der Quelldatensatz und jede Ansicht folgt. Ein Team kann die Dokumentation so auch abfragen, statt auf einen wandfüllenden Graphen zu starren.
Clustering verlangt Zurückhaltung. Zusammenhangskomponenten, Paketdeklarationen, Namenspräfixe, Eigentümerdateien und Auslieferungseinheiten können Grenzen vorschlagen. Sie dürfen diese nicht stillschweigend erfinden. Wenn AR*-Programme Datensätze teilen und gemeinsam ausgeliefert werden, nennen Sie das einen abgeleiteten Abrechnungscluster und listen Sie die Regel auf, die ihn erzeugt hat. Ein Mensch kann ihn dann annehmen, teilen oder umbenennen.
Generierte Modultexte sollten praktische Fragen beantworten: Was gelangt in diese Einheit? Was kann sie aufrufen? Welche Daten besitzt sie, und welche berührt sie nur? Wie wird sie gebaut und ausgeliefert? Welche andere Einheit würde bei einer Schnittstellenänderung ausfallen? Ein farbiges Rechteck, das keine dieser Fragen beantwortet, ist Dekoration.
Statische Aufrufgraphen sind nützlich und berechenbar unvollständig
Ein statischer Aufrufgraph kann Aufrufe zuverlässig erfassen, deren Ziele sich direkt aus dem Quelltext auflösen lassen. Er kann auch umgekehrte Kanten liefern, die für Änderungsplanung oft nützlicher sind: Statt zu fragen, was eine Funktion aufruft, fragen Entwickler, wer die Funktion erreichen kann, die sie ersetzen wollen.
Das Handbuch zu GNU cflow trifft für C genau diese Unterscheidung zwischen direktem und umgekehrtem Graphen. Es bietet außerdem Steuerung für Symbolfilter und Präprozessierung. Diese Einschränkung zählt. Ein Graph hängt vom Sprach-Frontend, von der Präprozessorkonfiguration, von Build-Flags und von den gewählten Einstiegspunkten ab. Einen Parser mit Standardeinstellungen über jede Datei laufen zu lassen, entspricht nicht der Analyse des Programms, das in Produktion gebaut wird.
Dynamischer Dispatch erzeugt die erste große Lücke. Funktionszeiger, Reflection, Dependency Injection, COM-Dispatch, generierte Proxys, dynamisches COBOL-CALL und aus Daten zusammengesetzte Programmnamen können das Ziel verbergen. Ein Quelltextscanner kann die Dispatch-Stelle und den Ausdruck zur Zielauswahl erfassen, sollte aber eine ungeklärte Kante anlegen, statt ein Ziel zu erraten.
Externe Ausführung schafft eine weitere Lücke. Shell-Befehle, APIs zur Job-Übermittlung, Datenbank-Trigger, Nachrichtenkonsumenten und Dateien, die ein anderer Prozess abfragt, überschreiten Grenzen, die ein sprachspezifischer Graph selten sieht. Das Repository kann beide Enden enthalten, ohne eine direkte Symbolkante zwischen ihnen zu besitzen.
Halten Sie für jede Kante die Art der Auflösung fest:
static, wenn Syntax und Symbolauflösung das Ziel bestimmen.configured, wenn ein Manifest oder eine Einstellung das Ziel nennt.observed, wenn eine Laufzeitspur das Ziel aufzeichnet.possible, wenn die Dispatch-Analyse eine begrenzte Menge liefert.unknown, wenn die Aufrufstelle existiert, das Ziel aber ungelöst bleibt.
Löschen Sie unbekannte Kanten nicht, um das Bild aufzuräumen. Oft sind sie die nützlichsten Punkte im Dokument, weil sie zeigen, wo eine Migration Tracing oder ein Gespräch mit dem Betrieb braucht. Ein Graph mit vollständig aufgelösten Aufrufen in einem stark reflektierenden oder konfigurationslastigen System wirbt meist nur für seine Blindheit.
Das Datenmodell existiert in drei konkurrierenden Fassungen
Das Repository kann ein deklariertes Schema, ein verwendetes Schema und ein abgeleitetes Geschäftsmodell liefern. Diese überschneiden sich, doch Teams geraten in Schwierigkeiten, wenn die Dokumentation sie als dieselbe Sache darstellt.
Das deklarierte Schema stammt aus DDL, Migrationsdateien, ORM-Mappings, Datensatzdefinitionen, Copybooks, Validierungsregeln und im Codebaum abgelegten Schnappschüssen der Datenbankmetadaten. Es kann Tabellen, Spalten, Typen, Indizes, deklarierte Schlüssel, Nullfähigkeit und Constraints bestimmen. PostgreSQL beschreibt information_schema.columns als portable Sicht auf Spalteninformationen und weist darauf hin, dass PostgreSQL-spezifische Typen letztlich in pg_catalog liegen. Das ist eine nützliche Warnung: Selbst Datenbankmetadaten haben eine portable und eine herstellerspezifische Schicht.
Das verwendete Schema stammt aus dem Code. SQL-Zeichenketten, Query Builder, Datei-Ein- und -Ausgabe, Datenzugriffsklassen, Bildschirmbindungen und Berichtsdefinitionen zeigen, welche Felder jedes Programm liest oder schreibt. Diese Sicht deckt Tabellen ohne deklarierte Fremdschlüssel auf, die dennoch beständig verknüpft werden, sowie Spalten, die in DDL existieren, aber nicht mehr im Repository-Code auftauchen.
Das abgeleitete Geschäftsmodell fügt Bedeutung hinzu: Ein Konto gehört zu einem Kunden, ein Status C bedeutet geschlossen, oder ein Paar von Gültigkeitsdaten modelliert einen Versicherungszeitraum. Automatisierung kann solche Beziehungen aus Namen, Joins, Prüfungen und wiederholten Transformationen vorschlagen. Sie kann sie ohne Glossar, Test, Bestätigung durch den Betrieb oder beobachtete Daten nicht zur Tatsache machen.
Eine brauchbare Extraktion hält Widersprüche sichtbar:
SELECT table_schema, table_name, column_name, data_type, is_nullable
FROM information_schema.columns
WHERE table_schema NOT IN ('pg_catalog', 'information_schema')
ORDER BY table_schema, table_name, ordinal_position;
Vergleichen Sie diese Ausgabe mit den Repository-Verweisen, statt eine Seite als maßgeblich festzulegen. Wenn der Code legacy_code auswählt, das erfasste Schema die Spalte aber nicht enthält, kann der Schnappschuss veraltet sein, das SQL bedingt laufen oder die Produktionsdatenbank anders aussehen. Wenn die DDL einen Fremdschlüssel deklariert, dem kein Code folgt, ist der Constraint dennoch relevant. Die Abweichung ist ein Befund und kein Ärgernis, das man wegführen sollte.
Auch die Herkunft auf Feldebene verlangt Vorsicht. Direkte Zuweisungen und benannte Transformationen können eine Herkunftskante stützen. Eine über ein generisches Gateway aufgerufene Stored Procedure, ein Tabellenmakro oder ein von einem Bediener bearbeiteter Export unterbrechen die Kette. Kennzeichnen Sie die Unterbrechung. Zeichnen Sie keinen durchgehenden Pfeil durch fehlende Belege.
Batch-Abhängigkeiten liegen außerhalb der JCL
Ein Repository kann einen großen Teil des Batch-Graphen ableiten, doch JCL oder Skripte allein enthalten selten den Produktionszeitplan. Sie zeigen Programme, Schritte, Prozeduren, Datensätze, Verzweigungen anhand von Rückgabecodes und ausdrückliche Job-Übermittlungen. Kalender, Vorgängerregeln, Ressourcen, Überschreibungen und Wiederanlaufaktionen liegen oft in einer Scheduler-Datenbank oder Betriebskonfiguration.
Die IBM-Dokumentation zu Workload Scheduler beschreibt Vorgänger und Nachfolger von Jobs, einschließlich Bedingungen anhand von Jobstatus oder Rückgabecodes. Die Dokumentation zum JCL-Repository sagt außerdem, dass der Scheduler für Jobs im aktuellen Plan eine Kopie der übermittelten JCL hält. Daraus ergibt sich eine wichtige Grenze: Die übermittelte JCL ist ein Ausführungsartefakt, während der aktuelle Plan den Orchestrierungszustand trägt. Ein Git-Repository, das nur eine Seite enthält, kann den vollständigen Abhängigkeitsgraphen nicht belegen.
Extrahieren Sie innerhalb des Repositorys mindestens vier Kantenklassen: Schrittreihenfolge, Programmausführung, Datenfluss und ausdrückliche Bedingung. Eine Produzent-Konsument-Kante, die daraus abgeleitet wird, dass ein Job einen Datensatz schreibt und ein anderer ihn liest, muss als abgeleitet gekennzeichnet bleiben. Datensatznamen können generationsbezogen oder symbolisch sein, bei der Übermittlung ersetzt werden oder aus Gründen geteilt sein, die nichts mit Reihenfolge zu tun haben.
Stellen Sie das Ergebnis so dar, dass fehlende Quellen Platz haben:
job: CLOSE_AR
steps:
- exec: EXTRACT_AR
writes: [AR.CLOSE.GDG(+1)]
- exec: POST_AR
when: EXTRACT_AR.RC <= 4
external_predecessors:
- name: LOAD_RATES
source: scheduler_export
unresolved:
- "Symbolic HLQ is supplied by the submission profile"
Das letzte Feld ist Teil der Dokumentation und kein peinlicher Makel. Es sagt dem Migrationsteam, welches Artefakt es als Nächstes anfordern muss.
Steuerkarten und Scheduler-Exits verdienen besondere Aufmerksamkeit. Ein einzeiliger JCL-Schritt kann Hunderte Parameterzeilen aus einem Datensatz beziehen, der außerhalb der Versionsverwaltung gepflegt wird. Ein Scheduler-Exit kann Variablen umschreiben oder eine Prozedurbibliothek auswählen. Behandeln Sie referenzierte, aber fehlende Steuerdaten als externe Abhängigkeit mit einem Verantwortlichen und einem Beschaffungsauftrag.
Laufzeitbelege verändern die Antwort
Statische Extraktion beschreibt, was das Repository zulässt. Laufzeitbelege zeigen, was ausgewählte Ausführungen tatsächlich getan haben. Keine Sicht darf sich als die andere ausgeben.
Aufgezeichnete Traces, Protokolle von Datenbankanweisungen, Job-Verläufe, Nachrichtenmetadaten, Dateikataloge und Produktionsverkehr können dynamische Ziele bestätigen und Pfade priorisieren. Sie können zeigen, dass ein konfigurierbarer Dispatcher während des Erfassungszeitraums drei von zwanzig möglichen Programmen gewählt hat. Sie können nicht beweisen, dass die anderen siebzehn tot sind. Das Fehlen in einer Spur bedeutet "in dieser Stichprobe nicht beobachtet" und nicht "unerreichbar".
Die stärkste Dokumentation speichert statische und beobachtete Kanten getrennt und bietet dann Schnittmenge und Unterschiede an. Nehmen wir eine Aufrufstelle mit einer konfigurierten Zielliste aus RATEA, RATEB und RATEC. Ein Monatsabschluss-Trace sieht RATEA und RATEC. Der richtige Datensatz behält alle drei möglichen Ziele, markiert zwei als beobachtet und erfasst Zeitraum und Umgebung. RATEB aus dem Graphen zu löschen, würde begrenzte Belege in eine falsche Aussage verwandeln.
Produktionsverkehr hilft auch, Verhalten während einer Neuentwicklung zu prüfen. Ein- und Ausgaben können zu Paritätsfällen werden, wenn die Erfassung sensible Daten entfernt oder schützt und die verhaltensbestimmenden Variablen erhält. Ein bestandener Paritätsfall beweist Übereinstimmung für diesen Fall. Er stellt keine allgemeine Gleichwertigkeit her. Die Dokumentation sollte deshalb die Abdeckung nach Einstiegspunkt, Verzweigung, Datenform und Fehlerklasse angeben, sofern diese Maße verfügbar sind.
An diesem Punkt wird Repository-Analyse mehr als ein hübscherer Index. Ein statischer Graph zeigt, wo Messpunkte nötig sind. Traces zeigen, welche ungeklärten Kanten Aufmerksamkeit verdienen. Unterschiede zwischen alter und neuer Ausführung legen undokumentiertes Verhalten offen, und diese Befunde können in den Evidenzspeicher zurückfließen.
Eine Laufzeitüberlagerung darf die statische Basis nie löschen. Seltene Quartalsjobs, Fehlerbehandlungen, regulatorische Exporte und Notfallverfahren können während einer normalen Erfassung fehlen. Teams erklären sie oft für tot, weil der gewöhnliche Trace schweigt, und lernen ihren Zweck erst in dem einen Ereignis kennen, in dem sie laufen.
Generierte Texte brauchen Quellen und ein Ablaufdatum
Generierte Texte werden vertrauenswürdig, wenn Prüfer jede wesentliche Aussage anfechten können, ohne den Generator zurückzuentwickeln. Stellen Sie Quellenverweise neben die Aussagen und ergänzen Sie Extraktionsrevision, Werkzeugversion, Konfiguration und Erzeugungszeit in den Dokumentmetadaten.
Der Repository-Commit ist das Wirksamkeitsdatum des Dokuments. Wenn sich der Hauptzweig ändert, ist das generierte Dokument veraltet, auch wenn sein Text noch plausibel klingt. Erzeugen Sie es in der Continuous Integration neu oder kennzeichnen Sie klar den beschriebenen Commit. Ich lasse lieber eine Aktualitätsprüfung fehlschlagen, als still alte Diagramme mit neuem Code zu mischen.
Aussagen brauchen unterschiedliche Quellenformen. Eine strukturelle Aussage kann Quellzeilen nennen. Eine Laufzeitaussage sollte einen Trace-Satz oder Job-Verlaufsexport samt Beobachtungsfenster nennen. Eine Geschäftsdefinition sollte auf ein freigegebenes Glossar, eine Regel, einen Test oder einen benannten Prüfer verweisen. Wenn keine Quelle existiert, kennzeichnen Sie die Aussage als Frage oder Ableitung.
Verwenden Sie ein kleines Prüfprotokoll, statt Unsicherheit im Text zu vergraben:
ID CLAIM CLASS EVIDENCE
DOC-041 POSTINV writes AR_LEDGER observed post_invoice.cbl:88
DOC-042 AR_LEDGER is the accounting system inferred table name, 6 writers
DOC-043 CLOSE_AR may be safely restarted unresolved no recovery rule found
Die Ausgabeform ist wichtig, weil sie das Verhalten der Prüfer verändert. Wenn alle drei Aussagen zu flüssigen Absätzen werden, akzeptieren Leser sie meist gemeinsam. Ein Protokoll zwingt die schwache Aussage dazu, schwach zu bleiben.
Das Ablaufdatum sollte selektiv sein. Ein Modulinventar kann bei jedem Merge neu entstehen. Eine von einem Bediener freigegebene Geschäftsbedeutung sollte bestehen bleiben, bis sich ihr Beleg ändert, doch das System muss Freigabe und Quelle behalten. Eine Laufzeitaussage läuft ab, sobald ihr Beobachtungsfenster die aktuelle Nutzung nicht mehr abbildet. Ein globaler Stempel "zuletzt aktualisiert" kann diese Unterschiede nicht ausdrücken.
Gemischte Sprachen brauchen ein gemeinsames Evidenzmodell
Kein einzelner Parser kann ein System dokumentieren, das COBOL, JCL, PL/SQL, Shell, Java und Tabellenmakros umfasst. Jede Sprache braucht ein Frontend, das ihre Deklarationen und Auflösungsregeln versteht. Das zusammengeführte Ergebnis braucht zugleich ein gemeinsames Vokabular für Einheiten, Einstiegspunkte, Datenbestände und Kanten.
Textsuche hat weiterhin ihren Platz, sollte aber Kandidaten finden und keine Beziehungen behaupten. Eine Suche nach einem Tabellennamen kann eingebettetes SQL, Kommentare, kopierte Definitionen, Testdaten und gleich benannte, aber unverbundene Felder finden. Ein sprachbewusster Extraktor kann einige Treffer einordnen. Ein späterer Auflösungslauf kann einen Aufruf unter der richtigen Build-Konfiguration mit einer Deklaration verbinden.
Normalisieren Sie Identitäten, ohne native Namen zu löschen. POSTINV, ein Quelldateiname, ein Lademodulname und eine Scheduler-Operation können dieselbe ausführbare Einheit in verschiedenen Phasen bezeichnen. Bewahren Sie jeden Bezeichner auf und fügen Sie eine belegte Alias-Beziehung hinzu. Wenn das Alias nur aus einer Namensregel stammt, markieren Sie es als abgeleitet. Zu frühes Zusammenführen von Identitäten erzeugt falsche Kanten, die sich später schwer entwirren lassen.
Sprachübergreifende Verbindungen zeigen sich meist an Protokollen und Artefakten statt an Symbolen. Ein COBOL-Job schreibt eine flache Datei, die ein Perl-Skript liest. Ein VB6-Client ruft eine in Delphi implementierte COM-Schnittstelle auf. Eine Stored Procedure schreibt eine Queue-Tabelle, die ein Dienst abfragt. Modellieren Sie Datei, Schnittstelle, Tabelle oder Nachricht als eigenen Knoten. Eine direkte Verbindung beider Programme würde den Vertrag verbergen, der sie tatsächlich koppelt.
Generierter Quelltext braucht zwei Datensätze: die Eingabe des Generators und das vom Build verwendete Artefakt. Wer nur Vorlagen analysiert, verpasst erzeugtes Verhalten. Wer nur erzeugte Dateien analysiert, macht Verantwortlichkeit und Neuerzeugung unklar. Die Dokumentation sollte zeigen, welche Datei bearbeitet werden darf und welche überschrieben wird.
Große Repositorys schaffen ein Skalierungsproblem, aber kein anderes Wahrheitsproblem. Parsen Sie Dateien inkrementell, speichern Sie inhaltsadressierte Ergebnisse zwischen und berechnen Sie betroffene Kanten neu, wenn sich Deklarationen oder Konfiguration ändern. Verkleinern Sie den Bereich nicht durch Stichproben von Verzeichnissen und nennen das Ergebnis eine Systemübersicht. Ein Codebaum mit einer Million Zeilen lässt sich in Teilen verarbeiten, doch seine grenzüberschreitenden Verweise müssen weiterhin gegen das gesamte Inventar aufgelöst werden.
Prüfung kann stichprobenartig und trotzdem gründlich sein
Ein Team kann generierte Dokumentation testen, ohne das gesamte Repository manuell neu zu lesen. Die Prüfung sollte nach Risiko und Kantentyp auswählen und anschließend automatische Invarianten nutzen, um breite Klassen von Extraktionsfehlern zu finden.
Beginnen Sie mit Parser-Testfällen. Geben Sie jedem Sprachextraktor kleine Beispiele für direkte Aufrufe, Aliasse, bedingte Kompilierung, dynamischen Dispatch, Includes, fehlerhafte Eingaben und Kommentare mit codeähnlichem Text. Prüfen Sie sowohl die Kanten, die er ausgeben muss, als auch die verführerischen falschen Kanten, die er ablehnen muss. Bewahren Sie verkleinerte echte Fehler als Regressionstests auf.
Führen Sie nach der Extraktion repositoryweite Invarianten aus. Jede zitierte Datei und Zeile muss am analysierten Commit existieren. Jedes aufgelöste Aufrufziel braucht eine Deklaration oder eine ausdrückliche externe Identität. Jedes Modulmitglied muss im Inventar vorkommen. Jeder Kantentyp muss erlaubte Quell- und Zielarten verwenden. Diese Prüfungen beweisen keine Bedeutung, finden aber fehlerhafte Verknüpfungen und veraltete Orte, bevor ein Prüfer sie sieht.
Wählen Sie danach ungleichmäßige Prüfstichproben. Untersuchen Sie alle unbekannten Kanten an wichtigen Einstiegspunkten, alle modulübergreifenden Schreibzugriffe, alle Scheduler-Bedingungen und einen zufälligen Anteil gewöhnlicher statischer Aufrufe. Prüfen Sie auch den negativen Raum: Wählen Sie bekannte dynamische Mechanismen und bestätigen Sie, dass das Dokument ihre Unsicherheit zeigt. Genauigkeit, die nur an einfachen direkten Aufrufen gemessen wird, belohnt die falsche Pipeline.
Ein kompakter Abnahmebericht kann sinnvolle Zahlen liefern, ohne sie in eine Qualitätsnote umzudeuten:
Analyzed commit: 7c41e2f
Parsed files: 18,442 of 18,517 discovered
Skipped files: 75 (list attached to the evidence store)
Resolved call edges: 91,208
Unknown dispatch sites: 613
Broken citations: 0
Scheduler sources: repository JCL only; current-plan export absent
Die Zahlen sind ein Beispiel für die Ausgabeform und kein Vergleichswert. Entscheidend sind der Nenner, die Liste übersprungener Dateien und die fehlende Scheduler-Quelle. Wer "18.442 Dateien analysiert" meldet, ohne die 75 übersprungenen zu nennen, lässt einen ausgefallenen Parser in einer großen Summe verschwinden.
Korrekturen aus der Prüfung sollten Regeln oder Evidenz aktualisieren und nicht nur den gerenderten Absatz. Wenn ein Prüfer ein falsches Alias findet, ergänzen Sie eine Einschränkung, die das Zusammenführen beim nächsten Mal verhindert. Wenn ein Bediener eine Geschäftsdefinition bestätigt, speichern Sie die Freigabe als eigene Quelle. Sonst erzeugt die nächste Generierung jeden korrigierten Fehler zuverlässig erneut.
Vertrauen endet an dynamischen und menschlichen Grenzen
Automatisierte Dokumentation wird an Grenzen unzuverlässig, an denen dem Repository die entscheidende Information fehlt. Die wichtigsten Grenzen sind dynamische Auswahl, externer Zustand, erzeugter oder fehlender Quelltext, Eingriffe des Betriebs, umgebungsspezifische Konfiguration und Geschäftsabsicht.
Daraus lässt sich eine Prüfliste machen:
- Lösen Sie jedes referenzierte Artefakt auf. Finden Sie eingebundene Dateien, erzeugte Quellen, Prozedurbibliotheken, Steuerkarten, Schemata und Auslieferungsmanifeste. Erfassen Sie alles Fehlende.
- Vergleichen Sie den wirklichen Build mit der Repository-Struktur. Erfassen Sie Compiler-Flags, bedingte Symbole, Schritte zur Codeerzeugung und die genauen Auslieferungseinheiten.
- Legen Sie Laufzeitbelege darüber, ohne sie für vollständig zu halten. Bewahren Sie Stichprobenzeitraum und Umgebung neben jeder beobachteten Kante auf.
- Fragen Sie den Betrieb nach Wiederanlauf, Stichtag, Überschreibung und Ausnahmewegen. Diese Regeln stehen oft in Runbooks oder Scheduler-Konsolen oder existieren nur im Gedächtnis.
- Verlangen Sie eine benannte Quelle für Geschäftsbezeichnungen. Eine plausible Auflösung eines achtstelligen Feldnamens bleibt eine Vermutung.
Ein verbreiteter Rat lautet, ein Sprachmodell solle das Repository lesen und in einem Durchlauf ein vollständiges Architekturhandbuch schreiben. Das ist beliebt, weil das erste Ergebnis schnell und schlüssig wirkt. Es ist falsch, weil Schlüssigkeit die sichtbaren Übergänge zwischen geparsten Tatsachen, Deutungen und Auslassungen entfernt. Verwenden Sie ein Modell, um einen Graphen zu erklären, Belege zu gruppieren und Fragen zu formulieren, aber behalten Sie den Evidenzgraphen als maßgebliche Instanz.
Sicherheits- und Zugriffsgrenzen können eine weitere blinde Stelle schaffen. Ein Analysator, der Scheduler-Exporte aus Produktion, verschlüsselte Konfiguration oder Datenbankkataloge nicht lesen darf, sollte das am Anfang sagen. Fehlender Zugriff darf nicht als fehlende Abhängigkeit erscheinen.
Der praktische Abnahmetest ist einfach: Wählen Sie Aussagen zufällig aus und folgen Sie ihren Quellen. Wenn Prüfer die strukturellen Aussagen nicht reproduzieren können, ist die Pipeline nicht bereit. Wenn sie diese reproduzieren können, aber dem Text widersprechen, korrigieren Sie die Ableitungsregel oder Formulierung, ohne die extrahierten Belege wegzuwerfen.
Dokumentation sollte den Neuentwicklungsplan steuern
Repository-Dokumentation rechtfertigt ihren Aufwand, wenn sie Reihenfolge, Tests und Umfang verändert. Eine Modulübersicht sollte unabhängig ersetzbare Einheiten und Knoten gemeinsamen Zustands zeigen. Ein umgekehrter Aufrufgraph sollte Aufrufer sichtbar machen, die Kompatibilitätsabdeckung brauchen. Das Datenmodell sollte Konflikte um Eigentum und verborgene Kopplung offenlegen. Der Batch-Graph sollte Stichtage und Wiederanlaufwege zeigen, die eine Neuentwicklung als Dienst bewahren muss.
Fragen Sie für die Migrationsplanung die Evidenz ab, statt sie von vorn bis hinten zu lesen. Ermitteln Sie, welche Einstiegspunkte ein mögliches Modul erreichen, welche Tabellen die vorgeschlagene Grenze überschreiten, welche Batch-Jobs es aufrufen und welche Kanten ungeklärt bleiben. Eine ungeklärte Kante an einem täglichen Abrechnungspfad verdient Arbeit vor einem vollständig erfassten Berichtsprogramm, selbst wenn das Programm mehr Zeilen hat.
Architekturmodernisierung braucht außerdem eine Verhaltensgrundlage. Jedes alte Programm in eine neue Sprache zu übertragen, erhält zufällige Grenzen und lässt generierte Diagramme vertraut aussehen, doch Vertrautheit ist ein schlechtes Entwurfskriterium. Verwenden Sie beobachtete Einstiegspunkte, Datenverträge, Nebenwirkungen und Reihenfolgebedingungen, um Kompatibilität zu definieren. Entwerfen Sie die Zieldienste dann um zusammenhängende Verantwortlichkeit.
CodeHero nutzt diese Kombination bei der Neuentwicklung alter Systeme: Die Plattform liest den gesamten gemischtsprachigen Codebaum, und ein Paritätswerkzeug vergleicht den Ersatz mit aufgezeichnetem Produktionsverkehr. Dadurch wird abgeleiteter Zweck nicht zur Tatsache. Strukturelle Extraktion und Verhaltensbelege erhalten getrennte Aufgaben, und genau diese Disziplin braucht eine Neuentwicklung.
Verlangen Sie vor der Freigabe eines generierten Dokuments eine Antwort auf eine konkrete Frage: Welche Aussagen würden sich ändern, wenn morgen der Scheduler-Export, der Laufzeit-Trace oder das Gespräch mit dem Betrieb einträfe? Kann das Dokument sie nicht benennen, hat es Unsicherheit versteckt, statt sie zu verwalten. Ein Repository kann eine ausgezeichnete Karte liefern, doch die leeren Bereiche müssen sichtbar bleiben, bis Belege sie füllen.
Bewahren Sie das Evidenzinventar nach der Auslieferung der Neuentwicklung auf. Es wird zum Regressionsorakel für veränderte Abhängigkeiten, zur Quelle für Betriebsdokumentation und zur Prüfung gegen neue zufällige Kopplung. Der Text kann altern, aber an Commits gebundene, reproduzierbare Tatsachen lassen sich bei jeder Systemänderung neu erzeugen.
FAQ
Welche Dokumentation lässt sich aus Quellcode erzeugen?
Quellcode kann Inventare, Modulübersichten, direkte Aufrufgraphen, deklarierte Datenmodelle, Build-Beziehungen und viele Datenzugriffskanten stützen. Der Generator sollte jedes Ergebnis belegen und alles kennzeichnen, was von Namensregeln oder unvollständiger Auflösung abhängt.
Kann ein Werkzeug den Geschäftszweck von Altcode verstehen?
Es kann aus Namen, Regeln, Tests und wiederholter Datennutzung geschäftliche Bedeutungen vorschlagen. Diese Vorschläge bleiben Ableitungen, bis ein Glossar, ein Mitarbeiter aus dem Betrieb, ein freigegebener Test oder eine andere maßgebliche Quelle sie bestätigt.
Wie genau ist ein automatisch erzeugter Aufrufgraph?
Direkte Aufrufe können sehr genau sein, wenn der Parser die wirkliche Build-Konfiguration verwendet. Reflection, Funktionszeiger, dynamische COBOL-Aufrufe, Konfiguration, externe Jobs und erzeugter Code schaffen Lücken, die der Graph zeigen muss.
Warum unterscheidet sich ein statischer Aufrufgraph von einem Laufzeit-Trace?
Ein statischer Graph beschreibt erlaubte Wege, die eine Analyse auflösen kann. Ein Trace zeichnet Wege auf, die in einer bestimmten Umgebung und einem bestimmten Stichprobenzeitraum genommen wurden. Beide zu verbinden ist nützlich, doch ein unbeobachteter statischer Weg ist nicht automatisch toter Code.
Kann ein Repository das vollständige Datenbankschema offenlegen?
Es kann eingecheckte DDL, Migrationen, Mappings, SQL-Verweise und Datensatzdefinitionen zeigen. Produktionskataloge, dynamisches SQL, externe Prozeduren und vom Betrieb gepflegte Dateien können abweichen, daher sollten Repository-Belege mit Datenbankmetadaten verglichen werden.
Wie findet man Abhängigkeiten zwischen Batch-Jobs automatisch?
Parsen Sie Schrittreihenfolge, ausgeführte Programme, Datensätze, Bedingungen, Steuerkarten und ausdrückliche Übermittlungen und ergänzen Sie dann Scheduler-Exporte. JCL allein kann Kalender, externe Vorgänger, Ressourcen, Überschreibungen oder den aktuellen Produktionsplan nicht belegen.
Sollte generierte Architekturdokumentation einen Vertrauenswert verwenden?
Ein einzelner Wert verbirgt, warum eine Aussage schwach ist. Verwenden Sie Klassen wie beobachtet, abgeleitet und ungeklärt und halten Sie Quelle und Auflösungsmethode neben jedem wichtigen Knoten und jeder Kante fest.
Wie oft sollte Repository-Dokumentation neu erzeugt werden?
Erzeugen Sie strukturelle Ausgaben bei jeder Änderung des analysierten Zweigs neu oder kennzeichnen Sie sie mit dem genauen Commit. Laufzeit- und menschlich bestätigte Aussagen brauchen eigene Beobachtungsfenster und Belegdaten statt eines globalen Aktualitätsstempels.
Können Sprachmodelle zuverlässige Code-Dokumentation schreiben?
Sie können extrahierte Belege erklären und nützliche Texte entwerfen, doch flüssiger Text darf nicht zur maßgeblichen Instanz werden. Parser-Datensätze, Laufzeitbeobachtungen, Quellen und ungeklärte Fragen müssen unter jeder generierten Erklärung erhalten bleiben.
Was sollte vor einer Neuentwicklung anhand generierter Dokumentation geprüft werden?
Prüfen Sie Parser-Abdeckung, übersprungene Dateien, dynamische Dispatch-Stellen, externe Artefakte, Scheduler-Quellen, Datenverantwortung, Wiederanlaufwege und Geschäftsbezeichnungen. Wählen Sie risikoreiche Kanten aus und verfolgen Sie ihre Quellen bis zum genauen analysierten Commit.