Drafts and saving

Reading time 6 min

Markdown on screen, browser recovery text, saved server source, generated output and deployed reader are distinct. Draft recovery protects unsaved text in one browser profile when storage works. Save writes source explicitly. Neither automatically publishes or deploys.

State matrix

State Meaning
Loaded Baseline from selected server file
Unsaved Current text differs from confirmed baseline
Saving Exact text snapshot request in flight
Saved Confirmed snapshot equals current text
Not saved Failed/unconfirmed request; text remains
Draft Browser text plus original server baseline
Published Separate build/output operation

Save is button or Ctrl+S/Cmd+S. Typing updates local recovery but is not automatic server autosave. A blank status after initial load is not a write failure; a save of unchanged loaded text can mark Saved without sending a new request. It does not reread a concurrently changed server file.

Save one reviewed change

  1. Verify intended account, server and source path.
  2. Read loaded text and coordinate other writers.
  3. Edit intended passage and inspect preview.
  4. Save once; wait for confirmed result.
  5. If newer typing remains Unsaved, save that separately.
  6. Reopen/inspect server source without discarding intended work.
  7. Build/publish/deploy only when required and authorized.
During save Result
Type newer text Confirmed old snapshot, newer text remains dirty
Press Save again One queued continuation if newer text remains
Repeated Save presses Not an unlimited request queue
First request fails Queue dropped; explicit diagnosed retry
Open another file Late old result cannot mark new file saved
Nothing changed between requests Extra queued write omitted

The state machine tracks request sequence/path and exact sent text. This protects local status from late responses; it is not multi-writer conflict detection. A completed request for an old file may have changed that server file even when another file is now selected. Verify affected source before repeating.

“Saved (not published yet)” uses the editor’s current publish-state check. It is a reminder, not proof of remote deployment or cryptographic content equality. Publishing stages explains marker limitations.

Failed or uncertain saves

Symptom Safe response
Session expired Preserve text, sign in privately, compare current source
Permission denied Check current account/grants; do not bypass path gates
Connection failed Inspect reachability and actual file before retry
Disk/write failure Preserve text; operator repairs selected storage
Non-JSON/bad response No confirmed success; investigate
Lost success response Reconcile source, not blind repetition

Error status says Not saved and provides Retry/dismiss controls. Clicking an error indicator also retries. Dismiss hides the error presentation; it does not establish a successful write or erase dirty text. A successful save removes that file’s local recovery record.

The server’s ordinary Markdown save has no revision token or three-way merge. A second writer’s newer file can be overwritten by an older screen. Unlike Admin section/settings forms, ordinary Save does not refuse every stale source. Coordinate edits and compare latest source before replacing it.

There is also no per-page version-history/undo service or guaranteed atomic Markdown-save transaction. Keep Git/protected source backups. Editor Save can ensure parent directories exist, so saving an old authorized path after another writer moves/deletes it may recreate source; investigate missing/moved files before saving old drafts.

Browser recovery model

Item Storage
Draft text Current unsaved Markdown
Base Server text that draft began from
Time Local timestamp, not server approval
Key Encoded account plus source path
Last page Separate per-account remembered path
Scope This origin/browser profile only

Recovery uses unencrypted localStorage, not server/database synchronization. It remains after sign-out and does not follow a user to another device/browser/origin. Changing scheme/host/port can select another browser storage area. Account-key separation is organization, not encryption or protection from someone with profile access.

Storage errors/quota/private browser policies can prevent put/get/remove. Invalid JSON or nonstring text/base records are ignored. There is no promised draft retention period, off-device backup or reliable deletion after every browser event. Maintain actual source history rather than relying on recovery alone.

Recover versus server text

Opening an authorized file reads current server source before asking about a differing stored draft. If draft baseline differs from current source, the dialog warns server changed since draft started.

Choice Result
Recover draft Loads local text for review, not save
Use server text Keeps current source on screen
Draft equals server Redundant draft removed
Unauthorized/missing remembered path Not automatically reopened from tree

Choosing server text leaves differing recovery available until deliberate save/edit behavior changes/removes it. Do not assume closing the prompt securely erased old text. Choosing recovery is not a merge: compare current server source and intended draft passages before Save.

Startup prefers explicit ?file= then remembered last path, but only reopens a file present in the current authorized tree. Old drafts can remain even when no old path opens. Missing reopening is not proof the draft never existed or source was deleted.

In-app departures

Admin navigation/sign-out or ordinary same-window departure can use the native unsaved dialog. Guard attempts to store draft before presenting choices.

Choice Effect
Stay here Do not leave
Keep draft and leave Leave with local recovery only
Save and leave Attempt Save; leave only when current text no longer dirty
Escape/cancel Stay
Storage unavailable Keep disabled; save/preserve first

Typing while a Save-and-leave request is pending can leave newer text dirty, so the page remains. Read its status rather than assuming departure means every keystroke was saved. The dialog’s “kept” statement refers to local browser storage, never publication.

Selecting another file has a different Discard confirmation, not these three options. Confirming removes current draft before loading selected server file. Preserve wanted text first; do not treat Discard as a harmless background switch.

Refresh/tab-close attempts a local draft write and asks the browser’s native beforeunload warning when dirty. Browser policy controls whether/how that warning appears. Crashes, killed tabs, cleanup or unavailable storage can lose recovery. No UI promises protection against all failures.

Rename and delete interactions

The same editor’s rename checks whether target is open file/ancestor and uses departure guard. On success it rebinds current path, removes old draft key, remembers new path and preserves current text against its server baseline. Dirty text becomes recovery at the new path when storage works.

Admin/other-profile/other-tab rename does not migrate every draft. A section folder change also updates assignments and ends affected sessions, not all local recovery keys. Coordinate writers and save/preserve before shared reorganizations.

Delete affecting the open file also guards departure, then removes current recovery record and clears editor after successful source deletion. “Keep draft” before deletion is not an archive promise: successful deletion can remove that open draft record. Preserve required text separately before destructive actions. Other unrelated/profile drafts may remain.

Privacy and completion

Verify Evidence
Correct target Actual account/server/path
Recovery reviewed Latest source versus local draft
Save confirmed Intended exact text on server
Newer typing No unsaved remainder you intended to keep
Shared work Other writer changes reconciled
Reader Separate build/host check if requested
Private profile Sensitive local copies handled under policy

Do not put passwords, tokens or private runtime data into Markdown drafts. Ending sessions is not browser storage erasure. Password/settings/access forms have separate unsaved behavior; this recovery store is not a universal form backup.

Local regression tests cover draft key/error paths and save-state timing. They do not certify real Safari/browser quota, crash recovery, multi-writer merge or production disk restoration. Validation limits records the boundary.