Recovery
Every way back Borago Board keeps, from the recycle bin and restore points to the secret journal, held credentials and the run archive, and where each lives.
Almost nothing on a Borago Board board is destroyed when it is deleted. A task is closed, never deleted. A deleted project waits in the recycle bin for 30 days. A whole copy of the board is saved before a new version of the app may change the database. The last 10 values a credential has held are kept in a journal beside the database, and a credential that a sync removed is held rather than dropped. A task's last 100 runs are archived with their output. This page states what each layer keeps, what it deliberately leaves out, and the exact place in the app to reach it.
The layers
| Layer | Covers | Where to reach it | Surfaces |
|---|---|---|---|
| Recycle bin | Projects you deleted, with their tasks, comments and attachments | Settings, then Data & recovery, under Recycle bin | Desktop, browser on the local network, cloud browser, phone |
| Restore points | The whole board, across an app update | Settings, then Data & recovery, under Restore points | Desktop and browser on the local network only. The section is not shown on the cloud browser or the phone |
| Secret journal | The last 10 values a project's git key, each provider API key and its environment variables have held | The project's settings, under the field, in the earlier values kept on this device row | Desktop and browser on the local network only. The cloud browser and the phone see no history |
| Held credentials | A credential removed by a change that arrived by sync | The notification bell, and Settings, then Keys & credentials, under Removed credentials, still recoverable | Desktop and browser on the local network |
| Previous attempt | What a failed or interrupted run did, carried into the retry | Automatic. Nothing to press | Wherever the task runs |
| Run archive | The last 100 runs of each task, with their output | The task, under Run History | Desktop, browser on the local network, cloud browser, phone |
Tasks are closed, never deleted
There is no control that deletes a task, on any surface. A task leaves the board by being closed, and a closed task is reopened from the task itself. A task row can carry a deletion only as part of its project's deletion, which is what the recycle bin restores.
The recycle bin
Deleting a project from the board is reversible. The rows are not destroyed. The project and everything under it are marked deleted in one write, the project's containers are stopped, and the project's folder is set aside. The bin lists it for 30 days.
| Control | Where | What it does |
|---|---|---|
| Recycle bin | Settings, then Data & recovery | Lists deleted projects, newest first, each with its task count and the time left. Shown only while the bin holds something |
| Restore | On a listed project | Puts the project back, with its tasks. The board shows it again without a reload |
| Delete | On a listed project | Destroys that project now, behind two confirmations. The first asks you to type the project's name, the second says it also removes the project's containers, volumes, networks and images |
| Empty now | Above the list | Destroys every project in the bin now, behind two confirmations |
What restoring brings back and what it leaves:
- Only the tasks that were deleted in the same write as the project come back, matched on the exact moment the project was deleted. A task that was already marked deleted before the project was deleted stays deleted. Reviving it would hand the user tasks they cannot account for.
- The comments and attachments under the restored tasks come back with them.
- If a live project has taken the name meanwhile, the restored one is renamed, with a suffix such as "(restored)", because two projects cannot share one folder on disk. When the container name was the generated one it is renamed with the project, so the board keeps managing the container.
- The project's docker files are written back and its folder is put back in place.
A restore reaches the user's other devices and wins over the delete it undoes, so the project does not vanish again on the next sync. The restore travels like any other change. See Cloud sync.
At the end of the period, on every device that holds the rows, the sweep destroys them. This is the only place in the app that really destroys board data. It looks only at rows already marked deleted, so nothing visible on any board is in scope. Tasks that were marked deleted before their project was, and so were left behind by a restore, are swept the same way. The sweep runs at startup on the desktop and on the cloud, and a failure in it never stops the app from opening. Runs prune into the same sweep, described under The run archive.
Restore points
A restore point is a copy of the whole board file, saved on the desktop before a new version of the app is allowed to change the database. It exists because a test can only catch the failures it knows to look for, and a release that damages a board is discovered by the user, afterwards, with nothing to go back to.
| Fact | Value |
|---|---|
| Triggers | Two, either is enough. The new build has a database change to apply, or the app's version differs from the one that last opened this board |
| A fresh, empty board | Skipped. There is nothing to lose yet |
| Kept | 2. The newest ones. Older ones are removed |
| What is copied | The board file, and the secret journal beside it |
| Where | Beside the board's database on the desktop. Local files, not cloud backups. The cloud holds the account's live data and offers no earlier copy to restore. Its own backups exist for disaster recovery, not for rolling your board back |
| On the cloud | None are taken. The section says so by not appearing |
| If taking one fails | The failure is logged and the app starts anyway. A board that cannot start because its safety net failed is worse than a board without one this once |
| Control | Where | What it does |
|---|---|---|
| Restore points | Settings, then Data & recovery | Lists each copy with why it was saved, when, and its size. The reasons read Saved before updating, Saved before a database upgrade, Saved before you restored an earlier copy and Saved on request, with the version where known. Shown only while at least one copy exists or a restore is queued |
| Restore | On a listed copy | Queues that copy, behind a confirmation whose button reads Restart and restore. Everything on the board is replaced with the copy. Projects, tasks and comments created since are gone. The board you have now is saved as a restore point first |
| Cancel it | On the banner saying a restore is queued | Removes the queued restore. Nothing changes at the next start |
| Delete | On a listed copy | Deletes that copy from the computer, behind a confirmation. It is the only copy, so this cannot be undone. Disabled while a restore is queued |
Restoring is applied at the next start, not at the click. The database is open while the user is clicking, and swapping the file underneath a live connection turns a recovery into a corruption. So the choice is recorded, the desktop asks to restart, with the same warning about running tasks that an update restart shows, and the copy is swapped in before the database is opened again. The current board is copied first, so going back a version is itself undoable. From the browser on the local network the queued restore waits for the desktop to be restarted by hand.
The secret journal
A credential exists in exactly two places, the board's database and the user's head or password manager, so the app keeps a way back to earlier values. Each value that becomes the stored value of a project's git key, a provider API key or its environment variables is appended to a journal file beside the desktop's database, and the newest 10 per field are kept.
| Fact | Value |
|---|---|
| What is stored | The encrypted value, byte for byte as the database held it. Never the plaintext, never a re-encryption. It can be read by exactly the keys that could read the live value |
| Versions kept | 10 per field per project. The newest survive |
| When it captures | Whenever a value changes, whether you changed it, a synced change overwrote it, or the keys were re-encrypted, and again at every start |
| An empty value | Captures nothing. There is nothing to recover from an absence |
| Syncing | Never. It is a file, and the sync moves only records |
| On the cloud | No journal at all. The cloud stores no key to read one with |
| Key changes | The journal is re-encrypted with the rest of the secrets |
| Restore points | Copied alongside each one, and put back with it |
| Account switch | The outgoing account's entries are dropped, so the next account cannot inherit them |
| Control | Where | What it does |
|---|---|---|
| A row reading N earlier values kept on this device | The project's settings, under the git key in the Project Info tab and under the variables in the Environment Variables tab | Opens the list. Shown only when the journal holds a value that is not the current one. Each entry shows when it was stored and a hint that tells versions apart, variable names or a masked tail, never a value |
| Restore | On a version | Saves that version as the current value, exactly as if it had been typed in afresh, and syncs it. Disabled for a version stored under a key this device no longer has |
| The × on a version | On a version | Forgets that one value, behind a confirmation. Offered even for a version this device cannot open |
| Forget this history | Under the list | Forgets every earlier value of that one field, behind a confirmation. The value in use is not affected |
Forgetting is the one irreversible act on the tab. The confirmation says why. The history is the last copy, it is never synced, and the value it protects is one you cannot read back off the screen.
Held credentials
When a change that arrived by sync removes a credential this desktop held, the removal is unattended, since nobody at this keyboard made it. The credential is deactivated at once, because a removal made deliberately on another device is a decision this machine respects, and holding a possibly leaked key live would be wrong. The value is held instead of dropped.
| Fact | Value |
|---|---|
| What is held | The journal version that was current, named and listed, one press from being restored |
| How long | 7 days by default. Settable up to 3,650 days. 0 means never, so nothing is destroyed unattended |
| Changing the window | Re-derives the deadline of every hold already outstanding, from when each removal happened. Raising it rescues the hold you are looking at |
| A removal you made yourself | Not held. Clearing the field in this app on this machine already answers whether you meant it, and the journal still has the value |
| Expiry | Checked at startup and on every read of the list, never by a timer. Late costs nothing, early is unrecoverable |
| Where the setting lives | Outside the database, so a database failure cannot silently reset it to the shorter default |
| Control | Where | What it does |
|---|---|---|
| Restore | In the notification bell under the notice, and in Settings, then Keys & credentials, under Removed credentials, still recoverable | Puts the credential back and syncs it to the other devices |
| Delete permanently | Beside Restore | Destroys the held value, behind a second press reading Really delete it |
| Hold removed credentials for | Settings, then Keys & credentials | The window in days |
The notice names every credential one change removed, and it stays until that project has nothing left held, so restoring the git key does not hide the environment variables still counting down. The Settings section is the backstop for a notice that was dismissed, naming the project on each row.
The account switch
Each account has its own board file on the desktop, so switching accounts closes one file and opens another. Nothing is deleted, and signing back in reopens the first account's board as it was. See Cloud sync.
Installs that switched accounts on a version older than the per-account board files saved a backup of the outgoing account's rows and then removed them locally, with the secret journal copied beside the backup. Those backups are still honoured. When the account signs in again the backup is merged into its board through the ordinary sync merge, sent to the cloud, and then archived. A current install writes no new backup.
What a retry inherits
A run that ends without finishing, on a failure the queue will retry, a provider outage, a rate limit, an authentication error or a block, hands its output to the next attempt as the previous output. That text is what the model wrote, and on a run that mostly runs commands and edits files it is almost nothing. So the board also hands the next attempt a list of the commands the unfinished attempt ran, most recent last, marked as started rather than succeeded, so the retry re-checks the working tree before continuing. The paths a run edited are not listed. A stopped run gets the same list as its summary, because a run killed in its first minute usually has commands and no text.
The run archive
Each run of a task is kept as its own record, the newest 100 per task. Only the latest run's output is ever sent to a model, so a task on its sixth attempt does not re-send five dead transcripts to fail a sixth time. The one thing that crosses from the archive is a short list for the review after a run: that earlier runs happened, how each ended and one line of its summary, never a transcript.
| Fact | Value |
|---|---|
| Per run | The raw output, the outcome, the service and model that ran, start and end, an error if any, and whether the user stopped it |
| Output kept per run | Up to 1,000,000 characters. Over that, the head and the tail are kept with a marker naming how much was dropped, and the true length is recorded |
| Runs kept per task | 100. The newest win. An older run is marked deleted and its output cleared in the same write, then swept with the recycle bin's sweep |
| Written | Once, at the end of the run, on every path a run can end by. A failure to archive never fails the run |
| On the cloud | Every run's row on every plan. The newest run's output on every plan. Older runs' output only on Pro and Max, and during the trial, see pricing. The desktop keeps the output of every archived run regardless |
| Control | Where | What it does |
|---|---|---|
| Run History | In the task, under the latest run's output, with the count in brackets | Expands the list of runs, newest first, each with its number, outcome, duration, when it ended and what ran it. One run expands at a time, and its output is fetched only then |
| A notice under the list | Same place, on Basic, which has no transcript history, when an older run's output is not on the cloud | Says that only the latest run's output is kept in the cloud on this plan, and that the full output stays on the desktop that ran it |
Where each control lives
| Label | Where | What it does | Default | Surfaces | Notes |
|---|---|---|---|---|---|
| Recycle bin | Settings, then Data & recovery | Deleted projects, restorable for 30 days | Shown when non-empty | All | Restore, Delete, Empty now |
| Restore points | Settings, then Data & recovery | Whole-board copies saved before an update | Shown when one exists | Desktop, local browser | Restore, Cancel it, Delete |
| Removed credentials, still recoverable | Settings, then Keys & credentials | Credentials a sync removed, still held | Shown when one is held | Desktop, local browser | Restore, Delete permanently |
| Hold removed credentials for | Settings, then Keys & credentials | Days before a held credential is destroyed | 7 | Desktop, local browser | 0 keeps it until you choose |
| Saved keys | Settings, then Keys & credentials | The vault of keys linked into projects | All | Not a recovery layer. A linked key is not copied into the project, so deleting one leaves the link and the run fails loudly | |
| N earlier values kept on this device | The project, under the git key and under the environment variables | The secret journal for that field | Shown when an earlier value exists | Desktop, local browser | Restore, forget one, Forget this history |
| Run History | The task | The run archive for that task | Collapsed | All |
Related: Recovering things, Restore a deleted project and roll back an upgrade, Cloud sync, Security, Secrets and environment variables.