# Local file registry

`V1FileRegistryStore` is the reference transaction boundary for a small
installation running on one machine. It keeps one complete Open Print archive
on an ordinary local filesystem.

The store is available from the Node-only package path:

```ts
import { V1FileRegistryStore } from "@open-print/core/node/file-store";
```

It is not included when a browser imports the main package.

## Issuance transaction

An issuance request supplies stable IDs, a signing context, and a callback that
builds claims after the store allocates the sequence:

```ts
const result = await store.issue({
  certificateId,
  editionId,
  eventId,
  signing,
  createClaims: ({ sequence, issuedAt }) => ({
    ...claims,
    id: certificateId,
    issuedAt,
    sequence,
  }),
});
```

The store holds its write lock while it allocates sequences, signs
certificates, appends issuance events, creates a checkpoint, builds the next
archive, and replaces the previous file. If any request in the transaction
fails, nothing is written.

Requests received in the same turn are batched. This keeps a busy free edition
from repeatedly checking the whole registry while preserving one unique
certificate and event per collector.

## Locking

The lock file coordinates processes on one local machine. Waiting writers time
out rather than proceeding without the lock. Automatic stale-lock removal is
off by default because deleting another process's live lock is worse than
stopping for an operator.

After a process crash, inspect the matching `.lock` file and confirm that no
writer is active before removing it. `staleLockMs` is retained in the beta API
shape for source compatibility but non-null values are rejected: deciding that
a lock is stale and deleting it cannot be made atomic with another writer's
acquisition using portable Node filesystem APIs.

Network filesystems do not all provide the same creation and rename
guarantees. Multi-machine services should implement this boundary with a
database transaction or compare-and-append operation.

## Signing keys

The store receives a `CryptoKey` from the calling application. It never writes
that key into the archive. Production code should load or access the private
key through protected issuer infrastructure and only pass the signing handle
into the transaction.
