SOTER
Logos Fact File Spec
Purpose
Define the Logos DSL syntax for .fact files: the language-level rules for
writing fact blocks that record occurrences against a .model (Ontology)
and project through a .view (Lens).
This specification covers the language layer. The underlying storage and protocol layer — canonical envelope fields, hash chains, and sequence numbers — is owned by Akasha; see AkashaLedgerTechnicalSpec.md.
Foundational axioms (Save-First, Immutability, Bitemporality) are defined in PhilosophyConstitution.md § 2.
Scope
- The
.factfile as an immutable, append-only event log — the third pillar of the SOTER system alongside.model(Ontology) and.view(Lens). - Syntax and attributes of the
factblock (occurred_at,recorded_at,trigger,consume,produce,corrects,type). - Bitemporality as expressed at the Logos language level.
- Correction and Reconciler mechanics (
corrects,logical_compensation). - Linter error and warning codes for
.factfiles.
Non-Goals
- Storage backend, canonical byte serialization, hash-chain, or Merkle checkpoint mechanics — see AkashaLedgerTechnicalSpec.md and FactSimulatorArchitectureSpec.md.
- Fact generator, anomaly injection, or verifier implementation details — see FactSimulatorArchitectureSpec.md.
- Analytical ledger partitioning and workflow board projections — see AnalyticalLedgerWorkflowSpec.md.
.modeland.viewsyntax — see the Logos language specification.
Terminology
| Term | Meaning |
|---|---|
fact |
A single entry in the append-only Ledger, describing an occurrence. |
| Observer | Assigns recorded_at and maintains the FIFO write queue. |
| Ledger | The append-only, inviolable store of facts. |
| Verifier | Collides facts with the .model to check MES arithmetic. |
| Reconciler | Generates a compensating fact when an arithmetic gap is detected. |
| Ontological Dissonance | The state detected by the Verifier when reality and model diverge. |
occurred_at |
Phenomenon time — declared by the source (subjective). |
recorded_at |
Recording time — assigned by the Observer (objective). |
trigger |
Reference to the Action (from .model, or a prior fact) that caused this fact. |
consume / produce |
Resources (Objects) removed or created by the fact, with cost basis. |
corrects |
Reference to an earlier, incorrect fact this fact supersedes. |
| Friction | The metric recorded_at - occurred_at; informational delay. |
Model or Contract
Ledger Pipeline
Source (Sensor / UI)
↓
Observer ← assigns recorded_at, FIFO queue
↓
Ledger ← Append-only (inviolable)
↓
Verifier ← collides facts with .model (MES arithmetic)
↓
Reconciler ← generates Ontological Dissonance if a gap is detected
↓
Observer ← closed cybernetic loop (fact returns to input)
Syntax of the fact Block
fact <ID>
occurred_at: <ISO8601>
recorded_at: <ISO8601> # (optional — assigned by the Observer)
trigger: <Action-UUID>
consume:
<Object-UUID>: { amount: <number>, cost_basis: <value> <currency> }
produce:
<Object-UUID>: { cost_basis: <value> <currency> }
Complete List of Attributes
| Attribute | Required | Description |
|---|---|---|
occurred_at |
✅ | Time declared by the source (subjective) |
recorded_at |
⬜ | Objective recording time in the Ledger (assigned by the Observer) |
trigger |
✅ | UUID of the Action from .model that triggered the event |
consume |
⬜ | Consumed resources (Object) with quantities and cost basis |
produce |
⬜ | Produced resources with cost basis / market value |
corrects |
⬜ | ID of an earlier incorrect fact (immutable correction) |
type |
⬜ | logical_compensation — fact generated by the Reconciler |
Rules
- Immutability: Once written, a fact is inviolable. History is not
rewritten — it is corrected by adding a new fact with
corrects:. - Append-only FIFO: The write order is absolute. The Observer assigns
the
recorded_attimestamp at the moment of recording. - Description, not Prescription: Facts describe how things are, not how they should be. The Reconciler deals with physical consistency (arithmetics), not ethical evaluation.
f-001-style corrected facts remain in the Ledger for auditing purposes. Any state calculations ignore the corrected fact and only take the correcting fact into account.
Bitemporality
| Dimension | Attribute | Character |
|---|---|---|
| Phenomenon Time | occurred_at |
Subjective — declared by the source |
| Recording Time | recorded_at |
Objective — assigned by the system |
| Friction | recorded_at - occurred_at |
Key metric of informational delay |
Examples
Corrections (Immutable Correction)
Errors are not deleted. You create a new fact with corrects::
fact f-002
occurred_at: 2026-03-08T09:05:00
corrects: f-001
trigger: u-<action-UUID>
consume:
u-<object-UUID>: { amount: 10, cost_basis: 2000 PLN }
produce:
u-<object-UUID>: { cost_basis: 1800 PLN }
Ontological Dissonance (Reconciler)
When the Verifier detects an arithmetic gap (e.g., 200 PLN missing in the balance), the Reconciler automatically generates a compensating fact:
fact f-003
type: logical_compensation
recorded_at: 2026-03-08T09:05:01 # A millisecond after f-002
trigger: f-002
produce:
u-bug-basket: { cost_basis: 200 PLN }
This fact is injected back into the Observer's input — closing the cybernetic loop.
Complete Example
soter v1
# --- FACTS ---
# 1. Adam reports 10h — error in amount
fact f-001
occurred_at: 2026-03-08T09:00:00
trigger: u-function-implementation
consume:
u-man-hour: { amount: 10, cost_basis: 1500 PLN } # ERROR: should be 2000
produce:
u-code-feature: { cost_basis: 2000 PLN }
# 2. Adam corrects the report
fact f-002
occurred_at: 2026-03-08T09:05:00
corrects: f-001
trigger: u-function-implementation
consume:
u-man-hour: { amount: 10, cost_basis: 2000 PLN }
produce:
u-code-feature: { cost_basis: 1800 PLN } # 200 PLN "escapes"
# 3. RECONCILER: closes the balance
fact f-003
type: logical_compensation
recorded_at: 2026-03-08T09:05:01
trigger: f-002
produce:
u-bug-basket: { cost_basis: 200 PLN }
Validation
Linter rules for .fact:
| Error | Code | Condition |
|---|---|---|
Missing occurred_at |
E-F01 | Every fact must have a phenomenon time |
Missing trigger |
E-F02 | Every fact must point to an Action from .model |
trigger points to non-existent UUID |
E-F03 | Reference to an undefined Action |
| Balance gap without compensation | W-F10 | consume.cost_basis ≠ produce.cost_basis (no Reconciler fact) |
corrects points to non-existent ID |
E-F04 | Spectral correction reference |
Compatibility
The fact block described here is the Logos-language authoring surface.
When a fact is committed, it is mapped onto Akasha's canonical fact
envelope (id, stream, sequence, previous_hash, hash, and related
protocol fields) — see the Examples section of
AkashaLedgerTechnicalSpec.md. The two field
sets are related but not identical: this spec's trigger/consume/
produce express the SVO/MES semantics of an occurrence, while Akasha's
envelope carries protocol-level bookkeeping (hash chain, receipts,
signatures) that this spec does not define.
The details of technical requirements for the fact generator and cryptographic validation of the ledger (hashchain and Merkle checkpoints) can be found in FactSimulatorArchitectureSpec.md.
Open Questions
- What is the precise, canonical mapping between this spec's
factblock attributes (trigger,consume,produce) and Akasha's fact envelope fields (action,objects,payload)? - Should
correctssupport multiple prior fact IDs (as Akasha's terminology allows forcorrectsas a reference list), or remain single-valued at the Logos syntax level?
Related Documents
- AkashaLedgerTechnicalSpec.md - the storage/protocol layer that persists facts written in this syntax.
- AkashaLedgerOverview.md - entry point for ledger documentation.
- FactSimulatorArchitectureSpec.md - fact generator, hash-chain, and verifier implementation spec.
- AnalyticalLedgerWorkflowSpec.md - analytical (sandbox) ledger partitioning built on the same fact concept.
- CookbooksIndex.md - cookbook index for the fact simulator.
- PhilosophyConstitution.md - Save-First, Immutability, and Bitemporality axioms.
- DocumentationStyleGuide.md - writing profile and document-type rules.
- TechnicalSpecTemplate.md - technical document template.