8000 enhancement (v3.0.0): expose LogWriter and FactRecord in every binding · Issue #467 · project-minigraf/minigraf · GitHub
[go: up one dir, main page]

Skip to content

enhancement (v3.0.0): expose LogWriter and FactRecord in every binding #467

Closed

Description

@adityamukho

Follow-up to #431. PR #466 adds the raw log writer to the Rust API on v3. This issue exposes it in every binding, so the migration tool for temporal_reasoning#378 can live in the temporal_reasoning Python package. Python comes first because it is Tier 1.

What lands in core (PR #466)

pub struct FactRecord {            // already public since #430
    pub entity: EntityId, pub attribute: String, pub value: Value,
    pub tx_count: u64, pub tx_id: u64,
    pub valid_from: i64, pub valid_to: i64,   // i64::MAX = forever
    pub asserted: bool,
}

impl LogWriter {
    pub fn create(path, opts: OpenOptions) -> Result<Self>;
    pub fn append(&mut self, rec: &FactRecord) -> Result<()>;
    pub fn advance_tx_count(&mut self, tx_count: u64) -> Result<()>;
    pub fn tx_count(&self) -> u64;
    pub fn finish(self) -> Result<()>;
}
  • Records come in transaction order. A record opens a later transaction or joins the open one with the same tx_id. Gaps are allowed, and :as-of on a gap shows the state before it.

  • The file is built at <path>.partial and renamed into place by finish. Dropping the writer without finish deletes the .partial.

  • Errors:

    • STG-043: the target or its WAL exists (at create, and again at finish).
    • API-015: a record out of transaction order, or advance_tx_count going backwards.
    • API-016: a second tx_id in one transaction.
    • API-011: two valid-time windows for one fact in one transaction.
    • WAL-003: an oversize value or ident.
    • API-014: read_only options.
    • STG-025 or STG-026: a second writer for the same path.

    A rejected record changes nothing, and the writer stays usable.

Design: docs/superpowers/specs/2026-10-07-log-writer-design.md.

Binding shape

  • A FactRecord record type with the eight fields above. value uses the binding's existing value type. valid_to = i64::MAX means forever.
  • A LogWriter object with:
  • UniFFI objects are shared (Arc), so finish consumes the inner writer behind a mutex. Every call after finish is a coded error, not a panic.
  • The error codes above reach the caller as the binding's coded error, like every other code.
  • Idiom:
    • Python: a context manager whose __exit__ calls finish on success and drops the writer on an exception.
    • Java: AutoCloseable.
    • Node: finish() plus close().

The extract side, fact_log() as an FFI cursor (next_batch(n)), is planned with #462 (binding cursors). This issue needs the same FactRecord type, so whichever lands first defines it.

Checklist

  • minigraf-python (Tier 1)
  • minigraf-node
  • minigraf-java
  • minigraf-android
  • minigraf-swift
  • minigraf-c
  • minigraf-wasm: LogWriter is file-backed only (not built on wasm32), so document why it does not apply

Each binding needs tests for:

  • a round trip: records appended and finished, then the reopened file gives the same fact_log records and current_tx_count
  • a hole left by a skipped transaction
  • API-015 and STG-043 reaching the caller as coded errors
  • dropping or closing without finish leaving no file

Related: #431, #465 (open_with_options), #462 (binding cursors), #430 (fact log), temporal_reasoning#378.

🤖 Generated with Claude Code

Done (2026-10-07)

minigraf-python#6 (context manager), minigraf-java#9 (AutoCloseable), minigraf-android#6, minigraf-swift#6, minigraf-node#5 (finish() + close()), minigraf-c#4, and minigraf-wasm#4 (README: LogWriter isn't built for wasm32). Every binding exposes fact_log as a next_batch cursor and a lossless FactRecord; the UniFFI four share a MiniGrafValue enum. Each tests a round trip with identical records and current_tx_count, a hole, API-015/STG-043, and close-without-finish leaving no file. Use after finish/close is the new API-018 (core #468). append_batch reports (batch index N).

Activity

  1. added this to the v3.0.0 milestone on Oct 7, 2026
  2. added
    enhancementNew feature or request
    rustPull requests that update rust code
    migrationMigration related issue
    on Oct 7, 2026
  3. adityamukho commented on Oct 7, 2026

    @adityamukho
    CollaboratorAuthor

    All checklist items done; see the 'Done' section in the description. Ships in v3.0.0.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or requestmigrationMigration related issuerustPull requests that update rust code

    Type

    No type

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions

      0