Anforderungen an das Betriebsjournal (REQ-JRN)
Umgesetzt in crates/railit-journal, crates/railit-runtime und apps/railitd. Nachweise in crates/railit-runtime/tests/journal.rs, apps/railitd/tests/api.rs und apps/railit/tests/cli.rs.
| ID | Anforderung | Gefährdung | Nachweis |
|---|---|---|---|
| REQ-JRN-001 | Das Journal hält je Zyklus Zeitpunkt und alle Eingaben des Kerns fest, verkettet über SHA-256. Jede Veränderung, Entfernung oder Einfügung einer Zeile wird bei der Prüfung erkannt. | H-011 | tampering_breaks_the_chain, journal_verify_and_replay |
| REQ-JRN-002 | Ein Journal lässt sich gegen den aufgezeichneten Plan deterministisch abspielen. Ausgaben (Hash je Zyklus) und Zustand (Hash an Prüfpunkten) müssen übereinstimmen; die erste Abweichung wird gemeldet. Ein fremder Plan wird abgewiesen. | H-011, H-007 | journal_replays_to_the_same_state, forged_journal_is_detected_by_replay, replay_needs_the_recorded_plan, aux_operation_and_journal |
| REQ-JRN-003 | Ein Journal wird nie überschrieben. Ein Schreibfehler beendet nur das Journal, nicht den Betrieb, und wird gemeldet. Eine beim Abbruch unvollständige letzte Zeile wird erkannt und ignoriert. | H-011 | railitd --journal (öffnet nur neue Dateien), Runtime::journal_error, aux_operation_and_journal |
| REQ-JRN-004 | Mit dem Schlüssel des Stellwerks (railitd --seal-key) werden Journal und Auditprotokoll gesiegelt: Ein Siegel ist eine Ed25519-Signatur über den Hash der vorhergehenden Zeile und bestätigt sie und alle davor; im Journal folgt eines nach dem Kopf, regelmäßig und beim Beenden, im Auditprotokoll eines nach jedem Eintrag. Die Prüfung mit dem öffentlichen Schlüssel weist fremde, verfälschte und wechselnde Siegel ab und nennt die Einträge nach dem letzten Siegel; eine neu geschriebene Kette trägt kein gültiges Siegel. Ein Auditprotokoll mit fremden Siegeln verhindert den Start. | H-011 | sealed_journal_verifies_with_the_station_key, rewritten_journal_cannot_carry_the_station_seal, tampered_signature_is_detected, sealed_audit_log, foreign_seals_block_reopening, sealed_journal_and_audit_log |
| REQ-JRN-005 | Die Eingaben eines Zyklus stehen im Journal als Änderung gegenüber dem vorigen Zyklus, an Prüfpunkten vollständig. Beim Lesen werden sie exakt wieder zusammengesetzt; eine unvollständige oder ungeordnete Änderung ist ein Formatfehler. Journale der Versionen 2 und 3 bleiben lesbar. | H-011 | deltas_reconstruct_every_input_list, malformed_deltas_are_rejected, forged_journal_is_detected_by_replay |
| REQ-JRN-006 | Das Journal enthält regelmäßig (im Dienst alle zehn Minuten) einen Zustandsabzug, unmittelbar nach einem Zyklus mit vollständigen Eingaben und nie im sicheren Zustand der Sicherheitsschicht. Das Replay spielt die Abschnitte zwischen den Abzügen parallel ab; jeder Abschnitt muss genau im nächsten Abzug enden, gemeldet wird die früheste Abweichung. Das Ergebnis gleicht dem Abspielen am Stück. 24 h Betrieb bei 5000 Elementen spielen in weniger als 60 s ab (railit bench --check). | H-011 | snapshots_split_the_replay, forged_snapshot_is_detected_by_replay, journal_covers_trip_and_reset_of_the_safety_layer |
| REQ-JRN-007 | Im Knotenbetrieb (railitd --node … --journal) schreibt der Spiegel jeden Zyklus des Knotens, den er nachgerechnet und geprüft hat, mit genau dessen Eingaben, und jeden Zustandsabgleich als Zustandsübernahme. Das Replay rechnet ab einer Übernahme mit dem übernommenen Zustand weiter; Zyklen, die der Spiegel nicht gesehen hat, sind so ausgewiesen. Meldungen und Handlungen an der Sicherheitsschicht des Knotens stehen nur zur Information im Journal. Alle Szenarien werden lokal, mit 2-von-3 und auf Knoten mitgeschrieben und abgespielt. | H-011 | node_journal_replays_across_resyncs, safe_computer_nodes_over_api, all_scenarios_pass_on_safe_computer_nodes |
| REQ-JRN-008 | Diagnose aus dem Journal: Der Zustand zu einem Zeitpunkt (railit journal state --at) und die Stellbefehle und Ereignisse eines Zeitfensters (railit journal events --from --to) werden ab dem letzten Zustandsabzug bzw. der letzten Übernahme davor rekonstruiert; die Ausgaben werden neu berechnet und gegen die Hashes im Journal geprüft. Das Ergebnis gleicht dem Abspielen vom Anfang. | H-011 | window_replays_from_the_nearest_snapshot, journal_follow_state_and_events |
| REQ-JRN-009 | Ein wachsendes Journal lässt sich mitlesen (Follower, railit journal follow): Jede neue Zeile wird sofort geprüft (Kette, Siegel, Format) und nachgerechnet; der Zustand des Mitlesers gleicht nach jedem Zyklus dem des Stellwerks, auch wenn die Bytes in beliebigen Stücken ankommen. Eine unvollständige letzte Zeile wartet auf den Rest; nach der ersten Abweichung bleibt der Mitleser mit dem Fehler stehen. | H-011, H-015 | follower_tracks_the_running_interlocking, follower_reads_node_journal, journal_follow_state_and_events, mutated_journals, rechained_snapshot_mutations |
| REQ-JRN-010 | Zeitstempel: Siegel tragen die Uhrzeit des Stellwerks (UTC), sie ist Teil der Signatur, und die Zeiten der Siegel einer Datei laufen nicht zurück; die Prüfung nennt die Zeitspanne der Siegel. Ein Zeuge mit eigenem Schlüssel bestätigt mit railit journal witness, dass der aktuelle Stand einer Datei (Journal oder Auditprotokoll) zu seiner Uhrzeit bestand (<Datei>.witness); verify --witness-key prüft Signatur, Zuordnung zu einer Zeile der Kette und dass spätere Zeilen nicht früher bezeugt sind. Ein neu geschriebenes Journal passt nicht mehr zu alten Zeugnissen. | H-011 | seals_carry_signed_times_and_witnesses_attest_them, witnesses_attest_lines_in_order, journal_witness (CLI) |