# Compare and restore a previous saved source version

Use Local save history to review an earlier version, restore its text and format to the editor, then choose deliberately when disk should change.

## Compatibility

Fresh current-source Windows 2.9.0 review candidate; final-package/platform checks pending

Published guidance with release-applicability limits. Confirm package applicability before following this guide.

[Download Saved-version recovery teaching source and read-only inspector (ZIP)](/_functions/kbExample?name=josim-local-save-history.zip)

Includes: history-demo.cir, inspect_source.py, README.txt.

## Choose the right kind of recovery

Local save history retains versions captured by successful Save, Save As and autosave. Restore to buffer applies the selected text and file format to the editor. It does not itself save that buffer, but a configured autosave policy can write it afterwards.

Text Undo belongs to the current session. Recovery checkpoints preserve unsaved buffers separately, including work that has never had a named source destination. Local history is neither Git history nor a backup guarantee. The checked task below restores a version that was actually saved.

## Prepare the complete teaching example

Extract history-demo.cir and inspect_source.py together, then copy the circuit to a writable teaching folder. Use the intended JoSIM®-Pro 2.9 GUI and its normal access requirements. The read-only Python inspector needs Python 3 standard library only; it does not need a licence, product binary or access to the GUI configuration.

The supplied original is 168 bytes, UTF-8 without BOM, LF and one final newline. It contains V1 IN 0 DC .1 and R1 IN 0 1000. The deliberate edited state changes those lines to V1 IN 0 DC .2 and R1 IN 0 2000, then saves as UTF-8 BOM / CRLF with a final newline, giving 178 bytes. This is a source-recovery fixture; no calculation is accepted by this guide.

## Make disk writes deliberate

Before restoring, review Tools > Preferences > Autosave. Choose Off for this teaching exercise and accept the setting. If you keep an automatic-write policy in another workflow, account for when it may save a restored buffer; buffer-only restoration is not a promise that disk will remain unchanged indefinitely.

Off does not disable recovery checkpointing. Automatic writes, interrupted-process recovery and every other autosave policy remain outside this exercise. Restore your preferred policy afterwards only when you intend its source writes.

![The actual Autosave preference panel shows Off and the separate 2000 millisecond delay field.](https://static.wixstatic.com/media/31de30_10a38e60c4ae471889408effbf9e36f9~mv2.png)

For this deliberate restore, Autosave is Off. Recovery checkpoints remain a separate feature; the displayed delay does not make Off write source files.

## Create two saved versions

1. Open the writable history-demo.cir. Opening alone does not create a saved-version timeline. If Local save history is empty, close it and use Save once; the checked unchanged first Save retained one deduplicated original version.
2. Change the V1 line to V1 IN 0 DC .2 and R1 to R1 IN 0 2000. Use the editor status-bar format controls to select CRLF and UTF-8 with BOM, keep the final newline, then Save. This creates the second saved version.
3. Choose Edit > Navigation > Local save history. Select the earlier version by its source and format, rather than assuming a row number or timestamp. Compare Current editor and Saved version, including the changed-region summary.
4. Use the View selector and Show versions/Show details controls if a narrow review hides the timeline or summary. Read the complete saved source before restoring.

![The actual history comparison shows the current 0.2 volt, 2000 ohm source in UTF-8 BOM with CRLF beside the earlier 0.1 volt, 1000 ohm source in UTF-8 with LF.](https://static.wixstatic.com/media/31de30_9c0afecda1ce4262a52a903a4d0090c1~mv2.png)

Compare both source and file format. Current editor and Saved version are read-only review panes; applying the reviewed version changes the live buffer before an explicit Save writes disk.

## Restore, inspect and save

1. Check the confirmation that you reviewed this version, then choose Restore to buffer. Without that confirmation, the checked dialog leaves the source unchanged and asks you to review first. Close cancels the review.
2. The original text and UTF-8/LF format return as an unsaved edit. With Autosave Off, disk still contains the newer BOM/CRLF version. Compare the live buffer with disk deliberately; a disk-only inspector cannot confirm an unsaved buffer.
3. Undo once to return to the newer saved source and format. Redo reapplies the restored version. Neither action writes disk in this checked Off-policy path.
4. When satisfied, choose Save. The checked save writes the original 168 bytes and adds a new history entry after the newer version. It does not erase the intervening saved version.
5. After a normal close/relaunch, explicitly reopen the saved file and its Local save history. The checked second process retained all three entries and could restore the other version into a new dirty buffer. Undoing that new restore returned to the saved original; the previous session’s text Undo history was not restored.

## Recover a blocked review

Read-only sources can be compared, but Restore is disabled. Use the supported editable-copy workflow if you need a writable independent source; do not change the original’s protection merely to complete this exercise.

If the editor or its path changes after the review opens, restoration is rejected. Close and reopen the timeline, review the current content again, then choose the intended version. The native stale-review check preserved a concurrent buffer edit and did not write disk.

A failed or missing source save is separate from history. Keep the current buffer, inspect the first save diagnostic and reconcile external disk changes before retrying. This example does not inject storage failures or qualify network filesystems.

## Understand history and Trash limits

The maintained manual documents up to 30 active versions per path for 30 days, with 8 MiB per path, 64 MiB overall, 4,096 entries and a 2 MiB snapshot limit. Trash has up to 30 versions per path for seven days within the shared budgets; pruning can remove older entries before those time limits. These are retention rules, not a backup guarantee.

Move to Trash removes a saved version from the active timeline without deleting the source file. Show deleted versions (Trash) and Recover from Trash return an entry before it can be restored. Those actions and retention/pruning behaviour are source-derived instructions, not exercised outcomes in VAL-073.

Each full source path has its own timeline, so Save As starts a destination history. Opening, editing an untitled buffer or writing a recovery checkpoint does not create saved-file history. Do not publish or hand an agent your entire configuration directory just to inspect this teaching example.

## Inspect the saved teaching source without writing it

Run in the extracted input folder. Set $Python to your Python executable, $Source to the full path of the saved teaching circuit you want to inspect, and $Expected to original or edited. For a fresh download or the final explicitly saved restoration, choose original. After saving the deliberate edit, or while that edit remains on disk beneath an unsaved restored buffer, choose edited.

The helper prints JSON and returns 0 for the exact expected bytes, 1 for a readable UTF-8 mismatch, or 2 for a refused/unreadable input. It prints no source text or path, changes no files and reads no history/configuration. It validates only these two teaching states; UTF-16 and arbitrary product source validity are outside its domain.

Treat a nonzero verdict as a reason to inspect state, not as permission to overwrite source. Matching normalized text with a different BOM or line ending is still a byte mismatch. A passed disk inspection does not prove which buffer is visible or which input a previous simulation used.

```text
& $Python -B .\inspect_source.py --source $Source --expect $Expected
if ($LASTEXITCODE -ne 0) { throw 'The saved teaching source does not match the expected state; inspect the JSON verdict before saving or running anything.' }
```

## Save history-demo.cir

```text
* Synthetic local save history teaching circuit
V1 IN 0 DC .1
R1 IN 0 1000
.OPTION SEED=321 ANALYSIS=VOLTAGE INTEGRATION=BDF
.TRAN 5p 100p 0 5p
.PRINT V(IN) I(R1)
.END
```

## Save inspect_source.py

```text
"""Read and identify the exact original or edited local-history teaching file."""
import argparse
import hashlib
import json
from pathlib import Path
import sys

ORIGINAL = '''* Synthetic local save history teaching circuit
V1 IN 0 DC .1
R1 IN 0 1000
.OPTION SEED=321 ANALYSIS=VOLTAGE INTEGRATION=BDF
.TRAN 5p 100p 0 5p
.PRINT V(IN) I(R1)
.END
'''
LIMIT = 2 * 1024 * 1024


def main():
    parser = argparse.ArgumentParser(description=__doc__)
    parser.add_argument('--source', required=True, type=Path)
    parser.add_argument('--expect', required=True, choices=['original', 'edited'])
    args = parser.parse_args()
    report = {'schema': 'sun-magnetics-teaching-source/1', 'status': 'refused',
              'expected_state': args.expect,
              'scope': 'Read-only disk inspection of these two teaching states; no buffer access, history restoration or simulation'}
    try:
        if not args.source.is_file():
            raise ValueError('Source must be an existing regular file')
        if args.source.stat().st_size > LIMIT:
            raise ValueError('Source exceeds the two MiB inspection limit')
        raw = args.source.read_bytes()
        if len(raw) > LIMIT:
            raise ValueError('Source exceeds the two MiB inspection limit')
        if raw.startswith((b'\xff\xfe', b'\xfe\xff', b'\x00\x00\xfe\xff')):
            raise ValueError('This teaching inspector accepts UTF-8 only; it is not a general editor-format validator')
        text = raw.decode('utf-8-sig', errors='strict')
        encoding = 'UTF-8 BOM' if raw.startswith(b'\xef\xbb\xbf') else 'UTF-8'
        kinds = set()
        if '\r\n' in text:
            kinds.add('CRLF')
        remainder = text.replace('\r\n', '')
        if '\n' in remainder:
            kinds.add('LF')
        if '\r' in remainder:
            kinds.add('CR')
        eol = next(iter(kinds)) if len(kinds) == 1 else ('Mixed' if kinds else 'None')
        expected_text = ORIGINAL
        expected = ORIGINAL.encode('utf-8')
        if args.expect == 'edited':
            expected_text = ORIGINAL.replace('V1 IN 0 DC .1', 'V1 IN 0 DC .2').replace('R1 IN 0 1000', 'R1 IN 0 2000')
            expected = b'\xef\xbb\xbf' + expected_text.replace('\n', '\r\n').encode('utf-8')
        report.update(status='passed' if raw == expected else 'mismatch', byte_count=len(raw),
                      encoding=encoding, line_endings=eol, final_newline=text.endswith(('\r', '\n')),
                      sha256=hashlib.sha256(raw).hexdigest(),
                      text_matches=text.replace('\r\n', '\n').replace('\r', '\n') == expected_text,
                      bytes_match=raw == expected)
    except UnicodeDecodeError:
        report['reason'] = 'Source is not valid UTF-8; no bytes were changed'
    except ValueError as error:
        report['reason'] = str(error)
    except OSError:
        report['reason'] = 'Source could not be read; no bytes were changed'
    print(json.dumps(report))
    return {'passed': 0, 'mismatch': 1, 'refused': 2}[report['status']]


if __name__ == '__main__':
    raise SystemExit(main())
```

## Check the result

Require the intended saved path, selected version, complete text and format, explicit confirmation and the expected buffer/disk distinction. At the end of this exercise, explicit Save restores the exact original bytes; the local history retains the later version too.

## If the version is unavailable

Check that you opened the intended full path and that a successful save captured the version within the documented limits. Save As, recovery copies, text Undo and Git history are different stores. Preserve any remaining source and snapshots privately; this example does not recover expired or corrupt history.

## Sources and verification details

Recorded inputs/builds only. Complete walkthrough and final-package acceptance remain separate.

- VAL-072: Windows CPython 3.13.11; two-state teaching-source inspection only. 18 read-only Python client checks inspect exact original, edited and native-saved disk bytes, distinguish normalized text from file format, and reject malformed, oversized, missing or mismatched teaching input. No history, configuration or licence writes and no simulation. The actual browser-downloaded bytes pass eight command/archive comparisons and repeat all 18 client checks. No solver or numerical acceptance, Trash deletion/recovery, retention/pruning/failure injection, autosave writes/crash recovery, physical OS picker/pointer, other platforms or final-package/full-article acceptance. The inspector reads disk at the instant of inspection; it cannot see an unsaved buffer or restore a saved version.
- VAL-073: Frozen maintained-source-matched Windows JoSIM-Pro 2.9.0 candidate. 27 independent native/source/byte checks across two normal Windows app processes cover Autosave Off, first-save deduplication, actual source edits and format conversion, comparison/Close, confirmation/read-only/stale guards, buffer-only restore, Undo/Redo, explicit Save and persistent saved history after explicit reopening. No solver or numerical acceptance, Trash deletion/recovery, retention/pruning/failure injection, autosave writes/crash recovery, physical OS picker/pointer, other platforms or final-package/full-article acceptance. One earlier abnormal native exit remains unattributed. The completed scenario explicitly settles the event loop after each modal.

- josim-history-autosave-off: Actual frozen Windows JoSIM-Pro 2.9.0 history scenario, reviewed 4 November 2026. No solver or numerical acceptance, Trash deletion/recovery, retention/pruning/failure injection, autosave writes/crash recovery, physical OS picker/pointer, other platforms or final-package/full-article acceptance. The completed native scenario retains its prior abnormal-attempt qualification.
- josim-history-compare: Actual frozen Windows JoSIM-Pro 2.9.0 history scenario, reviewed 4 November 2026. No solver or numerical acceptance, Trash deletion/recovery, retention/pruning/failure injection, autosave writes/crash recovery, physical OS picker/pointer, other platforms or final-package/full-article acceptance. The completed native scenario retains its prior abnormal-attempt qualification.

- josim-pro:docs/manual_source/sections/GUI.tex: Autosave, recovery checkpoints and Compare and restore local save history
- validation:local-history-20261104: VAL-072/073 exact source identity, modal guards, explicit saves and separate-process local history

- 18 read-only Python client checks inspect exact original, edited and native-saved disk bytes, distinguish normalized text from file format, and reject malformed, oversized, missing or mismatched teaching input. No history, configuration or licence writes and no simulation.
- 27 independent native/source/byte checks across two normal Windows app processes cover Autosave Off, first-save deduplication, actual source edits and format conversion, comparison/Close, confirmation/read-only/stale guards, buffer-only restore, Undo/Redo, explicit Save and persistent saved history after explicit reopening.
- No solver or numerical acceptance, Trash deletion/recovery, retention/pruning/failure injection, autosave writes/crash recovery, physical OS picker/pointer, other platforms or final-package/full-article acceptance.
- The earlier abnormal native exit is retained without a cause or product repair claim; the completed repeat settles each modal before continuing.

## Related guides

- [Run the intended saved netlist and recognise stale results](/knowledge-base/josim-run-current-source)
- [Review Git changes, stage selected lines and resolve a source conflict](/knowledge-base/josim-git-review)
- [Find declarations, references and source locations](/knowledge-base/josim-editor-navigation)
- [Prepare a useful support report without exposing a licence or private design](/knowledge-base/support-effective-report)
- [Choose autosave and recover unsaved source](/knowledge-base/josim-autosave-recovery)
