aboutsummaryrefslogtreecommitdiff
path: root/internal/journal
diff options
context:
space:
mode:
Diffstat (limited to 'internal/journal')
-rw-r--r--internal/journal/journal.go12
-rw-r--r--internal/journal/journal_test.go21
-rw-r--r--internal/journal/read.go110
-rw-r--r--internal/journal/read_test.go132
4 files changed, 136 insertions, 139 deletions
diff --git a/internal/journal/journal.go b/internal/journal/journal.go
index 085c88a..60dc37f 100644
--- a/internal/journal/journal.go
+++ b/internal/journal/journal.go
@@ -92,12 +92,12 @@ func endWithNewline(f *os.File) error {
// Time and ModTime are formatted with RFC3339Nano, not RFC3339: spec §9
// asks for "RFC 3339 with offset", which RFC3339Nano still is (it only adds
// an optional fractional-second field; a zero-nanosecond time formats
-// identically under both). Task 5's undo needs the fractional seconds: a
-// refusal check comparing a file's current mtime against the mtime this
-// line records must not be fooled by a file rewritten within the same
-// whole second. read.go's parser already accepts fractional seconds under
-// either constant (a documented time.Parse special case for RFC3339), so
-// only this side needed to change.
+// identically under both). Undo needs the fractional seconds: a refusal
+// check comparing a file's current mtime against the mtime this line
+// records must not be fooled by a file rewritten within the same whole
+// second. read.go's parser already accepts fractional seconds under either
+// constant (a documented time.Parse special case for RFC3339), so only
+// this side needed to change.
func (w *Writer) Append(e Entry) error {
line := strings.Join([]string{
e.Time.Format(time.RFC3339Nano),
diff --git a/internal/journal/journal_test.go b/internal/journal/journal_test.go
index e8b18ae..1d53941 100644
--- a/internal/journal/journal_test.go
+++ b/internal/journal/journal_test.go
@@ -88,16 +88,15 @@ func TestRoundTripsAwkwardNames(t *testing.T) {
}
}
-// TestAppendWritesRFC3339WithOffsetAndKeepsNanoseconds is item 13, promoted
-// to before-commit by the plan 4 final review: nothing anywhere pinned the
-// journal's on-disk time format - RFC3339Nano appears in no test file, and
-// every timestamp assertion round-trips through krino's own Writer and
-// Entries, so a change to something no other tool could parse would pass
-// silently. The journal is the only record undo has. This reads the RAW
-// bytes of a written line - not Entries, which would launder the format
-// through krino's own parser - and asserts column 1 parses as RFC 3339 with
-// a real numeric offset (not just "Z"), and that a time carrying
-// nanoseconds keeps them.
+// TestAppendWritesRFC3339WithOffsetAndKeepsNanoseconds pins the journal's
+// on-disk time format: nothing else does - RFC3339Nano appears in no test
+// file, and every timestamp assertion round-trips through krino's own
+// Writer and Entries, so a change to something no other tool could parse
+// would pass silently. The journal is the only record undo has. This
+// reads the RAW bytes of a written line - not Entries, which would
+// launder the format through krino's own parser - and asserts column 1
+// parses as RFC 3339 with a real numeric offset (not just "Z"), and that a
+// time carrying nanoseconds keeps them.
func TestAppendWritesRFC3339WithOffsetAndKeepsNanoseconds(t *testing.T) {
path := filepath.Join(t.TempDir(), "state", "krino.log")
w, err := Open(path)
@@ -151,7 +150,7 @@ func TestAppendIsAppendOnly(t *testing.T) {
// TestOpenRepairsAMissingFinalNewline: a crash can leave the log's last
// line without its newline; the next run's first line must not be glued
-// onto it, or that run could never be undone (review M8).
+// onto it, or that run could never be undone.
func TestOpenRepairsAMissingFinalNewline(t *testing.T) {
path := filepath.Join(t.TempDir(), "krino.log")
if err := os.WriteFile(path, []byte("2026-09-11T10:02:03+02:00\tR0\tdl\ta.pdf\t1\tmo"), 0o644); err != nil {
diff --git a/internal/journal/read.go b/internal/journal/read.go
index 5a1de04..aa79118 100644
--- a/internal/journal/read.go
+++ b/internal/journal/read.go
@@ -25,12 +25,12 @@ const wantFields = 13
const undoOfPrefix = "undo of "
// UndoOf returns the Detail value an undo run's run-start entry carries to
-// record which run it reverses (see undoOfPrefix). Fix wave item 2 /
-// final-wave item 17: before this, internal/engine wrote the same text as
-// a bare string literal with nothing tying it to undoOfPrefix, so a typo in
-// either would silently break Runs' Undone marking while every test stayed
-// green. This is the one place that string is built; internal/engine calls
-// it rather than keeping its own copy.
+// record which run it reverses (see undoOfPrefix). Before this,
+// internal/engine wrote the same text as a bare string literal with
+// nothing tying it to undoOfPrefix, so a typo in either would silently
+// break Runs' Undone marking while every test stayed green. This is the
+// one place that string is built; internal/engine calls it rather than
+// keeping its own copy.
func UndoOf(run string) string {
return undoOfPrefix + run
}
@@ -44,8 +44,8 @@ type Run struct {
Counts map[string]int // action -> count of status "ok"
Undone bool // a later run reversed this one
// PartlyUndone is set with Undone while fewer of the run's reversible
- // steps have been reversed, over all its undo runs, than it took
- // (triage 34l): some were declined, refused or failed.
+ // steps have been reversed, over all its undo runs, than it took: some
+ // were declined, refused or failed.
PartlyUndone bool
UndoOf string // for an undo run, the run it reverses; "" otherwise
}
@@ -67,10 +67,10 @@ type ReversedKey struct {
// ReversedSteps counts, for runID, every reversal that earlier undo runs of
// it completed ("ok" undo- entries of runs whose run-start says they undo
-// runID), so a later undo of the same run can offer only what is left
-// (review M10). An undo run's own unparsable lines are skipped; a missing
-// reversal is then offered again, where its own checks refuse it if it had
-// in fact happened.
+// runID), so a later undo of the same run can offer only what is left. An
+// undo run's own unparsable lines are skipped; a missing reversal is then
+// offered again, where its own checks refuse it if it had in fact
+// happened.
func ReversedSteps(path, runID string) (map[ReversedKey]int, error) {
lines, err := readLines(path)
if err != nil {
@@ -93,19 +93,20 @@ func ReversedSteps(path, runID string) (map[ReversedKey]int, error) {
return out, nil
}
-// Entries returns every entry belonging to runID, in file order. Since plan
-// 10 (re-review N1), an unparsable line whose run column names another run
-// is ignored, and one of this run whose directory and file columns are still
-// readable is returned as a "damaged" entry for that file, so undo refuses
-// that file alone. Otherwise a line that fails to parse is skipped, but
-// Entries fails closed within the run's own window - from its run-start line to its run-end line, or to end of
-// file when there is no run-end (a crashed run, which is precisely when
-// corruption is likely): any unparsable line found inside that window sets
-// the returned error, whether or not the line's own Run column can still be
-// read back. The mere possibility that it belonged to this run is enough,
-// because an incomplete chain must refuse the whole run rather than let an
-// undo reverse it partway (spec §10). A line outside the window is ignored
-// even when unparsable, since it cannot belong to this run.
+// Entries returns every entry belonging to runID, in file order. An
+// unparsable line whose run column names another run is ignored, and one
+// of this run whose directory and file columns are still readable is
+// returned as a "damaged" entry for that file, so undo refuses that file
+// alone. Otherwise a line that fails to parse is skipped, but Entries
+// fails closed within the run's own window - from its run-start line to
+// its run-end line, or to end of file when there is no run-end (a crashed
+// run, which is precisely when corruption is likely): any unparsable line
+// found inside that window sets the returned error, whether or not the
+// line's own Run column can still be read back. The mere possibility that
+// it belonged to this run is enough, because an incomplete chain must
+// refuse the whole run rather than let an undo reverse it partway (spec
+// §10). A line outside the window is ignored even when unparsable, since
+// it cannot belong to this run.
//
// The residual risk this leaves is a false refusal, not a false success:
// krino's lock is per directory, not global, so two processes could in
@@ -154,7 +155,7 @@ func Entries(path, runID string) ([]Entry, error) {
run, runFound := runFieldOf(line)
if runFound && run != runID {
// Another run's damaged line: runs of different directories can
- // interleave, and it says nothing about this one (re-review N1).
+ // interleave, and it says nothing about this one.
continue
}
ours := inWindow || (runFound && run == runID)
@@ -165,7 +166,7 @@ func Entries(path, runID string) ([]Entry, error) {
// A line of this run cut or damaged where its file is still
// readable: that file's chain may be missing a step, so it is
// returned as damaged and PlanUndo refuses just that file; the
- // rest of the run stays undoable (re-review N1).
+ // rest of the run stays undoable.
out = append(out, Entry{Run: runID, Dir: dir, File: file, Action: "damaged", Status: "damaged", Detail: fmt.Sprintf("line %d", i+1)})
continue
}
@@ -185,8 +186,8 @@ func Entries(path, runID string) ([]Entry, error) {
// runFieldOf best-effort extracts a line's Run column even when the line
// otherwise fails to parse, so Entries can tell whether an unparsable line
// belonged to the run it was asked for. The column counts only when a tab
-// ends it: a line cut inside it holds a prefix of some run's ID, which names
-// no run (plan 10 re-check R2).
+// ends it: a line cut inside it holds a prefix of some run's ID, which
+// names no run.
func runFieldOf(line string) (string, bool) {
f := strings.SplitN(line, "\t", 3)
if len(f) < 3 {
@@ -214,13 +215,13 @@ func fileFieldsOf(line string) (dir, file string, ok bool) {
//
// A run is marked Undone when a later run's run-start entry's Detail is
// undoOfPrefix followed by this run's ID, AND that later run actually
-// reversed something (fix wave item 2): a fully declined undo - every file
-// the reviewer chose not to reverse - still opens with that same run-start
-// (ApplyUndo logs a declined file exactly as spec §9 asks the forward path
-// to), so the Detail alone is not proof anything happened. Reproduced by
-// the reviewer: `krino undo` with every file declined left `krino log`
-// reporting the original run "(undone)" regardless. What actually happened
-// is provable from the same file: at least one "ok" undo-* entry.
+// reversed something: a fully declined undo - every file declined rather
+// than reversed - still opens with that same run-start (ApplyUndo logs a
+// declined file exactly as spec §9 asks the forward path to), so the
+// Detail alone is not proof anything happened. Without this check, `krino
+// undo` with every file declined would leave `krino log` reporting the
+// original run "(undone)" regardless. What actually happened is provable
+// from the same file: at least one "ok" undo-* entry.
func Runs(path string, n int) ([]Run, error) {
lines, err := readLines(path)
if err != nil {
@@ -230,9 +231,8 @@ func Runs(path string, n int) ([]Run, error) {
order := make([]string, 0)
byID := make(map[string]*Run)
pendingUndo := make(map[string]string) // undo run ID -> the run ID it claims to undo
- // A file whose chain ended in a permanent delete is never undone, so its
- // reversible steps do not count toward what a run took (plan 11 review
- // L8).
+ // A file whose chain ended in a permanent delete is never undone, so
+ // its reversible steps do not count toward what a run took.
type fileOf struct{ run, dir, file string }
reversibleOf := map[fileOf]int{}
deletedFile := map[fileOf]bool{}
@@ -312,22 +312,22 @@ func Runs(path string, n int) ([]Run, error) {
return runs, nil
}
-// ranAnyUndoStep reports whether counts - a run's own tally of "ok" actions,
-// by action name - includes at least one undo- action that actually
-// restored something, as opposed to merely having been started and then
-// declining every file (Important 2), or having failed to restore anything
-// while a wholly unrelated undo-mkdir still happened to succeed (the
-// coordinator's tightening of that same fix): "undo-mkdir" is deliberately
-// excluded, the one undo- action package journal cannot help but name
-// directly (this package must not import internal/engine to reuse its
-// isFileAffecting predicate - journal is the lower layer), but which draws
-// exactly the same line that predicate does. Removing a directory once it
-// turns out empty is tidiness, not a restoration: a file's own chain stops
-// after a failed file-affecting reversal, but a failed or refused
-// undo-mkdir never stops anything (see internal/engine's isFileAffecting
-// and undoFile), so it can succeed for one file while every file-affecting
-// reversal in the whole run failed - and marking the original run Undone
-// from that alone would be Important 2's bug again, by a narrower route.
+// ranAnyUndoStep reports whether counts - a run's own tally of "ok"
+// actions, by action name - includes at least one undo- action that
+// actually restored something, as opposed to merely having been started
+// and then declining every file, or having failed to restore anything
+// while a wholly unrelated undo-mkdir still happened to succeed:
+// "undo-mkdir" is deliberately excluded, the one undo- action package
+// journal cannot help but name directly (this package must not import
+// internal/engine to reuse its isFileAffecting predicate - journal is the
+// lower layer), but which draws exactly the same line that predicate
+// does. Removing a directory once it turns out empty is tidiness, not a
+// restoration: a file's own chain stops after a failed file-affecting
+// reversal, but a failed or refused undo-mkdir never stops anything (see
+// internal/engine's isFileAffecting and undoFile), so it can succeed for
+// one file while every file-affecting reversal in the whole run failed -
+// and marking the original run Undone from that alone would be the same
+// bug again, by a narrower route.
func ranAnyUndoStep(counts map[string]int) bool {
for action, n := range counts {
if n > 0 && action != "undo-mkdir" && strings.HasPrefix(action, "undo-") {
diff --git a/internal/journal/read_test.go b/internal/journal/read_test.go
index 4f1c902..d2bbd3a 100644
--- a/internal/journal/read_test.go
+++ b/internal/journal/read_test.go
@@ -104,17 +104,17 @@ func TestRunsMarksAnUndoneRun(t *testing.T) {
}
}
-// TestRunsDoesNotMarkUndoneWhenEveryFileWasDeclined is fix wave item 2
-// (Important) / final-wave item 17: an undo run's run-start Detail alone
-// used to be enough for Runs to mark the original run Undone, even when the
-// undo run went on to decline every file (spec §9's "declined files are
-// logged even though nothing happens to them", extended to undo) and
-// reversed nothing at all. Reproduced by the reviewer via pty: `krino log`
-// told the user a run had been undone when the file was still filed. Run B
-// here carries the same run-start Detail as TestRunsMarksAnUndoneRun's, but
-// every one of its file-scoped entries is "declined", never "ok" - the
-// shape ApplyUndo logs when the front end's own review declines everything
-// - so run A must come back exactly as untouched.
+// TestRunsDoesNotMarkUndoneWhenEveryFileWasDeclined: an undo run's
+// run-start Detail alone is not enough for Runs to mark the original run
+// Undone, even when the undo run went on to decline every file (spec §9's
+// "declined files are logged even though nothing happens to them",
+// extended to undo) and reversed nothing at all - otherwise `krino log`
+// would tell the user a run had been undone when the file was still
+// filed. Run B here carries the same run-start Detail as
+// TestRunsMarksAnUndoneRun's, but every one of its file-scoped entries is
+// "declined", never "ok" - the shape ApplyUndo logs when the front end's
+// own review declines everything - so run A must come back exactly as
+// untouched.
func TestRunsDoesNotMarkUndoneWhenEveryFileWasDeclined(t *testing.T) {
path := filepath.Join(t.TempDir(), "krino.log")
w, _ := Open(path)
@@ -146,19 +146,19 @@ func TestRunsDoesNotMarkUndoneWhenEveryFileWasDeclined(t *testing.T) {
}
}
-// TestRunsDoesNotMarkUndoneWhenOnlyOkEntryIsMkdir is the coordinator's
-// tightening of fix wave item 2: "at least one ok undo-* entry" is still
-// too loose, by the same shape as the bug it fixes. A file's own chain
-// stops after a failed file-affecting reversal, but a failed or refused
-// undo-mkdir deliberately does not stop anything (internal/engine's
-// isFileAffecting draws exactly this line, and undoFile's stop-on-failure
-// check shares it) - so an undo-mkdir belonging to one file can still
-// succeed even though every file-affecting reversal in the whole run
-// failed. Here x.pdf's own undo-move fails, y.pdf's own undo-move also
-// fails, and z.pdf's undo-mkdir - tidying up a directory that turned out
-// empty, not restoring anything - is the run's only "ok" entry. Marking
-// the original run Undone from that alone would be exactly Important 2's
-// bug again, by a narrower route.
+// TestRunsDoesNotMarkUndoneWhenOnlyOkEntryIsMkdir: "at least one ok
+// undo-* entry" alone is too loose a check, by the same shape as the bug
+// it fixes above. A file's own chain stops after a failed file-affecting
+// reversal, but a failed or refused undo-mkdir deliberately does not stop
+// anything (internal/engine's isFileAffecting draws exactly this line,
+// and undoFile's stop-on-failure check shares it) - so an undo-mkdir
+// belonging to one file can still succeed even though every
+// file-affecting reversal in the whole run failed. Here x.pdf's own
+// undo-move fails, y.pdf's own undo-move also fails, and z.pdf's
+// undo-mkdir - tidying up a directory that turned out empty, not
+// restoring anything - is the run's only "ok" entry. Marking the original
+// run Undone from that alone would be the same bug again, by a narrower
+// route.
func TestRunsDoesNotMarkUndoneWhenOnlyOkEntryIsMkdir(t *testing.T) {
path := filepath.Join(t.TempDir(), "krino.log")
w, _ := Open(path)
@@ -196,12 +196,12 @@ func TestRunsDoesNotMarkUndoneWhenOnlyOkEntryIsMkdir(t *testing.T) {
}
}
-// TestEntriesCrashedRunReturnsNilError is item 1: a run-start present,
-// run-end absent, and otherwise clean is exactly the crashed-run shape
-// Entries' own doc comment says it must accept - "to end of file when there
-// is no run-end (a crashed run, which is precisely when corruption is
-// likely)". Pinning it as its own test, rather than leaving it implicit in
-// tests about something else, is the point of the item.
+// TestEntriesCrashedRunReturnsNilError: a run-start present, run-end
+// absent, and otherwise clean is exactly the crashed-run shape Entries'
+// own doc comment says it must accept - "to end of file when there is no
+// run-end (a crashed run, which is precisely when corruption is likely)".
+// Pinning it as its own test, rather than leaving it implicit in tests
+// about something else, is deliberate.
func TestEntriesCrashedRunReturnsNilError(t *testing.T) {
path := filepath.Join(t.TempDir(), "krino.log")
w, _ := Open(path)
@@ -227,10 +227,10 @@ func TestEntriesCrashedRunReturnsNilError(t *testing.T) {
}
}
-// TestEntriesIntactRunReturnsNilError is item 2: a complete, clean run -
-// run-start, a step, run-end, nothing corrupt - must read back with a nil
-// error. Every other test in this file needs this to be true along the way,
-// but none of them state it as their own point; this one does.
+// TestEntriesIntactRunReturnsNilError: a complete, clean run - run-start,
+// a step, run-end, nothing corrupt - must read back with a nil error.
+// Every other test in this file needs this to be true along the way, but
+// none of them state it as their own point; this one does.
func TestEntriesIntactRunReturnsNilError(t *testing.T) {
path := filepath.Join(t.TempDir(), "krino.log")
w, _ := Open(path)
@@ -258,9 +258,9 @@ func TestEntriesIntactRunReturnsNilError(t *testing.T) {
}
}
-// TestEntriesBothFailureModesReportsBadLineFirst is item 3: a run that both
-// has an unparsable line inside its window AND lacks a readable run-start
-// must surface as the unparsable-line error, not the missing-run-start one -
+// TestEntriesBothFailureModesReportsBadLineFirst: a run that both has an
+// unparsable line inside its window AND lacks a readable run-start must
+// surface as the unparsable-line error, not the missing-run-start one -
// Entries checks badLine before sawRunStart. The run-start line here is
// destroyed unattributably (as in TestEntriesFailsClosedOnMissingRunStart),
// and a second, still-attributable line is separately corrupted so badLine
@@ -303,9 +303,9 @@ func TestEntriesBothFailureModesReportsBadLineFirst(t *testing.T) {
t.Fatal(err)
}
- // Since plan 10 a damaged line whose file is readable refuses only that
- // file (a "damaged" entry); the run as a whole still fails closed here,
- // on its missing run-start.
+ // A damaged line whose file is readable refuses only that file (a
+ // "damaged" entry); the run as a whole still fails closed here, on its
+ // missing run-start.
got, err := Entries(path, "A")
if err == nil {
t.Fatal("Entries returned no error with a missing run-start")
@@ -318,11 +318,10 @@ func TestEntriesBothFailureModesReportsBadLineFirst(t *testing.T) {
}
}
-// TestEntriesAdjacentRunStartsOneCorrupted is item 4. Ruling R2: this pins
-// what journal.Entries does TODAY for two runs whose run-start lines are
-// adjacent, one of them corrupted - it does not assert an invented "correct"
-// result, and internal/journal is not touched by this task. The log here is
-// exactly:
+// TestEntriesAdjacentRunStartsOneCorrupted pins what journal.Entries does
+// for two runs whose run-start lines are adjacent, one of them corrupted -
+// it asserts the observed behaviour, not an invented "correct" result.
+// The log here is exactly:
//
// 1 run-start A (good)
// 2 run-start B (corrupted: no tabs, unattributable)
@@ -342,11 +341,10 @@ func TestEntriesBothFailureModesReportsBadLineFirst(t *testing.T) {
// line), so it reaches the end of the file with no badLine, and instead
// fails on B's missing run-start.
//
-// Concern (not fixed here, per R2 - flagged for judgement, not code
-// change): the SAME corrupted line produces two different error shapes
-// depending only on which run asks, which is a surprising inconsistency in
-// the message a caller sees, even though both directions correctly fail
-// closed.
+// This is a known inconsistency, left as is rather than fixed: the SAME
+// corrupted line produces two different error shapes depending only on
+// which run asks, which is a surprising inconsistency in the message a
+// caller sees, even though both directions correctly fail closed.
func TestEntriesAdjacentRunStartsOneCorrupted(t *testing.T) {
path := filepath.Join(t.TempDir(), "krino.log")
w, _ := Open(path)
@@ -415,10 +413,10 @@ func TestEntriesAdjacentRunStartsOneCorrupted(t *testing.T) {
// TestEntriesReportsAMangledLine: a corrupt line that is not the log's
// final line must not be silently dropped by Entries the way Runs drops it
-// - PlanUndo needs to know a step went missing. Since plan 10 (re-review
-// N1) a line whose directory and file columns are readable is returned as a
-// "damaged" entry for that file, so only that file is refused and the rest
-// of the run can still be undone.
+// - PlanUndo needs to know a step went missing. A line whose directory and
+// file columns are readable is returned as a "damaged" entry for that
+// file, so only that file is refused and the rest of the run can still be
+// undone.
func TestEntriesReportsAMangledLine(t *testing.T) {
path := filepath.Join(t.TempDir(), "krino.log")
w, _ := Open(path)
@@ -464,9 +462,9 @@ func TestEntriesReportsAMangledLine(t *testing.T) {
}
}
-// TestEntriesIgnoresAnotherRunsDamagedLine: a damaged line whose run column
-// names another run - two directories' runs can interleave in one log - does
-// not refuse this run, even inside its window (re-review N1).
+// TestEntriesIgnoresAnotherRunsDamagedLine: a damaged line whose run
+// column names another run - two directories' runs can interleave in one
+// log - does not refuse this run, even inside its window.
func TestEntriesIgnoresAnotherRunsDamagedLine(t *testing.T) {
path := filepath.Join(t.TempDir(), "krino.log")
w, _ := Open(path)
@@ -657,8 +655,8 @@ func TestEntriesFailsClosedOnMissingRunStart(t *testing.T) {
// TestReversedStepsCountsEveryUndoOfARun: the steps earlier undo runs of a
// run already reversed - only "ok" undo entries of runs that undo it - so
-// a later undo of the same run can offer just what is left (review M10).
-// Runs also names the run an undo run reversed.
+// a later undo of the same run can offer just what is left. Runs also
+// names the run an undo run reversed.
func TestReversedStepsCountsEveryUndoOfARun(t *testing.T) {
path := filepath.Join(t.TempDir(), "krino.log")
w, err := Open(path)
@@ -705,8 +703,8 @@ func TestReversedStepsCountsEveryUndoOfARun(t *testing.T) {
// TestEntriesRefusesALineCutInsideItsRunColumn: a crash that cuts the last
// line inside its run column leaves a prefix of some run's ID - it cannot
-// be called another run's line, so inside this run's window it refuses the
-// run (plan 10 re-check R2).
+// be called another run's line, so inside this run's window it refuses
+// the run.
func TestEntriesRefusesALineCutInsideItsRunColumn(t *testing.T) {
path := filepath.Join(t.TempDir(), "krino.log")
w, _ := Open(path)
@@ -733,9 +731,9 @@ func TestEntriesRefusesALineCutInsideItsRunColumn(t *testing.T) {
}
// TestRunsMarksAPartlyUndoneRun: a run whose undo reversed some of its
-// reversible steps but not all is partly undone; once a later undo reverses
-// the rest, it is undone in full. A permanent delete counts toward neither
-// (triage 34l).
+// reversible steps but not all is partly undone; once a later undo
+// reverses the rest, it is undone in full. A permanent delete counts
+// toward neither.
func TestRunsMarksAPartlyUndoneRun(t *testing.T) {
path := filepath.Join(t.TempDir(), "krino.log")
w, _ := Open(path)
@@ -780,9 +778,9 @@ func TestRunsMarksAPartlyUndoneRun(t *testing.T) {
}
}
-// TestRunsIgnoresAPermanentlyDeletedFilesSteps: a file whose chain ended in
-// a permanent delete can never be undone, so its earlier steps do not keep
-// the run partly undone forever (plan 11 review L8).
+// TestRunsIgnoresAPermanentlyDeletedFilesSteps: a file whose chain ended
+// in a permanent delete can never be undone, so its earlier steps do not
+// keep the run partly undone forever.
func TestRunsIgnoresAPermanentlyDeletedFilesSteps(t *testing.T) {
path := filepath.Join(t.TempDir(), "krino.log")
w, _ := Open(path)