# Formats

## Purpose

Synaptopus uses JSON-facing artifact types as the bridge to future browser and TypeScript tooling:

- artifact manifest
- graph schema
- execution trace
- run report
- demo snapshot

These are generated today by the internal demo exporter. The examples below reflect the current output shapes rather than speculative formats.

All exported artifacts are wrapped in a versioned envelope with this top-level shape:

- `artifact_type`
- `schema_version`
- `payload`
- `metadata`

Example:

```json
{
  "artifact_type": "graph_schema",
  "schema_version": "1.0",
  "payload": {
    "nodes": [],
    "edges": []
  },
  "metadata": {}
}
```

## Artifact Manifest

The manifest is the directory-level index for a set of exported artifacts.

Top-level fields:

- `schema_version`
- `artifacts`
- `metadata`

Each artifact entry has:

- `artifact_type`
- `file_name`

Example:

```json
{
  "schema_version": "1.0",
  "artifacts": [
    { "artifact_type": "graph_schema", "file_name": "graph.json" },
    { "artifact_type": "execution_trace", "file_name": "trace.json" },
    { "artifact_type": "run_report", "file_name": "report.json" },
    { "artifact_type": "demo_snapshot", "file_name": "snapshot.json" }
  ],
  "metadata": {
    "example": "parity_pressure",
    "snapshot_after_accepted": 2
  }
}
```

## Graph Schema

The graph schema describes node roles and wiring. It does not encode full runtime behavior by itself.

Top-level fields:

- `nodes`
- `edges`

Each node has:

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

Each edge has:

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

Example:

```json
{
  "artifact_type": "graph_schema",
  "schema_version": "1.0",
  "payload": {
    "nodes": [
      {
        "node_id": "generator",
        "node_type": "generator",
        "input_names": ["state"],
        "output_names": ["candidate"]
      },
      {
        "node_id": "policy",
        "node_type": "policy",
        "input_names": ["state", "candidate", "critique", "category"],
        "output_names": ["decision", "accepted"]
      }
    ],
    "edges": [
      {
        "source_node_id": "generator",
        "source_output": "candidate",
        "target_node_id": "critic",
        "target_input": "candidate"
      }
    ]
  },
  "metadata": {}
}
```

## Execution Trace

The execution trace captures the real runtime behavior of a system under the generic accept/reject loop.

Top-level fields:

- `accepted`
- `attempts`
- `final_state`
- `total_seconds`

Each step trace contains:

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

The metadata payload is intentionally architecture- and example-specific, but it must still be JSON-safe. For the XOR novelty demo it contains:

- `critique`
- `category`
- `decision`

Example excerpt:

```json
{
  "artifact_type": "execution_trace",
  "schema_version": "1.0",
  "payload": {
    "accepted": [
      {
        "candidate": [0, 1],
        "accepted": true,
        "metadata": {
          "critique": {
            "outputs": [0.9850980332426884],
            "loss": 0.0
          },
          "category": {
            "winner": 0,
            "matched": true,
            "new_category": false,
            "delta_vigilance": false
          },
          "decision": {
            "accepted": true,
            "label": "accept"
          }
        }
      }
    ]
  },
  "metadata": {}
}
```

## Generic And Example-Specific Trace Fields

The execution trace has two layers:

- generic runtime fields, which should remain stable across examples
- `metadata`, which may vary by example or architecture family

Generic fields:

- `previous_state`
- `next_state`
- `candidate`
- `accepted`
- `elapsed_seconds`

Example-specific metadata should stay JSON-safe and should be interpreted by consumers only when they know the example or system family.

## Run Report

The run report is a compact summary artifact for comparison, dashboarding, and experiment logging.

Top-level fields inside `payload`:

- `parameters`
- `accepted_count`
- `attempt_count`
- `total_seconds`
- `sequence_analysis`
- `average_attempts_per_accept`

Example:

```json
{
  "artifact_type": "run_report",
  "schema_version": "1.0",
  "payload": {
    "parameters": {
      "example": "xor_novelty",
      "accepted_count": 2,
      "max_attempts_per_accept": 4
    },
    "accepted_count": 2,
    "attempt_count": 3,
    "total_seconds": 0.00019715959206223488,
    "sequence_analysis": {
      "item_count": 2,
      "alphabet_size": 4,
      "unigram_entropy_bits": 1.0,
      "conditional_entropy_bits": 0.0,
      "normalized_entropy": 0.5,
      "predictability": 1.0,
      "redundancy": 0.5
    }
    },
    "average_attempts_per_accept": 1.5
  },
  "metadata": {}
}
```

The `sequence_analysis` object is optional. When present, it currently contains:

- `item_count`
- `alphabet_size`
- `unigram_entropy_bits`
- `conditional_entropy_bits`
- `normalized_entropy`
- `predictability`
- `redundancy`

## Demo Snapshot

The demo snapshot artifact is the first checkpoint/resume format in Synaptopus. It is currently scoped to the internal demos rather than arbitrary user-defined systems.

Top-level fields inside `payload`:

- `demo_name`
- `system`
- `record`
- `parameters`

The `system` object stores the mutable model internals needed to resume execution, such as ART1 categories and backpropagation weights. The `record` object stores the accumulated execution history up to the checkpoint.

Example:

```json
{
  "artifact_type": "demo_snapshot",
  "schema_version": "1.0",
  "payload": {
    "demo_name": "parity_pressure",
    "system": {
      "critic_network": {},
      "categorizer_network": {},
      "acceptance_threshold": 0.8
    },
    "record": {
      "accepted": [],
      "attempts": [],
      "final_state": {
        "accepted": [[0, 0, 1], [1, 0, 0]],
        "attempts": 5
      },
      "total_seconds": 0.0005
    },
    "parameters": {
      "accepted_count": 2,
      "max_attempts_per_accept": 12
    }
  },
  "metadata": {
    "demo_name": "parity_pressure"
  }
}
```

## Versioning

The current artifact schema version is:

- `1.0`

Any future breaking change to the envelope, manifest, or payload structures should increment the schema version rather than silently changing field meaning.

## Format Constraints

These constraints should remain stable:

- artifacts must be JSON-safe without Python-specific types
- exported files should be versioned via envelopes
- artifact sets should include a manifest
- tuples must serialize as arrays
- dataclass-like records must serialize as plain objects
- graph schemas must remain declarative
- traces must reflect actual runtime attempts and acceptances
- reports should stay compact and comparison-friendly

## Intended TypeScript Mapping

The natural future TypeScript split is:

- manifest interfaces
- artifact envelope interfaces
- graph schema interfaces
- trace interfaces
- report interfaces

Those should be derived directly from the current artifact contracts rather than reinterpreted independently in the frontend.
