Skip to main content

RuntimeStore

scripts/goal-runner/runtime_store.py defines the canonical RuntimeStore API. Every persistent mutation in ASF50 flows through it.

Construction

from pathlib import Path
from runtime_store import RuntimeStore

store = RuntimeStore(Path("scripts/goal-runner/local/runtime"))
store.migrate() # idempotent schema migration

migrate() reads schema_migrations and applies any pending migrations. It is safe to call on every orchestrator startup.

CRUD API

The store exposes a narrow API:

store.insert(table: str, row: dict) -> None
store.upsert(table: str, predicate: dict, row: dict) -> None
store.get(table: str, key: str, value: str) -> dict | None
store.list(table: str, **filters) -> list[dict]
store.delete(table: str, **filters) -> None # restricted to repair paths

There is no general "execute SQL" method.

Schema migrations

schema_migrations is a small table:

version INTEGER PRIMARY KEY,
applied_at TEXT NOT NULL,
description TEXT

A new migration is added by appending to runtime_store.MIGRATIONS and incrementing the version. The orchestrator refuses to start if the DB schema is older than the lowest migration.

Transaction semantics

Each insert/upsert/delete runs inside a transaction. The transaction is committed before the function returns. If the function raises, the transaction is rolled back.

Closing

Always close the store:

store.close()

In the orchestrator, this is done in a finally block.