The SISO Framework
Stream In, Stream Out: A Pure Functional Framework for AI-Assisted Software Development
Overview
SISO is an architectural framework that enables large language models to generate production-quality software through enforced constraints: immutability, pure functions, and single-responsibility transformations. By constraining the solution space, correct implementations become the path of least resistance for AI code generation.
The framework uses a layered architecture — CORE primitives, a Protocol for state declaration, and a Resolution layer that quarantines all impurity — enabling systems as complex as a full SQL database engine while preserving the framework's fundamental guarantees.
Paper
SISO: A Pure Functional Framework for Rapid AI-Assisted Software Development
Jonathan Bailey
December 2025
Download PDF
Architecture
SISO consists of three primitives and three layers. The primitives — Event, Gate, Stream — are the irreducible kernel (~150 lines). The layers — Protocol, Resolution, Persistence — extend the kernel to stateful systems without compromising its guarantees.
Core Primitives
- Events: Immutable data packets flowing through the system. A type and arbitrary data.
- Gates: Pure transformation functions. Each gate claims one event type by signature. The stream dispatches to the matching gate in O(1). Signature collision is a hard error.
- Streams: The depth-first processing loop. Events arrive via
emit(), the stream looks up the gate, transform runs immediately. Unclaimed events land in pending — the residue when processing settles.
- StreamLog: Tiered audit trail (OFF → EVENTS → DEEP → DATA). Observes decisions the stream already makes. Zero-cost when off.
Protocol Layer
- PureGate:
event → event. No state access. No side effects. Parse gates, filter gates, projection gates are PureGates.
- StateGate: Declares what state it needs via
reads(event) → ReadSet. Receives resolved state in transform(event, state) → MutationBatch. Never touches persistence directly. Still a pure function — the Runner resolves the indirection.
- ReadSet: Declares specific refs and prefix patterns the gate needs to read.
- MutationBatch: Describes puts, ref sets, ref deletes, and follow-up events. Data, not execution.
Resolution Layer
- Runner: The impure shell. The only thing in the system that touches Stream + Store + Refs. Wraps PureGates and StateGates so the Stream sees plain Gates. Resolves ReadSets against persistence, applies MutationBatches atomically, emits follow-up events.
Persistence Layer
- Store: Content-addressable object store. Canonical JSON → SHA-256 → immutable blobs. Same content always returns the same hash. The store doesn't know what it's holding.
- Refs: Named references to store hashes. A flat map of strings to strings. Set, get, delete, list by prefix.
Properties by Architecture
These properties are not bolted on. They fall out of the constraints.
- Stateless: Gates hold no state. PureGates see only the event. StateGates see the event and resolved state — never persistence directly.
- Single Effect: One signature, one gate, one transform. No ambiguity about what runs or why. Collision is a hard error, not a silent precedence bug.
- Polyglot: Gate/Event/Stream is a pattern, not a language feature. The Jaa database runs identically in JavaScript and PHP from the same architecture.
- Auditable: StreamLog observes decisions the stream already makes. Every event records whether it was claimed or fell to pending. Tiered levels add detail without changing gate code.
- Perfectly Parallel: No shared mutable state between gates. Streams are independent trees. Sub-streams share a log (append-only), not state.
- DOM-Canonical: For UI: the DOM is the state. SISO performs targeted updates via gates — no virtual DOM, no reconciliation, no re-render cycle.
Reference Implementations
1. Jaa Database Engine (JavaScript + PHP)
Complete relational database engine built on CORE primitives
SQL string in, query results out. The event chain sql → parse → plan → scan → filter → project → result is the framework's →E→E→ with typed gates. Content-addressable persistence with SHA-256 hashing. File-backed or in-memory. Interactive REPL. Dual implementation — same architecture, same tests, two languages.
- SELECT with JOINs, subqueries, CTEs (including recursive), UNION
- INSERT, UPDATE, DELETE with complex expressions
- GROUP BY, HAVING, ORDER BY, LIMIT, DISTINCT, CASE WHEN
- Aggregates (COUNT, SUM, AVG, MIN, MAX)
- Indexes, Views, Triggers, Transactions
- UPSERT (ON CONFLICT), ALTER TABLE, Constraints
- EXPLAIN, TRUNCATE
- 587 passing tests (JavaScript), 536 passing tests (PHP)
- ~5,700 lines JavaScript, ~5,900 lines PHP
DEMO: siso-framework.org/demos/jaa (non-persistent)
GitHub: github.com/siso-ai/jaa
2. Universal Math Gate (PHP)
All of symbolic mathematics in one gate
216 pattern-rewrite rules across 11 mathematical domains. The stream's depth-first loop is the evaluation engine — expressions re-enter the gate until nothing matches and the result falls to pending. Demonstrates that CORE's →E→E→ model is a term rewriting system. Math isn't calculation. It's transformation.
- Arithmetic, Algebra, Calculus (derivatives and integrals)
- Trigonometry (identities, sum/difference, double/half angle)
- Linear Algebra (determinants, eigenvalues, dot/cross products)
- Set Theory, Propositional Logic, Number Theory
- Complex Analysis (Euler's formula, conjugates, modulus)
- Differential Equations (first/second order, Laplace transforms)
- Statistics (probability, expectation, variance, distributions)
- 216 transforms across 11 domains in 1 gate
- ~600 lines of code
DEMO: siso-framework.org/demos/matek
GitHub: github.com/siso-ai/math-gate
What Makes This Work
The Protocol layer is what makes stateful systems possible without breaking purity. A StateGate doesn't read from a database — it returns a ReadSet declaring what it needs. It doesn't write to a database — it returns a MutationBatch describing what should change. The Resolution layer (Runner) is the only impure component, and it's structural, not business logic.
The persistence layer uses a content-addressable store (canonical JSON → SHA-256 → immutable blobs) with named references. This is Git's object model. Deduplication is free. Snapshots are free. The store doesn't know what it's holding — a row, a schema, a wiki page.
The result: the Jaa database is a set of gates. SQL parsing is PureGates. Table scans, inserts, updates are StateGates. The Runner wires them to persistence. The Stream dispatches events. 1,123 tests pass across two languages. The same architecture runs in JavaScript and PHP. No dependencies.
Core Principles
- Immutability: All data structures are immutable. Events carry data; they don't mutate it. The content-addressable store is append-only.
- Pure Functions: Gates have no side effects. PureGates are
event → event. StateGates are (event, state) → MutationBatch. Neither touches persistence.
- Single Responsibility: Each gate performs one transformation. One signature, one gate. O(1) dispatch.
- Event-Driven: Data flows through transformation pipelines. Unclaimed events are output, not errors.
Citation
@article{bailey2025siso,
title={SISO: A Pure Functional Framework for Rapid
AI-Assisted Software Development},
author={Bailey, Jonathan},
year={2025},
url={https://siso-framework.org}
}
License
All reference implementations are released under the GNU General Public License v3.0. See individual packages for details.
Requirements
- Jaa Database: Node.js 16+ (JS) or PHP 8.1+ (PHP)
- Universal Math Gate: PHP 8.1+
- All packages: Zero external dependencies