TramAI - governed AI workflows for Java and Kotlin

tramai-persistence-file

Version: 0.6.0
Status: Preview
Role: Single-node, AES-256-GCM encrypted file-backed implementations of the sovereign store contracts.

Purpose

tramai-persistence-file implements the store contracts owned by tramai-core and tramai-security — ApprovalStore, ApprovalContinuationStore, AuditStore and SuspendedInvocationStore — on top of the local filesystem. It is the durable option for single-node sovereign deployments that must not depend on a database or a cloud service.

Every record is authenticated-encrypted with AES-256-GCM. Filenames are SHA-256 digests of the record identity — never raw record IDs — and directory (0700) / file (0600) permissions are enforced, symlinks are rejected at every managed path, and an exclusive .tramai.lock prevents two JVM processes from opening the same store root.

What it provides

TypeRole
FileBackedSovereignStores.open(configuration)Composition root; returns all four stores behind one shared lock, AutoCloseable
FileBackedStoreConfiguration(rootDirectory, encryption, verifyOnOpen)Store root, encryption settings, optional integrity verification on open
FileStoreEncryptionConfiguration(activeKeyId, keyProvider)Active key id plus caller-owned key resolution
FileStoreEncryptionKeyProviderfun interface — resolve(keyId: String): SecretKey
FileApprovalStore, FileApprovalContinuationStore, FileAuditStore, FileSuspendedInvocationStoreThe four store implementations
FileStoreException hierarchyConfiguration, LockUnavailable, Permission, Corruption, UnsupportedFormat

Behavioral contracts worth knowing:

  • Atomic writes — mutable records are written to a temp sibling and ATOMIC_MOVEd into place; immutable audit events use CREATE_NEW so silent replacement is impossible.
  • Exactly-once continuation claim — claimForExecution releases the raw tool arguments once and re-encrypts the record with arguments = null. CLAIMED records never lazy-expire; only PENDING records transition to EXPIRED.
  • Hash-chained audit stream — each append validates sequence continuity, previousEventHash linkage and unique eventId; verifyAll() re-verifies the whole store on open.
  • Safe failure messages — exception text carries reason codes only, never record IDs, tool arguments, keys, ciphertext or nonces.

Dependencies

dependencies {
    implementation(platform("dev.tramai:tramai-bom:0.6.0"))
    implementation("dev.tramai:tramai-persistence-file")
}
val stores = FileBackedSovereignStores.open(
    FileBackedStoreConfiguration(
        rootDirectory = Path.of("/var/tramai/sovereign"),
        encryption = FileStoreEncryptionConfiguration(
            activeKeyId = "production-key-1",
            keyProvider = FileStoreEncryptionKeyProvider { keyId -> loadKey(keyId) },
        ),
        verifyOnOpen = true,
    ),
)

stores.approvalStore.create(request)
stores.auditStore.appendNext(streamId) { latest -> buildEvent(latest) }

stores.close() // releases the exclusive lock

Spring Boot applications normally wire these stores through tramai-spring-boot-starter-sovereign-persistence-file with tramai.sovereign.persistence.type: file instead of calling open directly.

When to use this module

  • A single-node sovereign deployment that needs durable approvals, continuations and audit without running PostgreSQL.
  • You want at-rest encryption and tamper evidence for sovereign state with a key you own.
  • You are building a reference or air-gapped deployment where the filesystem is the only available store.

When NOT to use this module

  • Multiple application nodes must share the same store — there is no distributed locking or network filesystem support.
  • You need key rotation, JDBC, or cloud KMS integration; use tramai-persistence-jdbc or a custom AuditStore / ApprovalStore implementation.
  • You are not on a POSIX filesystem — the store requires PosixFilePermissions.