Skip to content

Storage Layout

The desktop application keeps its configuration separate from execution data. Use Settings → General → Output to select an absolute execution-data folder. The effective folder is displayed there; it is never inferred from a shortcut’s working directory. The same control is available when backend startup fails.

Saving a folder takes effect after restarting the application. Restarting stops active work. Selecting another folder does not copy, move, or delete the previous folder: its history remains there and becomes available when you select it again. An unavailable destination leaves the current setting intact. The destination must support the storage backend’s publication and file-locking operations; ordinary write permission alone is insufficient.

Application paths use a stable application identifier. For the standard build it is com.stokker.dokime; a branded distribution uses its bundle identifier.

PurposeWindowsLinux default
Configuration%LOCALAPPDATA%/<app-id>/settings.json~/.config/<app-id>/settings.json
Application state%LOCALAPPDATA%/<app-id>/state/~/.local/state/<app-id>/
Default execution data%LOCALAPPDATA%/<app-id>/data/~/.local/share/<app-id>/

Linux respects XDG_CONFIG_HOME, XDG_STATE_HOME, and XDG_DATA_HOME. Application preferences and node identity do not follow the selected execution folder. Credentials continue to use the operating system credential store.

DOKIME_OUTPUT_ROOT overrides the desktop’s saved folder and is shown explicitly in settings. A desktop attached to a native remote endpoint uses the remote server’s storage; choosing a folder on the desktop cannot configure that server. Library hosts continue to choose their own paths through RuntimeConfig.

Execution history is stored by dokime-storage, with one dataset per execution:

<storage-root>/executions/datasets/<dataset-id>/
├── objects/<object-id>
└── checkpoints/<revision-id>.json

Additional backend files track ancestry, writer locks and replication delivery. Immutable objects contain captured metadata, tables, byte streams and documents; a published checkpoint identifies a complete revision. Do not edit these files manually. Reads pin a checkpoint so later writes cannot change an inspection.

Harmos uses an in-memory journal. Process-owned temporary record storage is not replayed on startup, and resuming unfinished acquisitions after a crash is not supported. Historical inspection uses execution checkpoints rather than a harmos/journal.jsonl or state.json replay.

Each execution captures an immutable ExecutionSnapshot when its run is admitted. It contains resolved input parameters, settings and secret references, template and document definitions, and the admitted plugin content digest. Secret material is resolved for the live plugin channel and is not included in the snapshot. Editing application or plugin settings affects future admissions; it does not rewrite previously captured evidence.

The authoritative path definitions and an annotated folder tree live in crates/dokime-app/src/capabilities/exports/storage/layout.rs. exports/contracts.rs defines the JSON manifests; exports/cycle.rs assembles one validated file set. Both folder exports and ZIP downloads use that file set.

cycles/<cycle-folder>/
├── cycle.json
├── records/
│ ├── records.jsonl
│ └── manifest.json
├── telemetry/
│ ├── samples.jsonl
│ └── manifest.json
├── traceability.json
├── artifacts/
│ ├── manifest.json
│ ├── <artifact-id>/<filename>
│ └── media/<artifact-id>/<filename>
└── executions/<execution-folder>/
├── execution.json
├── records/
│ ├── records.jsonl
│ └── manifest.json
├── telemetry/
│ ├── samples.jsonl
│ └── manifest.json
├── traceability.json
└── artifacts/
├── manifest.json
├── <artifact-id>/<filename>
├── media/<artifact-id>/<filename>
└── <native-output-relative-path>

Cycle and execution folder names combine a readable slug with a deterministic identity digest. Use the IDs in JSON as join keys; never parse identity from a folder name. All manifest file paths are relative to the cycle root. Each execution manifest includes its cycle ID, execution ID and case ID.

File or directoryContract
cycle.jsonVersioned cycle manifest, cycle state, record/telemetry contracts, document definitions, pending prompts, health, traceability, and portable report references.
execution.jsonExecution manifest plus complete execution state: frozen admitted inputs, settings references, plugin digest, outputs, steps and results. Secret material is excluded by the execution snapshot contract.
records/Full typed RecordEntry rows as JSONL. The manifest records row count, sequence range and timestamp range.
telemetry/Full typed TelemetrySample rows as JSONL, including channel, schema version, timestamps, per-stream sequence, scope, values, summary and metadata. The manifest records sample count and the available contracts for the exported channels/versions.
traceability.jsonContext/provenance snapshots projected from parameters, resources, host telemetry and execution metadata. This is not the complete input parameter set.
artifacts/Arbitrary files, including uploaded attachments, generated reports and execution-native outputs. The manifest records artifact ID, cycle-relative path, original native output path when applicable, MIME type, byte length, SHA-256 and finalization state.
artifacts/media/Images and videos, classified by the existing Dokime media classifier.

Records and telemetry are scope-local: the cycle directories contain data with the cycle ID and no execution ID. Execution directories contain data for that execution. Cycle ledgers do not duplicate execution rows. Global unscoped rows and evidence from other cycles are excluded. Manifests, empty ledgers and traceability arrays are emitted even when there is no corresponding evidence; media subdirectories appear only when they contain files.

Uploaded artifacts use an ID subdirectory so equal filenames cannot overwrite one another. Native outputs preserve their relative paths beneath artifacts/; an existing leading artifacts/ is removed before placement. Images and videos are placed beneath media/ unless that prefix is already present. Native output paths must not collide with reserved manifests or other exported files: ambiguous paths fail the export. Case-insensitive collisions and Windows-reserved names are rejected to keep exports portable. Authors create native outputs through the execution file API, not by writing into a generated cycle folder.

Content.DownloadCycleBundle captures the selected cycle export and streams a bounded ZIP with metadata, contiguous chunks, completion, and final gRPC status. The ZIP begins at cycle.json and uses the same relative paths shown above. It is assembled on demand, is never saved on the server, and is never registered as a runtime artifact. There is no bundles/ directory. Clients should save the stream themselves if they need an archive. The former POST/job-receipt flow is removed.

Content.GetCycleFolderPath explicitly materializes the export under the configured storage root and returns its local path. Remote listeners reject this host-path method; it is available to the local desktop opener. The generated folder is replaced on each request; manual additions are not retained. This is a read model of durable evidence, not the runtime’s live storage or an automatic replication feed.

Exports include complete uploaded artifacts and a finite observed prefix of native files that are still growing. Telemetry is read without UI sampling or row limits. Read/decoding errors fail the export rather than producing an empty successful ledger. Runtime state, telemetry and files use their respective capture boundaries; an export of an active cycle is not a single transaction across all three stores. Export a completed, quiescent cycle when a final result is required. ZIP generation retains the export payload and archive in memory; large media exports therefore require corresponding host memory.

Layout version 4 breaks version 3: telemetry and artifact files are materialized, traceability is a single scope-root file, execution JSON includes the full execution, report references are portable paths, and bundles are transient. No legacy layout compatibility layer or persisted ZIP is produced.

Dokime markDokime · Stokker Technologies