Problem
persistence.mode is declared, validated, defaulted, and then ignored by every managed service.
Rendering a service that declares mode: ephemeral produces the same runtime as one that declares nothing:
services:
redis:
version: 8-alpine
persistence:
mode: ephemeral
command: exec redis-server --requirepass "$REDIS_PASSWORD" --appendonly yes
volumes:
- ob_sample_redis_data:/data
Measured against main. Two separate defects, and the volume is the larger one:
- The durable volume is created regardless of mode.
ob_sample_redis_data is a named Docker volume with the usual ownership labels. persistence.mode currently governs volume ownership for workloads (internal/app/runtime.go:130); services never consult it.
- AOF is hardcoded on for
redis and valkey (internal/app/services.go:131 and :139), so a service declared disposable fsyncs every write into that durable volume.
This is not limited to Redis. Every managed driver — redis, valkey, postgres, mysql, mongodb, clickhouse, rabbitmq, meilisearch, nats, minio — renders a durable data volume under mode: ephemeral.
The declaration has no effect on any managed service today.
Why it matters beyond tidiness
For a TTL-bounded cache — Monk's live quotes, forming bars, feed health, one-shot challenges — the current behaviour pays AOF fsync on every write for data the author has explicitly declared disposable, and accumulates it in a volume nothing intends to read back.
The reporting is wrong in the same direction: a service declared ephemeral still owns a durable volume, so it survives ob destroy without --volumes and counts as durable data with no backup.
Contract
Two owners, and the split is what makes an override safe.
| Concern |
Owned by |
Overridable by settings? |
| Onebox volume: durable or disposable |
persistence.mode |
no |
Server persistence flags (appendonly, save, driver equivalents) |
mode-derived default |
yes |
| Durable-data backup warning, destructive-transition gate |
persistence.mode |
no |
persistence.mode is Onebox's own statement about data lifetime and is the thing it can enforce; a driver flag has no business changing it. settings covers the server's internals, where Onebox supplies a default derived from the mode and then gets out of the way.
Rules:
- Omitted persistence stays equivalent to
durable, so existing projects render byte-identically.
durable keeps today's behaviour exactly: durable volume, AOF on for Redis and Valkey, unchanged credentials, health, and connection semantics.
ephemeral produces no durable Onebox volume, and driver defaults that match: AOF and RDB off for Redis and Valkey, equivalents for other drivers where one exists.
- Explicit
settings win over the mode-derived default, and exactly one effective value is emitted per option. Today settingsRedisFlag appends after the hardcoded flags, so an authored appendonly: no renders --appendonly yes --appendonly no.
- Where an explicit setting diverges from what the mode implies,
ob canonical shows the effective value and where it came from, and ob doctor names the divergence in a sentence an operator can act on — for example, AOF enabled on ephemeral storage survives a restart but not a recreate. This is reported, not refused: the operator may choose it, but must not be misled by it.
- Do not infer that TTLs make a service ephemeral. Data lifetime is declared, never guessed from application behaviour.
Stateful transition safety
durable to ephemeral abandons durable data and must remain a destructive persistence transition in ob plan. This issue changes what is rendered after that transition is accepted; it must not weaken the existing data-loss gate.
ephemeral to durable creates the managed volume and enables the durable defaults, without claiming any pre-transition data was migrated.
Scope
The mode-to-default derivation is small. The real work is in internal/app/services.go, where driver commands are literal strings with settings appended: producing one effective value per option means the command becomes computed rather than concatenated.
Whether every driver gains an ephemeral flag set, or only Redis and Valkey do in the first pass while the others merely stop creating a durable volume, is worth deciding explicitly rather than by omission.
Verification
- Golden runtime: omitted and explicit
durable render byte-identically to today, for every managed driver. The frozen contract digests already enforce this.
- Golden runtime:
ephemeral renders no durable Onebox volume, for every managed driver.
- Golden runtime:
ephemeral Redis and Valkey render with AOF and RDB off.
- Explicit
settings.appendonly and settings.save override the derived default and emit exactly one value per option.
ob canonical reports the effective persistence value and its origin; ob doctor names a divergence between explicit settings and the declared mode.
durable to ephemeral still requires the destructive data-lifetime acknowledgement in ob plan.
- Ephemeral services raise no durable-data backup warning.
- Generated authenticated URLs and health checks are unchanged in both modes.
- Documentation states which layer each knob owns, and that the mode is not overridable by driver settings.
Done when
persistence.mode has an observable effect on every managed service: ephemeral is disposable in both Onebox storage ownership and server persistence behaviour, durable and omitted are unchanged from today, an explicit override is possible and visible, and every transition between the two stays explicit in the plan.
Problem
persistence.modeis declared, validated, defaulted, and then ignored by every managed service.Rendering a service that declares
mode: ephemeralproduces the same runtime as one that declares nothing:Measured against
main. Two separate defects, and the volume is the larger one:ob_sample_redis_datais a named Docker volume with the usual ownership labels.persistence.modecurrently governs volume ownership for workloads (internal/app/runtime.go:130); services never consult it.redisandvalkey(internal/app/services.go:131and:139), so a service declared disposable fsyncs every write into that durable volume.This is not limited to Redis. Every managed driver —
redis,valkey,postgres,mysql,mongodb,clickhouse,rabbitmq,meilisearch,nats,minio— renders a durable data volume undermode: ephemeral.The declaration has no effect on any managed service today.
Why it matters beyond tidiness
For a TTL-bounded cache — Monk's live quotes, forming bars, feed health, one-shot challenges — the current behaviour pays AOF fsync on every write for data the author has explicitly declared disposable, and accumulates it in a volume nothing intends to read back.
The reporting is wrong in the same direction: a service declared ephemeral still owns a durable volume, so it survives
ob destroywithout--volumesand counts as durable data with no backup.Contract
Two owners, and the split is what makes an override safe.
settings?persistence.modeappendonly,save, driver equivalents)persistence.modepersistence.modeis Onebox's own statement about data lifetime and is the thing it can enforce; a driver flag has no business changing it.settingscovers the server's internals, where Onebox supplies a default derived from the mode and then gets out of the way.Rules:
durable, so existing projects render byte-identically.durablekeeps today's behaviour exactly: durable volume, AOF on for Redis and Valkey, unchanged credentials, health, and connection semantics.ephemeralproduces no durable Onebox volume, and driver defaults that match: AOF and RDB off for Redis and Valkey, equivalents for other drivers where one exists.settingswin over the mode-derived default, and exactly one effective value is emitted per option. TodaysettingsRedisFlagappends after the hardcoded flags, so an authoredappendonly: norenders--appendonly yes --appendonly no.ob canonicalshows the effective value and where it came from, andob doctornames the divergence in a sentence an operator can act on — for example, AOF enabled on ephemeral storage survives a restart but not a recreate. This is reported, not refused: the operator may choose it, but must not be misled by it.Stateful transition safety
durabletoephemeralabandons durable data and must remain a destructive persistence transition inob plan. This issue changes what is rendered after that transition is accepted; it must not weaken the existing data-loss gate.ephemeraltodurablecreates the managed volume and enables the durable defaults, without claiming any pre-transition data was migrated.Scope
The mode-to-default derivation is small. The real work is in
internal/app/services.go, where driver commands are literal strings with settings appended: producing one effective value per option means the command becomes computed rather than concatenated.Whether every driver gains an ephemeral flag set, or only Redis and Valkey do in the first pass while the others merely stop creating a durable volume, is worth deciding explicitly rather than by omission.
Verification
durablerender byte-identically to today, for every managed driver. The frozen contract digests already enforce this.ephemeralrenders no durable Onebox volume, for every managed driver.ephemeralRedis and Valkey render with AOF and RDB off.settings.appendonlyandsettings.saveoverride the derived default and emit exactly one value per option.ob canonicalreports the effective persistence value and its origin;ob doctornames a divergence between explicit settings and the declared mode.durabletoephemeralstill requires the destructive data-lifetime acknowledgement inob plan.Done when
persistence.modehas an observable effect on every managed service:ephemeralis disposable in both Onebox storage ownership and server persistence behaviour,durableand omitted are unchanged from today, an explicit override is possible and visible, and every transition between the two stays explicit in the plan.