SyQon
SyQon Developer Platform

Astronomical imaging,
programmable.

Run SyQon models from a local pipeline, inspect scientific projects independently, and prepare integrations for the next generation of the Studio ecosystem.

Current surfaces
Neural CLIAvailable
SYQ Core 1Source available
Direct Model APIRoadmap
Plugin SDKRoadmap
01 / Integration surfaces

One engine. Several ways in.

Start with a stable local command-line contract today. Read and write scientific SYQ files independently. Direct model APIs and executable plugins will arrive as versioned, permission-aware surfaces—not undocumented hooks.

Available

Neural CLI

Headless access to the same models, preprocessing, tiling and reconstruction used by Studio.

Source available

SYQ Core

A publicly documented tiled container with checksummed objects, independent readers and Float64 support.

Roadmap

Model API

A future typed API for direct local execution without shell orchestration.

Roadmap

Plugin SDK

Future signed extensions for new processors, panels and graph-replayable operations.

02 / Neural CLI

Studio’s inference engine, without the Studio UI.

The CLI runs locally and uses the same installed runtime assets and device-bound entitlement as SyQon Studio. It never accepts a license override and never sends image pixels to SyQon servers.

First local run

Sign in once through SyQon Studio. Required model assets are installed according to the products available to that account. The CLI then reads the secure operating-system credential store.

No GUI process is started
FITS, XISF, TIFF, PNG, JPEG and camera RAW input
Float32 or Float64 scientific output
Atomic cancellation—no partial result is published
bash
CLI="/Applications/SyQon Studio.app/Contents/MacOS/syqon-cli"

"$CLI" --version
"$CLI" --list-models
"$CLI" --model prism-essential \
  --precision f32 input.fits denoised.fits
Canonical invocationsyqon-cli --model MODEL [OPTIONS] INPUT OUTPUT
Before you write code

The complete integration path

01

Install Studio

The CLI ships with SyQon Studio; it is not a separate model download or cloud endpoint.

02

Authenticate once

The user signs in through Studio. The CLI reads the device token from Keychain or Windows Credential Manager.

03

Install Required Items

Studio downloads only the models available to that account. Do not copy, load or address ONNX files directly.

04

Discover the CLI

Use the registered platform locations, validate with --version, and store the validated path as a fallback.

05

Spawn one process

Pass an argument array with shell execution disabled; capture stdout, stderr and the numeric exit status.

06

Consume the result

On exit 0, stdout is exactly the absolute output path plus a newline. Scientific outputs contain provenance metadata.

Important boundary

A third-party application does not import SyQon weights. It selects a public model identifier such as prism-essential; the licensed local CLI resolves the installed asset, validates access, runs inference and writes the requested file. This keeps credentials and proprietary weights outside your process.

Model registry

Stable CLI identifiers

IdentifierModelInput contractAccess
axiomAxiom V3Linear with Axiom stretch, or non-linearLicensed
prism-essentialPrism EssentialLinear RGB or monoIncluded
prism-advancedPrism Deep AdvancedLinear RGB or monoLicensed
prism-ultraPrism Deep UltraLinear or non-linearLicensed
prism-maxPrism Deep MaxLinear or non-linearLicensed
prism-legacy-v1Prism Legacy V1Legacy display-domain inputLicensed
prism-legacy-v2Prism Legacy V2Robust linear inputLicensed
parallaxParallaxLinear or non-linearLicensed
deep-gradientDeep GradientLinear RGB or monoIncluded
Common option contract
--tile-size 256..2048

Requested processing tile edge; fixed-contract models keep their validated internal size.

--overlap PIXELS

Overlap used by tiled reconstruction.

--application 0..1

Blend the inferred result with the original input.

--domain auto|linear|nonlinear

Read metadata or explicitly declare the input domain.

--precision u16|f32|f64

Select the scientific output sample representation.

--no-debayer

Keep camera RAW CFA samples instead of debayering.

--overwrite

Allow replacing an existing output; never implied.

--quiet

Suppress stderr progress while retaining failures.

--open-in-studio

Open the completed file in Studio after it has been saved.

--return-to / --return-arg

Return the saved result to an external executable or .app without a shell.

02A / Embed the CLI

A process contract your application can own.

Discover and validate the executable once, then invoke it directly with an argument array. The CLI keeps progress on stderr, the final absolute path on stdout and failures in the exit status—so machine output never competes with user-facing logs.

Automatic discovery

Try a previously validated path, SYQON_CLI_PATH, the standard installation and finally a user-selected path. On Windows, production integrations should also query HKCU\\Software\\Microsoft\\Windows\\CurrentVersion\\App Paths\\syqon-cli.exe. Never assume the CLI is in PATH.

macOS system
/Applications/SyQon Studio.app/Contents/MacOS/syqon-cli
macOS user
$HOME/Applications/SyQon Studio.app/Contents/MacOS/syqon-cli
Windows fallback
%LOCALAPPDATA%\Programs\SyQon Studio\syqon-cli.exe
javascript
import { access } from "node:fs/promises";
import { execFile, spawn } from "node:child_process";
import os from "node:os";
import path from "node:path";

function windowsAppPath() {
  return new Promise(resolve => execFile("reg", ["query",
    "HKCU\\Software\\Microsoft\\Windows\\CurrentVersion\\App Paths\\syqon-cli.exe", "/ve"
  ], { windowsHide: true }, (error, stdout) => {
    if (error) return resolve(undefined);
    resolve(stdout.match(/REG_SZ\s+(.+)$/m)?.[1]?.trim());
  }));
}

async function findSyqonCli() {
  const registered = process.platform === "win32" ? await windowsAppPath() : undefined;
  const candidates = process.platform === "darwin"
    ? [
        process.env.SYQON_CLI_PATH,
        "/Applications/SyQon Studio.app/Contents/MacOS/syqon-cli",
        path.join(os.homedir(), "Applications/SyQon Studio.app/Contents/MacOS/syqon-cli")
      ]
    : [
        process.env.SYQON_CLI_PATH,
        registered,
        path.join(process.env.LOCALAPPDATA ?? "", "Programs", "SyQon Studio", "syqon-cli.exe")
      ];

  for (const candidate of candidates.filter(Boolean)) {
    try {
      await access(candidate);
      const code = await new Promise(resolve => {
        spawn(candidate, ["--version"], { shell: false })
          .once("exit", value => resolve(value));
      });
      if (code === 0) return candidate;
    } catch {}
  }
  throw new Error("SyQon CLI was not found. Ask the user to install or locate SyQon Studio.");
}
Copyable integration

Run, monitor and recover

javascript
import { spawn } from "node:child_process";

function runSyqon(cli, input, output, signal) {
  return new Promise((resolve, reject) => {
    const child = spawn(cli, [
      "--model", "prism-ultra", "--domain", "nonlinear",
      input, output
    ], { shell: false, windowsHide: true, signal });
    let stdout = "", stderr = "";
    child.stdout.setEncoding("utf8"); child.stderr.setEncoding("utf8");
    child.stdout.on("data", chunk => stdout += chunk);
    child.stderr.on("data", chunk => {
      stderr += chunk;
      const match = chunk.match(/^(\S+)\s+(\d+)%/m);
      if (match) reportProgress(Number(match[2]));
    });
    child.once("error", reject);
    child.once("close", code => {
      if (code === 0) resolve(stdout.trim()); // absolute saved-output path
      else reject(Object.assign(new Error(stderr.trim()), { exitCode: code }));
    });
  });
}
stdout

Success only

Exit 0 prints the absolute saved-output path followed by one newline. Trim it; do not parse status prose.

stderr

Progress and diagnostics

Progress is emitted as “model 42%”. Preserve other lines verbatim for logs and user diagnostics.

signals

Safe cancellation

Send SIGINT or SIGTERM on macOS/Linux, or terminate the child process on Windows. No partial inferred output is published.

Automation

Predictable shell batches

shell
mkdir -p output
for input in masters/*.fits; do
  name="$(basename "$input" .fits)"
  syqon-cli --model prism-essential \
    --precision f32 \
    "$input" "output/${name}-prism.fits" || exit $?
done
Input / output rules

Accepted input

FITS, XISF, TIFF, PNG, JPEG and supported camera RAW.

Scientific precision

Use --precision u16|f32|f64. FITS, XISF and TIFF can preserve scientific samples.

Existing destination

Protected by default. Supply --overwrite only after your application has confirmed replacement.

Provenance

Scientific outputs include SYQON_CLI_MODEL and SYQON_CLI_VERSION plus engine provenance.

Application handoff

Use --return-to and repeatable --return-arg. {output} is replaced without invoking a command shell.

Failure contract

Every exit code has an application response

0
Success
Consume the absolute path printed to stdout.
1
General CLI error
Show stderr and retain the original input.
2
Invalid option or incompatible domain
Correct arguments or the declared linear/non-linear domain.
3
Input or output path error
Check existence, permissions and overwrite policy.
4
Authentication or entitlement denied
Ask the user to sign in or verify product access in Studio.
5
Inference failed
Report stderr; do not assume an output exists.
6
Output encoding failed
Choose a compatible container/precision or another destination.
7
Output saved; application handoff failed
Keep the saved result; only the optional handoff failed.
130
Interrupted by user
Treat as cancellation, not a processing failure.
03 / Model integration

Select a capability. Never handle a weight file.

Today, third-party workflows integrate through the CLI. This keeps model weights, account credentials and image data inside the user’s machine while preserving a deterministic process contract.

Account-bound

Entitlements come from the signed-in Studio account and a protected device snapshot. Flags cannot unlock a model.

Private by design

Inputs and outputs remain local. Account access, runtime delivery, updates and bounded usage telemetry use SyQon services.

Pipeline-friendly

Explicit inputs, outputs and exit codes make orchestration reproducible in scripts, launchers and desktop integrations.

Model recipes

Production commands by family

Declare the image domain when your container metadata cannot. Prism Essential and Advanced require linear input; Ultra and Max accept linear or non-linear data. Deep Gradient is always linear. Parallax requires at least one enabled stage.

Axiom

--axiom-stretch auto|identity|custom; custom also accepts --axiom-black, --axiom-mid and --axiom-white.

Prism

--application 0..1 blends inference with the original. Essential, Advanced, Ultra and Max retain the validated 512 px model contract.

Parallax

--family aesthetics|classic; correction, reduction and deblur are independent Boolean stages.

Deep Gradient

Its fixed 1920 × 1088 image-and-validity-mask contract is managed internally by the CLI.

shell
# Axiom V3 — starless image plus a separate Stars Only result
syqon-cli --model axiom --axiom-stretch auto \
  --stars-output M51-stars.fits M51.fits M51-starless.fits

# Prism Deep — explicitly process a non-linear XISF at 75% application
syqon-cli --model prism-max --domain nonlinear --application 0.75 \
  input.xisf restored.xisf

# Parallax — classic correction, reduction and deblur stages
syqon-cli --model parallax --family classic --correction true \
  --reduction true --reduction-level 5 \
  --deblur true --deblur-strength 0.45 input.fits parallax.fits

# Deep Gradient — corrected image plus extracted gradient
syqon-cli --model deep-gradient --gradient-output gradient.fits \
  linear-master.fits corrected-master.fits
Parallax stage router

Two families. Six internal variants. One stable CLI model.

Do not invoke Parallax ONNX filenames directly. Use --model parallax; the CLI validates the entitlement and selects the correct internal weight from the family and enabled stage. Stages run in this fixed order: correction, reduction, deblur.

--family aesthetics

Selects the Aesthetics correction, reduction and deblur variants. This is the default family.

--family classic

Selects Classic stellar-defect repair, classic reduction and classic deblur.

--correction true|false

Enables only the family’s stellar correction/repair stage.

--reduction true|false

Enables star reduction; --reduction-level accepts 0–10 and defaults to 5.

--deblur true|false

Enables deconvolution; --deblur-strength accepts 0–1 and defaults to 0.5.

shell
# Aesthetics · Stellar correction only
syqon-cli --model parallax --family aesthetics \
  --correction true --reduction false --deblur false input.fits corrected.fits

# Aesthetics · Star reduction only
syqon-cli --model parallax --family aesthetics \
  --correction false --reduction true --reduction-level 3 \
  --deblur false input.fits reduced.fits

# Aesthetics · Deblur only
syqon-cli --model parallax --family aesthetics \
  --correction false --reduction false \
  --deblur true --deblur-strength 0.65 input.fits deblurred.fits

# Classic · Stellar defect repair only
syqon-cli --model parallax --family classic \
  --correction true --reduction false --deblur false input.fits repaired.fits

# Classic · Star reduction only
syqon-cli --model parallax --family classic \
  --correction false --reduction true --reduction-level 5 \
  --deblur false input.fits reduced-classic.fits

# Classic · Deblur only
syqon-cli --model parallax --family classic \
  --correction false --reduction false \
  --deblur true --deblur-strength 0.5 input.fits deblurred-classic.fits

Aesthetics · correction

family=aesthetics · correction=true

Aesthetics · reduction

family=aesthetics · reduction=true

Aesthetics · deblur

family=aesthetics · deblur=true

Classic · defect repair

family=classic · correction=true

Classic · reduction

family=classic · reduction=true

Classic · deblur

family=classic · deblur=true
Combined pipelines are valid. Leave all three flags at their default true, or enable any combination. At least one stage must remain enabled; otherwise the CLI exits with inference failure and produces no result.
Direct SDK status

There is no public remote inference endpoint or embeddable model SDK yet. Build against the CLI contract today; the future typed API will version tensor contracts, cancellation, progress and capabilities explicitly.

Roadmap
04 / .syq scientific format

The image, its origins and its processing context.

SYQ Core 1 is a publicly documented, versioned, tiled container. A conforming reader can recover the primary image without understanding Studio sessions, neural history or optional extensions—and without SyQon Studio installed.

Development notice

SYQ is evolving quickly during this development phase.

Core 1 is an implementation candidate, not a frozen standard. Structures, APIs and conventions may change as interoperability testing progresses. Pin the exact Core version you implement, validate files defensively and review the release notes before upgrading.

Official source package · Core 1

The specification, reader, writer and test files are available together.

Do not reverse-engineer Studio files from this page. Download the canonical integration kit: it contains the complete C++17 reference library, exact binary specification, independent Python reader, command-line verifier, round-trip tests and four real conformance fixtures covering UInt8, UInt16, Float32 and Float64.

Noncommercial source license. The kit is provided under PolyForm Noncommercial 1.0.0. Noncommercial use, modification and redistribution are allowed under its terms, provided the SyQon copyright and attribution notice remains included. Commercial use or integration requires a separate written license from SyQon.
SHA-256 fb0ff7aa2280b2d4442c44d3f1a1c5fd32024884310ae4d8d4d3227fbef8e244
Download integration kit
Research & observatory licensing

Less restrictive licences may be granted free of charge for research.

SyQon welcomes requests from observatories, universities, scientific institutions and independent research groups. When SYQ supports genuine observational, educational or scientific research, we are available to provide a separate written licence with less restrictive terms at no cost. Describe the project, organisation and intended integration so we can evaluate the appropriate permissions.

Until a separate written grant is issued, the standard PolyForm Noncommercial licence remains in effect.

Request a research licence

Scientific samples

UInt8, UInt16, Float32 and true Float64 image planes with arbitrary documented channel counts.

Verified objects

Per-object SHA-256, bounded decompression and structural validation before tile data is returned.

Durable transactions

Atomic replacement or append transactions with a complete directory and recoverable last commit.

Optional context

Original sources, WCS, ICC, preview, Studio session and a replayable process graph remain separate objects.

Choose an implementation

Three supported reader paths

01

C++17 reference library

Best for native applications. Link the static syq target and use bounded, verified Reader and Writer APIs.

02

Independent Python reader

Best for research scripts and interoperability tests. It uses Python stdlib and the system libzstd—not Qt or Studio.

03

Core 1 wire specification

Best for another language. Implement the exact superblock, footer, directory, CBOR descriptor and tile rules below.

shell
cmake -S SYQ -B syq-build
cmake --build syq-build -j4
ctest --test-dir syq-build --output-on-failure

syq-build/syqtool info image.syq
syq-build/syqtool verify image.syq
syq-build/syqtool extract image.syq 1 object.raw
cmake
# Vendor the complete SYQ/ directory in external/SYQ.
add_subdirectory(external/SYQ)
target_link_libraries(my_astronomy_app PRIVATE syq)

# Requirements: C++17, CMake 3.16+, Qt 6 Core and Zstandard.
# Windows resolves zstd::libzstd; macOS/Linux use pkg-config libzstd.
Zero to first pixel

Prove the toolchain before integrating your application.

Run this sequence unchanged. It builds the same Core library used by Studio, executes its tests, verifies a real edge-tile fixture, decodes the first tile and exports the complete primary image. If these commands pass, your machine has a known-good SYQ reader baseline.

Required

C++17, CMake 3.16+, Qt 6 Core and Zstandard.

macOS

Install Qt 6 and zstd with your package manager; CMake discovers pkg-config libzstd.

Windows

Provide Qt 6 Core and a CMake zstd::libzstd target; use a Visual Studio x64 developer shell.

Linux

Install the Qt 6 Core development package, libzstd development package, CMake and a C++17 compiler.

shell
# 1. Download and unpack the official integration kit.
unzip SYQ-Core-1-Integration-Kit.zip

# 2. Build the reference library and diagnostic tool.
cmake -S SYQ -B syq-build -DCMAKE_BUILD_TYPE=Release
cmake --build syq-build --config Release -j4
ctest --test-dir syq-build -C Release --output-on-failure

# 3. Inspect and fully verify a real conformance fixture.
syq-build/syqtool info SYQ/examples/rgb-32.syq
syq-build/syqtool verify SYQ/examples/rgb-32.syq

# 4. Read tile zero without linking your application yet.
python3 SYQ/tools/read_syq.py SYQ/examples/rgb-32.syq --tile 0

# 5. Export the primary scientific image to Float64 FITS.
python3 SYQ/tools/read_syq.py SYQ/examples/rgb-32.syq --fits primary.fits
IMAGE_DESCRIPTOR payload

This CBOR map is the image contract.

The example is shown as JSON only for readability; on disk it is a CBOR map. Every listed top-level field is required. The descriptor object is uncompressed in the reference writer, while individual tile objects may be independent Zstandard frames.

sample

1 = UInt8, 2 = UInt16, 3 = Float32, 4 = Float64.

tiles

Type 2 object IDs in row-major tile order. IDs are unique and each tile parent must equal the descriptor ID.

role

MAIN_IMAGE, LINEAR_IMAGE, PROCESSING_CHECKPOINT, MASK, VARIANCE_MAP or another explicit producer-defined role.

transfer / state

Describe stored samples. They are not permission to apply an implicit stretch, gamma or colour conversion.

json
{
  "width": 513,
  "height": 259,
  "channels": 3,
  "tile_size": 256,
  "sample": 3,
  "uuid": "550e8400-e29b-41d4-a716-446655440000",
  "role": "MAIN_IMAGE",
  "transfer": "LINEAR",
  "state": "PROCESSED_LINEAR",
  "metadata": {
    "syq.camera.model": "Example Camera",
    "syq.sample.unit": "relative_intensity",
    "vendor.example.pipeline": "1.2.0"
  },
  "tiles": [1, 2, 3, 4, 5, 6]
}
C++ / read

Reconstruct the primary image, tile by tile

Reader::image() selects the footer’s primary image. Tiles are row-major, but samples inside every tile are channel-planar. Edge tiles are smaller than the declared tile size; calculate their actual width and height before copying.

cpp
#include <syq/syq.h>
#include <algorithm>
#include <cstdint>
#include <vector>

syq::Reader reader("M31.syq");
const syq::Image image = reader.image();     // primary image when id is omitted
const uint64_t nx = (image.width  + image.tileSize - 1) / image.tileSize;
const uint64_t ny = (image.height + image.tileSize - 1) / image.tileSize;

// Destination layout in this example: channel-planar Float64.
std::vector<double> pixels(image.width * image.height * image.channels);
for (uint64_t ty = 0; ty < ny; ++ty) {
  for (uint64_t tx = 0; tx < nx; ++tx) {
    const uint64_t tileIndex = ty * nx + tx; // tiles are row-major
    const uint32_t w = std::min<uint64_t>(image.tileSize, image.width  - tx * image.tileSize);
    const uint32_t h = std::min<uint64_t>(image.tileSize, image.height - ty * image.tileSize);
    const auto raw = reader.readTile(image, tileIndex); // verifies SHA-256 and decompresses
    const auto tile = syq::decodeSamples(raw, image.sample);

    for (uint32_t c = 0; c < image.channels; ++c)
      for (uint32_t y = 0; y < h; ++y)
        for (uint32_t x = 0; x < w; ++x) {
          const auto source = (uint64_t(c) * h + y) * w + x;
          const auto target = (uint64_t(c) * image.height + ty * image.tileSize + y)
                            * image.width + tx * image.tileSize + x;
          pixels[target] = tile[source];
        }
  }
}

Integer samples

UInt8 and UInt16 decode to normalized doubles in [0, 1].

Floating samples

Float32 and Float64 retain actual values, including negative, HDR and non-finite values. Never clamp implicitly.

Verification

readTile verifies bounds, decompresses Zstandard when required and validates SHA-256 before returning bytes.

C++ / write

Create atomically. Extend transactionally.

Writer(path) creates through an atomic replacement. Writer(path, true) appends objects and publishes a new directory/footer commit. If an append is interrupted, readers recover the most recent valid commit and ignore orphan bytes.

cpp
syq::Image image;
image.width = width; image.height = height; image.channels = channels;
image.tileSize = 256;
image.sample = syq::Sample::Float32;
image.role = "MAIN_IMAGE";
image.transfer = "LINEAR";
image.state = "PROCESSED_LINEAR";
image.metadata.insert(QStringLiteral("syq.camera.model"), QStringLiteral("Example Camera"));

syq::Writer writer("result.syq");           // atomic replacement
const auto primary = writer.addImage(image,
  [&](uint64_t x0, uint64_t y0, uint32_t w, uint32_t h) {
    std::vector<double> tile(uint64_t(w) * h * channels);
    // sourcePixels and each tile are channel-planar: [all R][all G][all B].
    for (uint32_t c = 0; c < channels; ++c)
      for (uint32_t y = 0; y < h; ++y)
        for (uint32_t x = 0; x < w; ++x)
          tile[(uint64_t(c) * h + y) * w + x] =
            sourcePixels[(uint64_t(c) * height + y0 + y) * width + x0 + x];
    return syq::encodeSamples(tile, image.sample);
  });
writer.commit(primary);                      // publishes directory + recovery footer

// Append metadata without rewriting the image payload.
syq::Reader existing("result.syq");
syq::Writer transaction("result.syq", true);
QCborMap note{{QStringLiteral("vendor.example.reviewed"), true}};
transaction.add(syq::Type::Metadata, QCborValue(note).toCbor());
transaction.commit(existing.primaryId());

Python inspection and import

python
# The independent reference reader needs only Python 3 and system libzstd.
python3 SYQ/tools/read_syq.py image.syq --tile 0
python3 SYQ/tools/read_syq.py image.syq --fits primary.fits

# Import it from a vendored SYQ/tools directory.
import sys
sys.path.insert(0, "vendor/SYQ/tools")
from read_syq import Reader

reader = Reader("image.syq")
image = reader.image
x, y, width, height, first_tile = reader.tile(0)
print(image["width"], image["height"], image["channels"])
print(x, y, width, height, len(first_tile))
Reader algorithm from zero
  1. 01Read the 128-byte superblock. Require magic 89 53 59 51 0D 0A 1A 0A, Core major 1, supported required features and the header digest.
  2. 02Read the final 80 bytes. Require ASCII SYQEND01, validate its checksum, committed file size and SHA-256 of the active directory.
  3. 03Parse the directory: an 8-byte entry count followed by fixed 96-byte entries. Reject overlaps, overflow, invalid ordering and unsupported required objects.
  4. 04Resolve primary_id to a Type 1 Image object. Decompress if codec is 1 (Zstandard), enforce the logical-size budget, verify SHA-256, then decode definite-length CBOR.
  5. 05Validate width, height, channels, tile_size, sample and the unique tile ID list. Expected tile count is ceil(width/tile_size) × ceil(height/tile_size).
  6. 06For each Type 2 Tile, require parent == primary image ID, validate edge dimensions, decode little-endian channel-planar samples and place them at their row-major tile coordinates.
  7. 07Ignore unknown optional objects. Reject unknown objects marked required. Never execute ProcessGraph data merely because it appears in a file.
Failure contract

Reject corruption explicitly.

A successful open means the container structure and primary descriptor are coherent. A successful tile read additionally means that tile stayed inside the committed file, decompressed to the declared logical length and matched its SHA-256. Importers must surface the failure; they must never silently invent black pixels.

Security boundary: PROCESS_GRAPH and Studio session objects are data. A reader never executes them. Hashes detect accidental corruption, not a malicious publisher; Core 1 does not define signatures or encryption.
cpp
try {
  syq::Reader reader(path);
  const auto image = reader.image();

  // Opening validates the header, active footer, directory geometry,
  // required features, primary descriptor and tile relationships.
  for (uint64_t i = 0; i < image.tiles.size(); ++i) {
    // Reading validates bounds, Zstandard output length and SHA-256.
    const QByteArray raw = reader.readTile(image, i);
    const std::vector<double> samples = syq::decodeSamples(raw, image.sample);
    consumeVerifiedTile(i, samples);
  }
} catch (const syq::Error& error) {
  // The file is unsupported, incomplete or corrupt. Do not substitute zeros
  // and do not report a successful scientific import.
  reportImportFailure(error.what());
}
Core 1 wire map

Fixed structures and byte order

All fixed-structure integers and IEEE image samples are unsigned little-endian. CBOR uses its own encoding rules. Serialize every field explicitly; never dump a language struct with compiler padding.

128-byte superblock

0..7 magic8..9 major = 110..11 minor = 012..15 header size = 12816..23 required features32..55 initial directory geometry + primary ID56..71 file UUID72..79 creation Unix ns96..127 SHA-256 of bytes 0..95

96-byte directory entry

0..7 object ID8..15 parent ID16..23 type + flags24..47 offset + stored/logical lengths48..55 codec + checksum algorithm56..87 uncompressed SHA-25688..95 reserved

80-byte commit footer

0..7 ASCII SYQEND018..31 directory offset/length + primary ID32..39 committed file size40..71 directory SHA-25672..79 first 8 bytes of footer SHA-256
Core object registry

What a reader must understand

TypeObjectReader requirement
1Image descriptorCore: CBOR geometry, sample type, transfer/state, metadata and ordered tile IDs.
2TileCore: little-endian, channel-planar samples; codec None or Zstandard.
3MetadataOptional namespaced CBOR metadata.
4–7Session, ProcessGraph, OriginalSource, PreviewOptional. Preserve or ignore; never execute untrusted graph content.
8–9WCS, ICCOptional astrometric and colour-management payloads.
>= 65536Vendor extensionVendor-defined. Ignore unless understood and not marked required.
Metadata conventions

Namespaced, explicit, never guessed

Use syq.camera.*, syq.acquisition.*, syq.optics.*, syq.filter.*, syq.astrometry.*, syq.photometry.* and syq.processing.*. Private keys belong under vendor.<organization>.*. Leave unknown units, colour primaries or CFA layout unknown—do not infer them from an RGB-looking array.

Ship checklist
Test mono, RGB, edge tiles and every supported sample type.
Reject overflow, overlap, duplicate IDs, impossible dimensions and excessive decompression before allocation.
Preserve unknown optional objects when your workflow promises round-trip fidelity.
Expose corrupt tile IDs; never silently replace missing scientific data with zeros.
Run syqtool verify and the independent Python reader in CI against generated fixtures.
Source available

Core 1 implementation candidate

The format and independent readers are tested, but Core 1 has not yet completed third-party security auditing, exhaustive fuzzing or extreme-scale stress testing. Numeric limits are deliberate: 64 MiB per object, 128 MiB directory, CBOR depth 32, up to 2 million CBOR items, 1024 channels, 1024 px tile edge and 1 million tiles. Check all arithmetic and allocation budgets before reading payloads.

Core hashes detect accidental damage; they are not signatures and do not prove publisher identity. Core 1 does not encrypt content. The suggested MIME type is application/x-syq and is not currently an IANA registration.

Developer updates

Follow the interfaces while they become stable.

Join the dedicated developer mailing list for CLI changes, SYQ revisions, interoperability fixtures, API previews and the future plugin SDK. This audience is kept separate from general product marketing.

Developer-only news. Unsubscribe at any time. Read our Privacy Policy.

06 / Plugin architecture

A controlled extension layer, prepared for what comes next.

Plugins are not publicly loadable today. The future SDK is being framed around explicit capabilities, signed packages and replayable processing—not unrestricted access to Studio internals.

01

Versioned manifest

Identity, compatible Studio range, entry points and declared capabilities before loading.

02

Permission boundary

File access, network use, model invocation and document mutation exposed only when declared and approved.

03

Graph-native processing

Image operations designed to publish deterministic parameters and participate in SYQ replay.

04

Native and local

Processing remains on the workstation, with resource budgets, cancellation and progress supplied by the host.

05

Signed distribution

Integrity and publisher identity considered part of the package contract, not an optional convention.

06

Stable UI surfaces

Future panels and inspectors mount into documented regions instead of patching private widgets.

Early ecosystem

Design an integration with us.

If you are building an astronomy application, observatory workflow or scientific reader, tell us which contract you need. Early feedback will shape the direct API and plugin SDK.

Contact SyQon