# Architecture

## Purpose

Synaptopus is designed around a simple idea: unlike artificial neural system families should be able to participate in one executable process without being flattened into one model class or hidden behind a monolithic runtime.

The current Python implementation therefore separates:

- architecture families
- execution semantics
- reporting and analysis
- graph descriptions
- trace serialization

That separation is deliberate. It is meant to support both local Python experimentation and a future JavaScript or browser-based driver that uses the same conceptual model.

## Execution Model

The core runtime model is sequential and stateful.

At the lowest level, a system produces a `StepTrace`:

- `previous_state`
- `next_state`
- `candidate`
- `accepted`
- `elapsed_seconds`
- optional `metadata`

These traces are accumulated into an `ExecutionRecord`, which contains:

- all attempted steps
- the accepted subset
- final state
- total runtime

Execution records can also be merged when a run is resumed from a checkpoint. That makes it possible to preserve both the pre-checkpoint history and the post-resume continuation as one logical run.

This model is intentionally compatible with systems that:

- generate candidates
- evaluate or categorize them
- reject and retry
- maintain internal state across attempts

That makes it a better fit for hybrid cognitive loops than a purely acyclic batch pipeline.

## Component Roles

The current orchestration model defines explicit component roles:

- `Generator`
- `Critic`
- `Categorizer`
- `AcceptancePolicy`
- `StateTransition`

These are combined by `CooperativeSystem`, which performs:

1. candidate generation
2. critique
3. categorization
4. policy decision
5. state transition

The result is still emitted as a standard `StepTrace`, so all downstream reporting and serialization remains generic.

## Architecture Families

At present, Synaptopus contains three reusable architecture families:

- multilayer feedforward backpropagation
- ART1 category learning
- Hopfield-style recurrent dynamics

The long-term intent is to add more families while preserving a stable orchestration and trace model.

## Graph Schema

The graph layer is deliberately thin. It is not a second execution engine.

It provides:

- `GraphNodeSpec`
- `GraphEdgeSpec`
- `GraphSchema`
- `FunctionalNode`

Each node spec records:

- `node_id`
- `node_type`
- `input_names`
- `output_names`

Each edge spec records:

- `source_node_id`
- `source_output`
- `target_node_id`
- `target_input`

This is enough to describe a workbench graph for a future UI. The runtime semantics still live in the Python component objects and execution traces, not in the schema alone.

See [FORMATS.md](FORMATS.md) for the current JSON schema shape and examples.

## Trace Serialization

Execution traces are exported through the serialization layer as JSON-safe objects.

The important rule is that the serialization boundary is explicit:

- Python dataclasses are converted to plain objects
- tuples become JSON arrays
- nested metadata is normalized recursively

The exported structures are:

- `SerializedStepTrace`
- `SerializedExecutionRecord`
- `DemoSnapshot`

This format is intended to be consumed by future browser tooling, teaching interfaces, and experiment dashboards.

See [FORMATS.md](FORMATS.md) for current trace and report examples.

## Snapshot And Resume

Synaptopus now has a first checkpoint/resume path for its internal demos.

A `DemoSnapshot` captures:

- the demo identity
- the serialized execution record up to the checkpoint
- the mutable system internals needed to continue the run
- run parameters relevant to the checkpoint

This is intentionally more than a trace dump. A trace alone is good for inspection, but a restartable run also needs the live model state that produced the trace. For the current demos, that includes the ART1 category state and the trained backprop network parameters.

The snapshot layer is presently demo-specific rather than fully generic. That is deliberate. It keeps the checkpoint semantics honest while the broader contract for arbitrary user-defined systems is still being designed.

## Reporting

Reporting is built over execution records rather than individual network families.

The current `RunReport` includes:

- accepted count
- attempt count
- average attempts per acceptance
- total runtime
- optional information-theoretic sequence analysis

This keeps reporting portable across domains and architectures.

## Why This Structure

This structure is meant to preserve three properties:

- heterogeneous architectures remain explicit
- execution stays inspectable
- web-facing tools can be built from serialized traces and graph schemas without redefining the system

That is the central architectural commitment of Synaptopus.
