Skip to content
Lumaft documentation contents
Lumaft documentation

Known limitations

What the current build does not do, in terms you can check against the running product.

Known limitations

Every entry describes what the current build does not do. Nothing here is a roadmap; a limitation leaves this page when the behavior changes, not when a change is planned. Read it before deciding whether Lumaft belongs in your environment.

Deployment and storage

SQLite is one replica, and PostgreSQL is yours to run

SQLite single-replica is Community's supported topology and it is complete. Beginning a SQLite-to-PostgreSQL adoption is Business; multiple serving PostgreSQL replicas are Enterprise. PostgreSQL is customer-operated: Lumaft does not supply, patch, replicate, or back up the server.

The single-replica rule is enforced. The process holds an exclusive lock on lumaft.db.owner; a second replica on the same file or shared volume fails to start with ownership-conflict.

Consequences on SQLite:

  • No horizontal scaling and no rolling deployment. An upgrade is a stop, then a start, and the restart is downtime.
  • WAL mode requires host-local locking. EFS, NFS, SMB, Azure Files, and shared ReadWriteMany volumes are outside the supported envelope even when the platform advertises POSIX locking. So are emptyDir, task scratch, the container writable layer, and any ECS service-managed EBS volume tied to a task.
  • Login throttling is process-local and resets on restart.

On PostgreSQL, every replica must share the same release, database, and configuration. Lapse keeps one primary serving and the others alive but not ready. Application transactions serialize installation-wide with a five-second contention bound; more replicas do not mean proportional write throughput. Change notifications have a fifteen-second poll fallback.

Upgrades are forward-only; a downgrade is a restore

Migrations run at startup, in order, transactionally, forward only. Each release declares the oldest schema revision it upgrades from and refuses older databases before touching them; a migration classified major, destructive, or long-running needs an explicit apply and a verified recovery point. A failed migration rolls back and leaves nothing partial.

An older image started against a database a newer one migrated refuses to start, naming both revisions. Pointing an older image at a migrated volume is never a rollback path; rolling back means restoring the pre-upgrade backup.

Backups are cold, and Lumaft cannot verify one exists

The supported SQLite backup is: stop, copy lumaft.db, start. A copy taken while the process runs is not valid. There is no scheduled backup, no online backup command, and no restore endpoint. Every destructive administration flow reports backupVerification: unknown and requires the administrator to attest that they took and verified a backup themselves.

Deleting evidence does not free disk

Retention expiry, retroactive shortening, purge, and forget free bytes for reuse inside the SQLite file. The file never shrinks and the volume never recovers space until an offline VACUUM runs against a stopped replica. The console's reclaimed-storage figures describe internal reuse and are a labelled lower bound. PostgreSQL needs its operator's own vacuum maintenance.

Retention is keyed to a backend's identity

The practical consequences for every backend change are in Changing your backends safely.

Lumaft's retention governs Lumaft's copy. It never deletes anything from your bucket. The fence that stops expired history being re-admitted is keyed on the backend identity Lumaft assigned when the record was configured. Removing a backend and adding it again for the same bucket produces a new identity, and history that had expired is observed again as new evidence with a fresh retention clock. Treat removing and re-adding a backend as restarting retention for everything it covers.

Coverage

History pruned before Lumaft observed it is gone

Lumaft's record begins when it first successfully reads a stack. Anything the backend had already pruned was never observed, and Lumaft does not reconstruct, extrapolate, or back-fill it. The console says so with History not observed, Before coverage began, Retention-limited interval, and Evidence pruned by retention rather than hiding it.

A restore rewinds Lumaft's record to the backup point. Backends converge forward from live state, but history from before the backup is whatever the backup held.

No attribution

The admitted field set from an update record has no actor, user, email, CI job, commit, or branch. No row will ever say who ran an operation, and no filter can search by person. Runner evidence carries the token's authority kind and, for administrators, its name — that is credential provenance, not human identity.

Transcript capture is bounded

Capture is off by default and needs a nonzero retention window, a token with capture permission, an explicit runner request, the external key, valid redaction configuration, and storage headroom. Output before permission arrives, queue overflow, interrupted delivery, and limit exhaustion leave explicit gaps. Collection admits at most 512 chunks, 8 MiB, and four hours per operation; retained text is at most 2 MiB as head and tail. Redaction cannot recognize every secret. Search, terminal emulation, and clickable content are not provided.

Runner integration

  • A correlated pair still renders as two rows. When a wrapped deployment reports itself and Lumaft also observes its backend record, both are kept as separate labelled rows. The trusted join is stored but not collapsed, and neither row links to the other.
  • Comparisons require explicit correlation and reported counts. Lumaft never infers a preview-to-apply match from timestamps, names, or similar counts.
  • policy-denied requires policy evidence. An exit code alone cannot establish it.
  • Counts require a fresh event log. Reused, malformed, oversized, or combined preview/apply logs leave counts unavailable.
  • No local spool. Undelivered evidence is lost and says so.
  • Actor labels, commit, branch, and build URL are not yet accepted.

The console

  • Export is one stack, one window, at a time. No installation-wide export, no CSV, no scheduled or API-triggered export; the format is the versioned JSON document, paged at 100 rows.
  • The Source filter is disabled. It offers only All sources; you cannot narrow the timeline to backend-only or runner-only evidence yet.
  • unknown is unreachable. It exists in the vocabulary but no source produces it, so the filter omits it.
  • Resource-to-operation association is temporal, not causal. The Operations near this change panel lists overlaps in time and labels them temporal.
  • English only, tested under Chromium only. Timestamps use a hardcoded en-US calendar with a UTC/local toggle. Firefox and WebKit are not exercised by any automated test.
  • No self-service account management. No signup, invitation, self-service password change, or session list. Lost bootstrap-administrator recovery is a file-based rotation with a restart.
  • Stack grants are not tenant isolation. They narrow retained-history reads; live observation pages remain installation-wide. Fixed administrators are never scoped.

Supported state formats

  • Lumaft reads Pulumi deployment checkpoints at envelope versions 0 through 4, with version 4 accepted only when its declared features are on Lumaft's pinned allowlist. Unknown versions and features fail closed as distinct, visible conditions.
  • The verified Pulumi CLI window is 3.245.0 through 3.258.0. Each version writes a corpus of real state that a conformance check reads on every build. State written by a CLI outside that window is unverified.
  • Pulumi has deprecated the legacy DIY layout and intends to remove it. Lumaft reads legacy state directly from S3 and is unaffected by the CLI change, but treat a legacy backend as something to migrate.
  • Other-engine backends are read at state version 4 only, from keys shaped env:/<workspace>/<project>/terraform.tfstate or <project>/terraform.tfstate beneath the configured prefix. Other versions, layouts, and multi-segment keys are unobserved.

Engine support bounds. State observation is verified against Terraform 1.15.9 and OpenTofu 1.12.6; other builds are unverified. Terraform and OpenTofu can write native S3 lock files when locking is enabled, but Lumaft does not currently observe them. Backend-native update history remains unavailable for those engines, so lock and update-history observation are Pulumi-only and these backends answer engine-unsupported for both rather than showing empty results.

Enterprise features

  • External audit delivery is a core-event feed for the named administration audit surfaces, not an export of every action. One fixed HTTPS receiver; buffering is limited to 10,000 references for seven days with visible overflow counters; retries can duplicate accepted events after an acknowledgement loss or restore. No exactly-once, ordering, completeness, or delivery SLA claim is made.
  • Whole-state capture is off by default and requires explicit backend opt-in, a separately backed-up key, and storage headroom. There is a 16 MiB per-copy ceiling. Retained state can include secrets and is available only through separate recovery grants. Lost keys cannot be reconstructed.