Reference
Core store files
The store's control and ledger files: the manifest that declares the store, the ID counters, the version stamp, the append-only worklog, and the concurrency lease. Choose a file to see what it holds and what it protects.
Core store file
The store manifest
manifest.toml .working/toml/
The store's control document and discovery marker: everything a tool needs to know about a store, it learns here first.
Template
Closed keysets throughout: an unknown key in any base section is a validation finding. The base
[opf] table carries the exact discovery token standard = "opf" and the
spec version the store conforms to. The reference scaffold's base:
The top-level tables:
[opf] standard, spec_version, layout (inline | per-record),
posture (off | warn | required), import_status (none | partial | complete)
[store] sync_target (empty under the in-repo default)
[modules] governance, delivery_assurance, operational_policy, concurrent_operation
[profiles.*] additive requirement bundles (version, base_compat, posture_floor,
required_modules, extension_namespace); may only ADD requirements
[types.*] one table per enabled type, carrying its normative namespace
[providers.*] handler + roles (create, auth, sync); local-directory and
generic-git-remote ship as universal fallbacks
[views.*] kind (deterministic | composed | projection), sources, target
[deliverables.*] the curated CHANGELOG.md declaration
[archive] period ("year")
[unmanaged] pre-existing files kept in place, enumerated
[vendors] registered x-<vendor> extension namespaces
The reference scaffold writes: every module false, no profile, an empty vendor
registry, posture = "required", import_status = "none",
layout = "inline", the twelve baseline type bindings, and thirteen declared views
(the twelve Markdown views plus the DECISIONS.toml projection), each targeting
.working/<name>.
Every OPF operation resolves the store through the pointer, then validates the manifest before acting; an unreadable or unparseable manifest is a cannot-evaluate that stops the tool. A profile a tool supports is enforced fail-closed; a profile it does not support is ignored for enforcement and recorded as unevaluated, so an unknown profile does not fail base validation. Weakening the posture (required toward warn or off) is a guardrail-configuration change: it takes effect only through the maintainer's explicit, recorded authorization, and a profile floor can raise, never lower, the effective posture.
The manifest is control data, not a record source, so it has no paired Markdown view; it is,
however, what declares every other pair, because the [views.*] map is the registry
the renderer and the drift gate read. It is created by opf init, validated before a
byte is written; updated by opf upgrade (a canonical model regeneration for the
1.0.0 to 1.1.0 schema migration, never a textual edit), by the adopter's own reviewed edit to
enable a module, register a vendor, or record an unmanaged path, and by opf migrate
re-pointing the recorded sync target. It is read by every verb at store
resolution, by opf render for the view map, and by opf doctor for
posture, types, modules, unmanaged containment, and pointer-to-sync-target agreement.
The problem it solves
A store with no self-declaration forces every tool to assume, and assumptions drift.
The manifest makes the store's contract explicit and machine-checkable: a tool validates the
base before operating, enforces only what is declared, and records a profile it does not support
as present-but-unevaluated rather than failing over it. Because the machine subdirectory is
observed at each use rather than declared and trusted, renaming it is a directory move with
nothing to go stale. Tooling locates the machine store by finding exactly one immediate
subdirectory of .working/ whose manifest declares the token; zero matches or more
than one stops the tool, never guesses.
At a glance
- Declares
[opf][modules][types.*][views.*][providers.*][profiles.*]- Read by
opf renderopf doctorevery verb, at store resolution- Written by
opf initopf upgradea reviewed adopter editopf migrate
What it protects
One reviewed contract, checked at every load
One reviewed file settles what would otherwise live in tool defaults and tribal knowledge. Because the manifest is validated on every load and its keysets are closed, a misconfiguration surfaces as a named finding at the point of use, which helps prevent a tool from operating on a store it misunderstands.
Core store file
The ID counters
counters.toml .working/toml/
The ID authority: one monotonic high-water value per record namespace.
Template
Every record ID has the form <NS>-<n>: a two-letter namespace mapped
one-to-one to its type (BI for backlog_item, FN for finding, WL for worklog, and so on) and a
positive integer. This file holds the highest integer ever allocated in each namespace. A fresh
store starts every counter at zero, covering the twelve baseline namespaces plus LF, the
importer's quarantine namespace, so an import can be accepted from day one. It is the smallest
schema in the store: a schema marker and one table of namespace-to-integer pairs. The scaffolded
document, byte for byte:
Allocation increments the counter under the store's lock as one atomic claim, so no gap between choosing an ID and reserving it can double-allocate. Counters are never reset and IDs are never reused, even when a record is superseded, refuted, or its work reverted. Rotation, index rewrites, and store relocation never touch this file. The schema upgrade to 1.1.0 extends it with the CN, MD, and PP namespaces while preserving every existing high-water. Counters are a control ledger, not a record type, so no view renders from them.
It is created by opf init with all namespaces at zero, updated by ID allocation
(atomically under the store lock, whenever any process creates a record in any type) and by
opf upgrade extending the namespace roster, and read by opf doctor (for
counter completeness, monotonicity against a prior committed snapshot, and every live or archived
ID within its high-water) and by record creation, to allocate the next ID.
The problem it solves
Durable records need permanent names.
A backlog number that gets reused after a revert, or a finding ID that means two different things in two eras of the project, quietly corrupts every link and every audit trail that referenced it. A single monotonic counter per namespace, claimed atomically, makes ID permanence structural rather than a policy people must remember.
At a glance
- Tracks
<NS>-<n>12 baseline namespaces + LF monotonic high-water- Written by
opf initID allocation, atomicopf upgrade- Read by
opf doctorrecord creation
What it protects
Permanent names that still resolve later
Permanent IDs make every cross-reference in the store durable: a link written today still resolves years and relocations later. The integrity gate checks that every live ID fits within its counter and that counters only ever grow, which helps prevent silent renumbering from entering the record at all.
Core store file
The version ledger
version.toml .working/toml/
The version and release ledger: numbers, dates, spans, and digests, never prose.
Template
Two arrays of rows. Each [[release]] row records the SemVer version
(unique in the ledger), the RFC 3339 UTC date read from the clock at the release
event, the worklog_span (the inclusive, contiguous span of worklog entry IDs the
release covers), and a coverage_digest over the covered entries, computed at release
cut. Spans must tile: contiguous, non-overlapping, in ID order, so the unreleased tail is
everything after the last span. Each [[summary]] row backs one public changelog
entry: covers (a version, a range like 1.0.0..1.2.3, or
unreleased), status (working, published, or superseded), the freeze
digest once published, and superseded_by when a range rollup replaced
it. Summary rows hold digests and ranges only; prose lives in exactly one place, the root
CHANGELOG.md.
A release cut appends a row and freezes the covered worklog span; from then on any change to
those entries breaks the recorded digest and fails the gate. Publishing a changelog summary
records its freeze digest here; editing a published entry is therefore never silent, because the
changed bytes break the digest and the edit is structurally a re-publication. A fresh store
scaffolds an empty ledger (release = [], summary = []).
It renders two deterministic views: the root VERSION file (the latest release's
version as exact bytes, the one generated file that carries no header) and the optional human view
VERSION.md. Both are byte-drift-gated. The reference scaffold's pinned initial view
set declares VERSION.md; the root VERSION view row joins the manifest
where the adopter's release flow requires it (see the site note on tooling status). The ledger is
created by opf init (empty), updated by the release cut (a new append-only release
row) and the changelog publish and rollup flow (summary rows and their digests), and read by
opf render (the VERSION and VERSION.md renders), the changelog range-coverage and
freeze gates, opf doctor (span tiling, frozen coverage digests, append-only
history), and release-delta tooling in the AIQT reference suite, as a consumer of the ledger.
The problem it solves
When the version anchor, the detailed record, and the public story share a file, they tangle.
Editing the story risks the facts, and cutting a release risks the prose. Splitting them means
each can be gated on what it actually is. This ledger is one of three deliberately separated
release artefacts: it anchors the versioning, the worklog holds every fact, and
CHANGELOG.md tells the public story. The ledger is the single source for the
project's version; the root VERSION file is deterministically generated from its
latest release, as exact bytes, so the version can never live in two hand-maintained places. Its
rows are append-only and immutable, so a release, once cut, is a fixed point everything else
reconciles against.
At a glance
- Records
[[release]][[summary]]SemVer, dates, spans, digests- Feeds
VERSIONVERSION.mdCHANGELOG.md- Read by
opf renderopf doctorchangelog gates release-delta tooling
What it protects
One ledger, one version, everywhere
The drift gate makes a stale VERSION file a reported failure, and the span-tiling
rule means late attribution to a published release cannot pass the gate, rather than being
forbidden by policy.
Core store file
The worklog
worklog.toml WL .working/toml/
The detailed operational record: one entry per change, appended as the work happens.
Template
An array of [[entry]] rows using a reduced record envelope: id
(namespace WL), date, actor, a change kind
(added, changed, fixed, removed,
security, docs, or infra; a manifest may register
additional kinds), a one-line summary, optional detail, and
links and refs to the records and revisions it concerns. Its status is
the single state recorded, and it never takes the /proposed qualifier
whatever the actor: a worklog entry records a fact, not a proposal awaiting ratification.
The worklog is the fact layer of the release triad. Every change gets an entry; every entry stays forever. Entries are mutable until a release freezes their span, immutable after, and never consumed, rolled away, or deleted. Every fact ever recorded stays in the worklog or its archive, and survives store relocation byte for byte. At release, the release's coverage digest freezes the covered entries; from then on any change to them is a gate failure, and an entry can never be appended into an already-released span, because spans are contiguous frozen ID intervals. Only released, frozen spans may rotate to the archive; the unreleased tail never rotates, whatever its age or size.
It renders WORKLOG.md, a deterministic, byte-drift-gated view at
.working/ top level, opening with the standard do-not-edit header. The worklog is
created by opf init (empty), updated by every change as an appended entry (IDs
allocated through counters.toml), by pre-release corrections in place, and by rotation of
released spans into the archive; it is read by opf render (WORKLOG.md), the release
cut (span selection and coverage digest), the changelog drafting flow (summaries are drafted from
spans), and opf doctor (span tiling, frozen digests, ID partition between active and
archive).
The problem it solves
Durable facts are what make summaries safe.
Because the detail beneath a changelog entry is never lost, the public story can be re-worded, re-rolled, and re-told at any depth without risk: editing a summary can never change the facts, which persist here. The freeze-at-release rule draws the line honestly: before release, a mistake is corrected in place through ordinary review; after release, a correction is a new entry that links the one it corrects.
At a glance
- Records
[[entry]]one per change append-only, never deleted- Renders
WORKLOG.md- Read by
opf renderopf doctorrelease cut changelog drafting
What it protects
A complete record a summary can be rebuilt from
A complete, append-only change record that a summary can always be rebuilt from. A silent edit to released history breaks a recorded digest and fails the gate, which helps prevent history from being quietly rewritten.
Core store file
The single-writer lease
lease.toml .working/toml/
Present only while a run holds the store's single-writer lease; its absence is the normal state.
Template
Before mutating the store, a run takes the lease. The standard requires it to be made observable
at the store's sync target before writes begin, so a second system's reconciliation sees the held
lease and refuses. It leaves a window in which a second system can begin before it observes
the held lease, and the divergence check detects the collision afterward. The file carries the holder, the operation, and
an acquired-at timestamp read from the clock at acquisition: a closed four-key shape,
schema, holder, operation, and acquired_at.
Where the concurrent-operation module is enabled, the lease is additionally recorded as a
session_lease record (namespace SL) with the states held, released, or
reconciled.
A lease is never seized from a live holder. It is reconciled against recorded state on resume or close, and a leftover lease from a dead run is released only through that reconciliation. The standard discloses the residual honestly: between taking the lease and its reaching the sync target there is a propagation window in which two systems can both begin; the divergence check is the overlapping control that catches that collision, and the two layers together, not the lease alone, are the guard. The lease is transient operational state, not a record source, so no view renders from it.
It is created by any mutating operation at lease acquisition (a fresh store has no lease, so it
is not scaffolded), removed by the holding run at clean close or by reconciliation after a dead
run, and read by every operation's consistency check before it acts, by opf doctor
(which validates the closed shape), and by a second system's reconciliation, which refuses while
the lease is held.
The problem it solves
Two runs writing the same store at once can each produce a locally consistent state that cannot merge.
A textual merge of TOML records can silently mangle the very records the standard exists to protect. An observable held lease reduces the opportunity for concurrent writes up front, and the consistency contract's divergence check detects, after the fact, a collision that begins inside the propagation window the lease does not cover.
At a glance
- Held during
- any mutating operation the single-writer window
- Contains
schemaholderoperationacquired_at- Enforced by
- every op's consistency check
opf doctora second system's reconciliation
What it protects
Concurrency safety that is honest about its bounds
The lease plus the divergence check helps prevent two-writer corruption of the store, and the standard names the window it cannot close rather than implying a promise the mechanism cannot honour.