-
From a stable Mission Data Contract to an engineering ecosystem
3 hours ago • 0 commentsWhen I published OrbitFabric v1.0.0, the main goal was to close one important question first:
Can a small spacecraft Mission Data Contract become stable enough that tools, generated artifacts and engineering workflows can depend on it without continuously changing the underlying semantics?
At that point the answer was finally yes.
Version 1.0 established a stable Mission Data Contract covering spacecraft structure, modes, telemetry, commands, events, faults, payload behavior, data products, storage and downlink intent, commandability, autonomy and recovery.
It also established deterministic validation, scenario evidence, generated documentation, runtime facing bindings and ground facing artifacts.
That was a useful milestone, but it exposed a second problem almost immediately.
Once other tools start consuming the Mission Data Contract, how do they consume it without becoming independent Mission Model interpreters?
This question shaped most of the work from v1.0 to v1.2.
The problem after v1.0
A YAML Mission Model is convenient for authorship and review.
It is not automatically the right integration boundary for every downstream tool.
If every consumer directly parses the source YAML, several problems appear.
- Each consumer can implement a slightly different interpretation of the same field.
- Derived relationships may be reconstructed differently.
- Optional domains may be handled inconsistently.
- Validation state can be separated from the exact model that was validated.
- A consumer can silently continue after a partial or incompatible parse.
- Over time, a second semantic authority can emerge outside Core.
That last point is the one I care about most.
The architectural rule is now explicit:
The Mission Model is the semantic source of truth. OrbitFabric Core owns Mission Data Contract interpretation. Downstream tools consume explicit Core owned facts. They do not reconstruct OrbitFabric semantics independently.This sounds simple, but it has strong consequences for the architecture.
Structured surfaces instead of private interpretation
The first step was to expose more of Core's interpretation through structured machine readable surfaces.
Different consumers need different views of the same Mission Data Contract, so a single generic JSON dump is not enough.
OrbitFabric now exposes several distinct Core owned surfaces.
model_summary.json What contract domains are present? entity_index.json What entities exist and how can they be addressed? relationship_manifest.json Which explicit admitted relationships connect those entities? mission_snapshot.json What complete Mission Model did Core actually load?These are deliberately different products.
An entity index is excellent for navigation, but it is not a complete semantic representation.
A relationship manifest is useful for graph based tools, but it must expose only relationships that Core actually owns.
A complete Mission Snapshot is useful when a consumer needs the full interpreted model, but it should not replace the smaller surfaces when a smaller contract is sufficient.
The objective is not to produce as much JSON as possible.
The objective is to make Core ownership explicit.
Why explicit relationships matter
This became particularly important for fault detection, isolation and recovery.
A tool looking at a telemetry limit, a fault definition and a recovery command can often guess that the three are related.
But guessing is exactly what I want downstream tools to avoid.
OrbitFabric v1.2 therefore added explicit FDIR related relationship families to the stable Relationship Manifest.
Examples include relationships such as:
- a fault observing a telemetry item
- a recovery intent dispatching a command
- a recovery intent targeting a mode
- an autonomous action being triggered by a fault
The rule is strict:
If Core does not expose the relationship, the consumer must not invent it.This is especially important for visual tools.
A graph can make inferred information look authoritative very quickly.
Once a relationship appears as an edge on screen, it becomes difficult for a user to remember whether that edge came from the Mission Data Contract, from a heuristic, or from a UI convenience.
Keeping that distinction explicit is more important than producing a visually richer graph.
v1.1: candidate inspection surfaces
Version 1.1 introduced another layer of structured outputs.
These surfaces are useful, implemented and machine readable, but they remain candidate rather than stable Core contracts.
They include:
dashboard_summary.jsonscenario_run_index.jsoncoverage_summary.json- structured scenario expectation accounting
This distinction between stable and candidate surfaces is intentional.
Once another project depends on a machine readable contract, changing that contract is no longer only an internal refactoring decision.
Compatibility becomes an architectural concern.
So OrbitFabric now distinguishes between:
stable Mission Data Contract semantics stable Core owned machine readable surfaces candidate Core inspection surfaces candidate external integration contracts generated public preview artifactsI prefer this mixed maturity model to pretending that every part of the project has the same stability simply because it ships in the same repository.
The missing piece: coherence
Even with good structured surfaces, another problem remained.
Suppose an external integration receives:
- a Mission Snapshot
- an Entity Index
- a Relationship Manifest
- a lint report
- a model summary
How does it know that all of those files describe the same logical Core interpretation?
File timestamps are not enough.
Directory proximity is not enough.
Running five export commands independently is not enough.
This led to the main integration change in OrbitFabric v1.2.
The Core Integration Input Set
Core can now produce one coherent Integration Input Set from one logical load and lint operation.
The current set contains:
integration_input_manifest.json mission_snapshot.json entity_index.json relationship_manifest.json lint_report.json model_summary.jsonThe important part is not only the files.
The important part is that Core produces them as one coherent unit.
The manifest records information including:
- required and companion roles
- surface kind and version
- availability
- load state
- lint state
- SHA 256 digests
- a deterministic fingerprint of the complete input set
The complete set is fingerprinted using canonical JSON serialization.
The manifest is written last.
This gives an external integration a simple rule:
Either consume one coherent Core Integration Input Set, or stop.If a required surface is incompatible, the integration must reject the input.
It must not fall back to reparsing the Mission Model YAML and continue with its own interpretation.
That fallback would defeat the entire semantic ownership boundary.
Why the manifest is written last
This may sound like a small implementation detail, but it is part of the contract.
If the manifest appeared before all required surfaces were successfully written, another process could observe what looks like a complete Integration Input Set while some artifacts are still missing or incomplete.
Publishing the manifest last turns it into the completion marker for the set.
The manifest therefore represents not only metadata, but also the publication boundary of one coherent Core output.
From files to an integration architecture
Once the Core input boundary became explicit, the next architectural layers became much easier to separate.
![]()
OrbitFabric Integration Architecture. Core owns Mission Data Contract semantics and produces one coherent integration input boundary. Target specific projection, adapter execution and Integration Result ownership remain outside Core.
The ownership model is:OrbitFabric Core owns Mission Data Contract semantics and coherent integration inputs Projection Profile owns authored target specific projection intent Integration Adapter owns target validation, projection and artifact generation Integration Result owns explicit mappings, artifacts, diagnostics, coverage and provenance Downstream consumer presents, navigates or orchestrates those explicit recordsThe important consequence is that target specific semantics stay outside Core.
Core does not need to know how a particular flight software framework, validation environment or ground system represents telemetry, commands or events.
The adapter understands the target.
The Projection Profile expresses the authored mapping intent.
The Integration Result records what actually happened.
Core remains responsible for OrbitFabric semantics.
Why this matters for Studio
One of the strongest forcing functions for these boundaries has been OrbitFabric Studio.
A visual workbench makes semantic ambiguity visible very quickly.
If Studio directly parses YAML, derives relationships privately or calculates its own hidden interpretation, then the project has two semantic authorities.
That is exactly what I want to avoid.
Studio therefore consumes Core owned surfaces such as the Mission Snapshot, Entity Index, Relationship Manifest and lint output.
The same architectural rule applies:
Core owns the fact. Studio makes the fact understandable.I will describe Studio itself in a separate project log because the visual architecture, relationship exploration and operational views deserve their own discussion.
The role of the Reference Mission
Another forcing function has been the OrbitFabric Reference Mission.
Small isolated examples are useful during implementation, but they are not enough to test whether an architecture remains coherent across multiple domains.
The Reference Mission combines spacecraft topology, operational modes, EPS, ADCS, communications, payload behavior, telemetry, commands, events, faults, data products, storage, contacts, downlink intent, commandability and recovery.
It also provides deterministic scenarios that exercise those relationships together.
This has been useful for identifying where a surface is merely convenient and where it actually needs to become an architectural contract.
I will also dedicate a separate log to that mission and to the way the same declared facts move from Mission Model to Core evidence and then into Studio.
What changed between v1.0 and v1.2?
The biggest change is not the number of YAML fields or CLI commands.
The main change is the boundary around semantic interpretation.
At v1.0 the central question was:
Can the Mission Data Contract itself become stable?
At v1.2 the question has become:
Can other tools depend on OrbitFabric without becoming independent interpreters of the Mission Data Contract?
The current answer is based on four rules.
- The Mission Model remains the semantic source of truth.
- Core remains the single semantic authority.
- Downstream consumers receive explicit Core owned facts through controlled surfaces.
- External integrations consume one coherent fingerprinted input set rather than reconstructing mission meaning from raw source files.
This architecture is now being exercised against real external software boundaries.
That work is already influencing the Integration Framework, but I do not want to collapse it into this log.
The next logs will cover the pieces individually:
- how OrbitFabric Studio visualizes a mission without becoming another Mission Model interpreter
- why a realistic Reference Mission became necessary
- how the generic Integration Framework separates Core semantics from target specific projection
- and finally, how a real spacecraft flight software and validation ecosystem is being used to pressure test those boundaries
The project has therefore moved beyond the original question of whether a lightweight Mission Data Contract is useful.
The more interesting question now is whether that contract can remain semantically coherent while several independent engineering tools start depending on it.
That is the problem I am trying to solve next.
OrbitFabric Core:
https://github.com/FAROTECH/orbitfabricOrbitFabric Studio:
https://github.com/FAROTECH/orbitfabric-studioOrbitFabric Reference Mission:
https://github.com/FAROTECH/orbitfabric-reference-mission -
v1.0.0 - Stable Mission Data Contract
05/20/2026 at 16:33 • 0 commentsOrbitFabric v1.0.0 is the first stable Mission Data Contract release.
This is not another vertical slice.
It is a boundary release.
The previous public logs followed the growth of OrbitFabric through specific contract layers:
payload contracts,
data products,
storage intent,
contact and downlink assumptions,
commandability and autonomy contracts,
end-to-end data-flow evidence,
and generated runtime-facing contract bindings.After that path, v1.0.0 stabilizes the deliberately narrow Core surface that those slices were building toward.
![]()
OrbitFabric v1.0.0 stabilizes the Core contract boundary: Mission Model in, Core-owned structured surfaces and reproducible artifacts out.
The important point is not that OrbitFabric is now complete.
It is not.
The important point is that the Core contract boundary is now explicit.
What v1.0.0 stabilizes
OrbitFabric v1.0.0 stabilizes a narrow Core surface around:
- Mission Model documented contract semantics
- structural validation
- semantic linting
- lint diagnostic policy
- scenario YAML evidence inputs
- lint JSON reports
- simulation JSON reports
- Core-owned structured surfaces
- documented CLI workflows
- release compatibility policy
- extensibility boundary contract
This is the v1.0.0 statement:
Define the contract once.
Validate it.
Exercise scenario evidence.
Generate review artifacts.
Export Core-owned structured surfaces.
Protect selected stable surface fields with golden signatures.
Keep the Mission Model as the source of truth.That is the stable boundary.
Not flight software.
Not a ground segment.
Not a mission control system.
A Mission Data Contract framework.
Core-owned structured surfaces
One of the most important v1.0.0 decisions is that downstream tools should not reconstruct OrbitFabric semantics from raw YAML, generated Markdown, terminal output, logs, UI state or private assumptions.
They should consume Core-owned structured surfaces.
The stable structured surface chain is:
model_summary.json -> What contract domains are present? entity_index.json -> What contract entities are defined? relationship_manifest.json -> How are indexed contract entities related?
These surfaces are derived from the validated Mission Model.
They are not a second source of truth.
They are read-only Core-owned views over the source of truth.
That distinction matters for future tools.
A visual workbench, inspection layer, generated artifact pipeline or future extension should not need to reimplement OrbitFabric Core semantics.
It should consume the structured surfaces produced by Core.
Golden signatures
v1.0.0 also introduces golden signature protection for selected contract-significant fields of the demo-3u Core-owned structured surfaces.
The protected signatures cover selected fields such as:
- surface kind
- surface version
- mission identity
- boundary flags
- domain counts
- entity identifiers
- relationship family counts
- selected relationship records
This does not freeze everything.
The golden signatures do not freeze:
- full generated JSON files
- absolute paths
- human-oriented terminal output
- Markdown wording
- generated runtime bindings
- generated ground dictionaries
- disposable artifact formatting
That is intentional.
The goal is to protect contract-significant behavior without pretending that every generated file byte is part of the stable API.
The v1.0 demo evidence chain
The selected v1.0 demonstration chain proves Mission Data Contract continuity across the main public surfaces.
The chain is:
payload.start_acquisition -> payload.acquisition_started -> payload.radiation_histogram data product evidence -> storage intent declared -> downlink intent declared -> science_next_available_contact downlink flow -> demo_contact_001 contact window -> scenario JSON evidence -> runtime-facing contract bindings -> ground-facing dictionaries -> model_summary.json -> entity_index.json -> relationship_manifest.json -> golden signatures protecting selected Core-owned surface fields
This is the right kind of evidence for OrbitFabric v1.0.0.
It proves continuity from one validated Mission Model across scenario evidence, generated review artifacts and Core-owned structured surfaces.
It does not prove flight readiness.
It does not prove ground readiness.
It does not prove protocol compliance.
It does not prove tool-specific integration.
It does not prove operational completeness.
What remains intentionally outside v1.0.0
OrbitFabric v1.0.0 does not introduce:
- flight runtime behavior
- ground runtime behavior
- mission control behavior
- telemetry archive
- command uplink service
- hardware abstraction layer
- RTOS integration
- binary telemetry decoder
- binary telecommand encoder
- CCSDS/PUS/CFDP implementation
- XTCE export
- Yamcs integration
- OpenC3 integration
- F Prime mapping
- cFS mapping
- relationship graph engine
- dependency graph engine
- plugin discovery
- plugin loading
- plugin execution
- schema migration tooling
- security enforcement semantics
- Studio-specific API
Those are not missing pieces of v1.0.0.
They are outside the stable Core boundary.
Why this matters
A v1.0 release can be misunderstood as a claim of operational readiness.
That is not the case here.
OrbitFabric v1.0.0 is a stable Mission Data Contract baseline.
It says:
this is the source of truth boundary,
these are the Core-owned structured surfaces,
this is how scenario evidence connects to generated artifacts,
this is what downstream tools should consume,
this is what golden signatures protect,
and this is what remains explicitly out of scope.That is valuable precisely because the boundary is narrow.
A small spacecraft tooling project becomes more useful when its limits are clear.
v1.0.0 is therefore not a claim that OrbitFabric is a flight stack.
It is the point where OrbitFabric Core becomes stable enough to build around without blurring the line between contract, evidence, generated artifacts and real runtime systems.
The next work can build from that baseline.
But the v1.0.0 rule remains:
Mission Model remains the source of truth.
Core owns Mission Data Contract semantics.
Core-owned structured surfaces are derived from the validated Mission Model.
Downstream tools consume those surfaces.
Generated runtime-facing and ground-facing artifacts remain reproducible and disposable unless explicitly classified otherwise.
Plugin execution remains out of scope.Feedback is welcome from people who have worked with mission data models, telemetry dictionaries, command dictionaries, generated artifacts, scenario evidence, ground-facing exports, model-to-code workflows or tool integration boundaries and have seen contract drift appear between documents, code, tests and operational assumptions.
-
v0.7.0 — Generated Runtime Skeletons
05/09/2026 at 15:19 • 0 commentsOrbitFabric v0.7.0 introduces the first generated runtime-facing contract binding layer.
This is a significant step, but the boundary is important.
Generated Runtime Skeletons are not flight software.
They are not an onboard runtime, not a scheduler, not a HAL, not a command dispatcher and not a command queue.
They are contract-facing software artifacts derived from the validated Mission Model.
Why this release matters
Previous OrbitFabric releases focused on making the mission data chain explicit.
The project could already describe telemetry, commands, events, faults, payload contracts, data products, storage intent, downlink intent, contact windows, commandability assumptions and end-to-end data-flow evidence.
v0.7.0 is the first release where that contract becomes directly visible to implementation code.
The chain now becomes:
Mission Model -> validation and linting -> RuntimeContract -> generated C++17 contract bindings -> host-build smoke validation -> user implementation outside generated/
This is the key shift.
OrbitFabric is no longer only producing documentation, reports and deterministic scenario evidence.
It can now generate a software-facing boundary that implementation code may include, compile and implement against.
RuntimeContract
v0.7.0 introduces RuntimeContract.
RuntimeContract is an intermediate model representing the software-facing subset of the validated Mission Model.
It is the bridge between the declarative mission contract and generated runtime-facing files.
The generation flow is:
Mission Model -> structural and semantic validation -> engineering linting -> RuntimeContract construction -> profile-specific generator -> generated runtime-facing artifacts
The current generation profile is:
cpp17
This is deliberately narrow.
The goal is not to generate onboard behavior.
The goal is to expose the validated contract surface in a deterministic software-facing form.
The new generator command
The new command is:
orbitfabric gen runtime examples/demo-3u/mission/
orbitfabric gen runtime examples/demo-3u/mission/The default generated output is:
generated/runtime/cpp17/
The generated C++17 profile currently emits:
generated/runtime/cpp17/runtime_contract_manifest.json generated/runtime/cpp17/CMakeLists.txt generated/runtime/cpp17/include/orbitfabric/generated/mission_ids.hpp generated/runtime/cpp17/include/orbitfabric/generated/mission_enums.hpp generated/runtime/cpp17/include/orbitfabric/generated/mission_registries.hpp generated/runtime/cpp17/include/orbitfabric/generated/command_args.hpp generated/runtime/cpp17/include/orbitfabric/generated/adapter_interfaces.hpp generated/runtime/cpp17/src/orbitfabric_runtime_contract_smoke.cpp
These are generated artifacts.
They are reproducible and disposable.
User implementation code must live outside generated/.
What the generated bindings expose
The generated runtime-facing contract bindings expose several kinds of information.
Identifier headers provide deterministic strongly typed identifiers for model elements such as:
ModeId TelemetryId CommandId EventId FaultId PacketId PayloadId DataProductId StoragePolicyId DownlinkPolicyId
Static registries expose contract metadata such as model IDs, symbol names, value types, units, command targets, event severities, fault metadata and data product attributes.
Command argument structs expose the declared shape of command arguments.
For example:
struct PayloadStartAcquisitionArgs { std::uint16_t duration_s; };This struct defines the contract-facing command argument shape.
It does not parse packets.
It does not validate permissions.
It does not enqueue commands.
It does not execute the command.
Adapter interfaces
v0.7.0 also generates abstract adapter interfaces.
Examples include:
ICommandHandler ITelemetrySink IEventReporter IFaultReporter
These interfaces are integration boundaries only.
They are not concrete services.
They do not implement command dispatch.
They do not poll telemetry.
They do not route events.
They do not manage faults.
They define where user implementation code can attach to the generated contract surface.
That distinction is important.
OrbitFabric generates the contract-facing boundary.
The user still owns the implementation.
Host-build smoke validation
The generated C++17 surface can be validated on the host with CMake:
cmake -S generated/runtime/cpp17 -B generated/runtime/cpp17/build cmake --build generated/runtime/cpp17/buildThis checks that the generated headers and smoke source are syntactically valid and buildable as C++17.
It does not validate flight behavior.
It does not prove onboard readiness.
It only validates the generated contract-binding surface.
What this release intentionally does not do
v0.7.0 intentionally does not introduce:
- flight runtime
- onboard application framework
- runtime loop
- command dispatch runtime
- command queue
- command validation runtime
- telemetry polling runtime
- event routing runtime
- fault manager runtime
- scheduler
- HAL
- drivers
- RTOS abstraction
- Linux daemon
- binary serialization
- CCSDS/PUS/CFDP mapping
- storage runtime
- downlink runtime
- user-code merge
- protected regions
- flight-ready software
Those are not missing pieces of v0.7.0.
They are outside the generated runtime skeleton boundary.
Security boundary
A final architectural review was performed before publishing v0.7.0.
The decision was not to add security hooks to this release.
OrbitFabric already exposes command risk as contract metadata, but it does not yet model security assumptions, command criticality contracts, data classification, trust boundary metadata, audit requirements or replay/integrity/confidentiality assumptions.
Those should be explored separately.
Adding vague security placeholders now would make the contract weaker, not stronger.
Why this matters before v0.8
v0.7.0 is the correct step before Ground Integration Artifacts.
Ground-facing exports should not be generated from isolated YAML fragments.
They should be generated from a validated Mission Data Contract that already has:
declared mission data,
validated references,
scenario evidence,
data-flow evidence,
runtime-facing identifiers,
typed command argument shapes,
metadata registries,
and implementation-facing adapter boundaries.That is what v0.7.0 adds.
It does not turn OrbitFabric into flight software.
It makes the Mission Model consumable by software without pretending to own the runtime.
The architectural rule remains:
generated code is disposable; user code lives outside generated/; integration happens through interfaces.
Feedback is welcome from people who have worked with generated headers, telemetry dictionaries, command interfaces, flight software integration boundaries, ground interface control documents or model-to-code workflows and have seen contract drift appear between documentation, tests and implementation code.
-
v0.6.0 — End-to-end mission data flow evidence
05/08/2026 at 21:32 • 0 commentsOrbitFabric v0.6.0 adds the first end-to-end Mission Data Flow Evidence slice.
The previous logs walked through the individual contract layers:
payload contracts,
data products,
storage intent,
downlink intent,
contact windows,
downlink flows,
commandability rules,
and autonomy assumptions.v0.6.0 connects those layers into one inspectable evidence chain.
It does not make OrbitFabric a runtime.
It makes the declared mission-data path traceable.
From contract layers to evidence
Until now, each release added another part of the Mission Data Contract.
v0.3.0 made data products and storage intent explicit.
v0.4.0 connected data products to contact windows and downlink flow contracts.
v0.5.0 added commandability and autonomy contracts, making command sources, command rules and recovery assumptions visible.
v0.6.0 adds the next question:
if a command is expected to produce mission data, can OrbitFabric trace that declared data product through storage intent, downlink intent, eligible downlink flow, contact window assumption and scenario evidence?
The contract chain now becomes:
command expected effect -> data product -> storage intent -> downlink intent -> eligible downlink flow -> matching contact window -> scenario evidence -> generated documentation -> JSON report evidence
This is the first end-to-end evidence slice in OrbitFabric.
What changed in v0.6.0
v0.6.0 introduces:
- command-declared data product effects
- command linting for expected data product references
- scenario data-flow assertions
- scenario reference validation for data-flow expectations
- deterministic data-flow evidence recording during simulation
- JSON simulation reports with data_flow_evidence
- generated data_flow.md documentation
- a dedicated data-flow documentation generator
- a new demo scenario: payload_data_flow_evidence.yaml
The important part is not that another generated file exists.
The important part is that the Mission Model can now describe and check a declared path from command intent to mission-data movement assumptions.
Command-declared data product effects
Commands may now declare that they are expected to produce or trigger one or more data products.
A shortened example looks like this:
expected_effects: data_products: - payload.radiation_histogram
This makes the command-to-data-product relationship explicit.
If a command claims to produce a data product that is not declared in data_products.yaml, OrbitFabric should fail early.
That is where the new command diagnostics are useful:
OF-CMD-008 OF-CMD-009
The intent is simple:
a command expected effect should not silently point to a non-existing mission-data object.
Scenario data-flow assertions
Scenarios can now assert that a declared data-flow path exists.
A shortened example looks like this:
expect: data_flow: data_product: payload.radiation_histogram triggered_by_command: payload.start_acquisition storage_intent_declared: true downlink_intent_declared: true eligible_downlink_flow: science_next_available_contact contact_window: demo_contact_001
This does not execute real storage.
It does not execute real downlink.
It asks whether the declared Mission Model contains a coherent contract-level path for that data product.
The scenario loader validates references before execution.
The new scenario diagnostics cover missing or invalid references in data-flow expectations:
OF-SCN-014 OF-SCN-015 OF-SCN-016 OF-SCN-017
What the simulator records
During deterministic host-side scenario execution, OrbitFabric records contract-level data-flow evidence when an accepted command declares data product effects.
The demo scenario exercises a chain like this:
payload.start_acquisition -> payload.acquisition_started -> payload lifecycle ACQUIRING -> payload.acquisition.active = true -> payload.radiation_histogram evidence recorded -> storage intent declared -> downlink intent declared -> science_next_available_contact eligible -> demo_contact_001 matched -> DATA_FLOW expectation met -> SCENARIO PASSED
This is still not a physical simulation.
It is not proving that a payload file exists.
It is not proving that an onboard storage service exists.
It is not proving that a downlink queue or ground station exists.
It is proving something narrower:
the declared Mission Data Contract contains a connected and inspectable path from command intent to data-flow evidence.
Generated artifacts
v0.6.0 adds:
generated/docs/data_flow.md
This file is generated by the standard documentation flow:
orbitfabric gen docs examples/demo-3u/mission/
A dedicated generator is also available:
orbitfabric gen data-flow examples/demo-3u/mission/ \ --output-file generated/docs/data_flow.md
The generated page summarizes declared command-to-data-product paths and renders:
Command
Data Product
Producer
Storage Intent
Downlink Intent
Eligible Downlink Flows
Matching Contact WindowsAs usual in OrbitFabric, generated artifacts are not the source of truth.
The source of truth remains the Mission Model and scenario YAML.
JSON report evidence
The simulation JSON report now carries data-flow evidence.
A shortened representation looks like this:
{ "summary": { "data_flow_evidence": 1 }, "data_flow_evidence": [ { "data_product_id": "payload.radiation_histogram", "triggered_by_command": "payload.start_acquisition", "storage_intent": { "declared": true, "class": "science", "retention": "7d", "overflow_policy": "drop_oldest" }, "downlink_intent": { "declared": true, "policy": "next_available_contact" }, "eligible_downlink_flows": [ "science_next_available_contact" ], "contact_windows": [ "demo_contact_001" ] } ] }This is useful because the evidence is no longer only visible in a human-readable scenario log.
It is also available as machine-readable report data.
That matters for future CI checks, generated evidence packs, integration tooling and eventually ground-facing artifacts.
Boundary
v0.6.0 intentionally does not introduce:
- real payload file generation
- real onboard storage writes
- file-system behavior
- compression behavior
- onboard queues
- real downlink execution
- contact scheduling
- RF behavior
- ground station operations
- CCSDS/PUS/CFDP behavior
- runtime skeleton generation
- flight-ready software
Those are not missing pieces of v0.6.0.
They are outside the boundary.
Data-flow evidence is deterministic contract-level evidence.
It proves that declared Mission Model assumptions are connected and inspectable.
It does not prove that real flight or ground software exists.
Why this matters before v0.7
v0.6.0 is an important architectural step because it completes the first end-to-end Mission Data Chain evidence slice.
OrbitFabric can now show that a command expected to produce a data product can be traced to:
declared data product,
declared storage intent,
declared downlink intent,
eligible downlink flow,
matching contact window,
scenario evidence,
generated documentation,
and JSON report evidence.That is the correct contract-level precondition before generated runtime skeletons.
If v0.7 starts generating runtime skeletons, those skeletons should not emerge from isolated YAML fragments.
They should emerge from a connected Mission Data Contract.
That is what v0.6.0 is about.
Feedback is welcome from people who have worked with command dictionaries, payload data products, storage assumptions, downlink planning, scenario evidence, CI validation or ground-facing integration artifacts and have seen those assumptions drift across tools and documents.
-
v0.5.0 — Commandability and autonomy contracts
05/07/2026 at 22:08 • 0 commentsOrbitFabric v0.5.0 adds the first Commandability and Autonomy Contract slice.
The previous logs focused on the mission-data chain:
what the spacecraft produces,
where data products are intended to be stored,
how they become eligible for downlink,
and which declared contact assumptions support that path.v0.5.0 adds the next contract question:
how are commands intended to be used, constrained, confirmed, and referenced by declared autonomous or recovery assumptions?
This is still contract-level modeling.
It is not command execution.
Why commandability belongs in the contract layer
A small spacecraft mission does not only need to describe telemetry, data products, storage intent and downlink assumptions.
It also needs to describe how commands are expected to be used.
For example:
Can this command be dispatched from ground?
Does it require a contact assumption?
Which mode should allow it?
Does it require explicit confirmation?
What event or telemetry evidence is expected after it runs?
Can an autonomous recovery assumption dispatch a command?
Which fault should lead to which recovery intent?Those are not only runtime questions.
They are also mission-data contract questions.
If a payload acquisition command exists, but nobody declares when it is commandable, which source may dispatch it, what confirmation is expected, or how recovery should stop it during a battery fault, then part of the mission behavior is still implicit.
OrbitFabric v0.5.0 tries to make that implicit layer visible.
What v0.5.0 adds
The new optional domain is:
mission/commandability.yaml
It can describe:
- command sources
- commandability rules
- command confirmation intent
- autonomous action assumptions
- recovery intents
The chain now extends one step further:
Payload Contract -> Data Product Contract -> Storage Intent -> Downlink Intent -> Contact Window Assumption -> Downlink Flow Contract -> Commandability and Autonomy Contract
This does not turn OrbitFabric into a command system.
It adds another declared consistency layer.
Example from the demo mission
A shortened excerpt from the synthetic demo mission looks like this:
commandability: sources: - id: ground_operator type: ground requires_contact: true contact_profile: primary_ground_contact - id: onboard_autonomy type: autonomous requires_contact: false rules: - id: payload_start_ground_rule command: payload.start_acquisition sources: - ground_operator allowed_modes: - NOMINAL confirmation: required expected_events: - payload.acquisition_started expected_effects: telemetry: payload.acquisition.active: true mode_transition: to: PAYLOAD_ACTIVE autonomous_actions: - id: stop_payload_on_battery_low trigger: fault: eps.battery_low_fault dispatches: command: payload.stop_acquisition source: onboard_autonomy expected_events: - payload.acquisition_stopped recovery_intents: - id: payload_battery_low_recovery fault: eps.battery_low_fault target_mode: DEGRADED commands: - payload.stop_acquisition
This is intentionally minimal.
It is not a real operator concept.
It is not a real command stack.
It is not real FDIR.
It is not onboard autonomy software.It is a declared contract-level assumption.
What gets checked
At this stage, the value is consistency.
OrbitFabric should fail early when:
- a commandability rule references an unknown command
- a commandability rule references an unknown source
- a commandability rule references an unknown mode
- a ground command source requires contact but references an unknown contact profile
- an autonomous action dispatches an unknown command
- an autonomous action references an unknown source
- an autonomous action trigger references an unknown event, fault or telemetry item
- a recovery intent references an unknown command
- a recovery intent references an unknown fault, event or mode
- a high-risk command lacks explicit confirmation intent
- an autonomous recovery assumption lacks expected events or effects
The goal is not to execute those commands.
The goal is to expose missing or inconsistent assumptions before they become integration debt.
What this is not
OrbitFabric v0.5.0 does not introduce:
- live uplink services
- operator authentication
- operator authorization
- encryption
- command queues
- operator consoles
- onboard schedulers
- command dispatchers
- flight autonomy runtime
- real FDIR or safing logic
- Yamcs or OpenC3 runtime services
- real spacecraft operations
Those are not missing pieces of v0.5.0.
They are intentionally outside the boundary.
Generated documentation
When commandability/autonomy contracts are present, OrbitFabric now generates:
generated/docs/commandability.md
That generated artifact documents command sources, commandability rules, autonomous action assumptions, recovery intents, referenced commands, referenced modes, expected events and expected effects.
As usual in OrbitFabric, generated artifacts are not the source of truth.
The source of truth remains the Mission Model.
Why this matters before v0.6
v0.5.0 is an important step before end-to-end mission data flow evidence.
Until now, the chain could describe what data is produced, where it is intended to be stored, and how it becomes eligible for downlink.
With commandability/autonomy contracts, the chain can also describe which declared commands and recovery assumptions affect that flow.
That makes the next step more meaningful.
End-to-end evidence should not only show that a payload product exists and can be downlinked.
It should also show that the mission contract declares:
which command starts the activity,
which source may dispatch it,
which mode allows it,
which confirmation is expected,
which fault may interrupt it,
which autonomous action may stop it,
and which recovery intent is declared.That is the reason v0.5.0 deliberately stops at the contract boundary.
OrbitFabric is still not runtime.
It is still not flight software.
It is still not a ground segment.
It is becoming a more complete Mission Data Contract layer.
Feedback is welcome from people who have worked with command dictionaries, operator procedures, fault recovery assumptions, autonomous safing behavior, test scenarios or ground-to-flight handover and have seen those assumptions drift across documents, code and operations planning.
-
New public minislices: from generic CubeSat to communications-oriented mission data contracts
05/06/2026 at 22:58 • 0 commentsToday I added a new set of public minislice examples to OrbitFabric.
The goal was to move beyond a single synthetic demo and show how the same model-first contract approach can be specialized into several small, recognizable CubeSat-style mission data patterns.
The new examples are:
examples/university-cubesat-minislice/ examples/oresat-inspired-minislice/ examples/finch-inspired-minislice/ examples/spacelab-inspired-communications-minislice/
Each minislice is intentionally small, public-material-derived or synthetic, and focused on OrbitFabric’s core scope:
telemetry commands events faults modes packets payload contracts data products contact windows downlink flows scenario evidence generated documentation
OrbitFabric is still not flight software, not an OBC firmware, not a dynamic simulator and not a ground segment.
These examples are contract-layer demonstrations.
1. Generic university CubeSat minislice
The first example is the baseline:
examples/university-cubesat-minislice/
It models a generic university CubeSat mission-data chain:
payload data generated → low-power warning → constrained low-rate contact → health and critical data prioritized → payload data partially downlinked → remaining data kept pending onboard → scenario evidence explains the result
This example is fully synthetic and acts as the clean baseline for the more specific public-inspired examples.
2. OreSat-inspired minislice
The second example is:
examples/oresat-inspired-minislice/
This is a public conceptual demo inspired by the OreSat ecosystem.
It focuses on a CubeSat-style pattern involving:
beacon / housekeeping priority power-aware operations C3-style command and data handling CFC-style payload data constrained downlink retained payload backlog
It is not an official OreSat model. It is not endorsed by OreSat, PSAS or Portland State University. It is not a conversion of OreSat configs or CANopen object dictionaries. It does not replace OreSat software, OLAF, Yamcs, configs or ground tools.
The point is narrower: use public inspiration to test whether OrbitFabric can express a realistic constrained-downlink mission data contract.
3. FINCH-inspired minislice
The third example is:
examples/finch-inspired-minislice/
This one is focused on an imaging-payload workflow.
It models:
acquisition parameters loaded → OBC schedules image acquisition → ADCS readiness checked → payload camera readiness checked → image acquisition → data compression → constrained downlink → compressed image data partially pending → scenario evidence records the outcome
It is not an official FINCH model. It is not endorsed by UTAT Space Systems, the University of Toronto Aerospace Team or the University of Toronto. It is not a conversion of FINCH architecture diagrams. It does not replace FINCH firmware, data-processing tools or systems-engineering tools.
The purpose is to show a different vertical slice: acquisition readiness, payload data generation, compression and partial downlink.
4. SpaceLab-inspired communications minislice
The fourth example is:
examples/spacelab-inspired-communications-minislice/
This one is communications-oriented rather than payload-oriented.
It is inspired by public SpaceLab UFSC / FloripaSat / GOLDS-UFSC material and focuses on a compact TT&C / OBDH data-flow contract:
periodic beacon available → synthetic ground contact starts → TT&C receives an abstract data-request command → OBDH accepts the request → OBDH selects stored telemetry/data frames → OBDH packages frames for downlink → beacon and critical housekeeping are prioritized first → requested frames are partially downlinked → remaining frames stay pending onboard → decoder evidence records partial completion
It is not an official SpaceLab, FloripaSat or GOLDS-UFSC model. It is not endorsed by SpaceLab UFSC or UFSC. It is not a claim that SpaceLab uses OrbitFabric. It is not a conversion of FloripaSat architecture, firmware, packet formats or operational plans. It does not replace SpaceLab decoder, transmitter, TT&C, OBDH, firmware or ground station software.
No real frequencies, callsigns, keys, TLEs, ground-station schedules or operational details are modeled.
Why these examples matter
The important part is not the number of files added.
The important part is that the same OrbitFabric structure can now describe four different mission-data situations:
generic CubeSat data/backlog flow power-aware beacon/housekeeping-first flow imaging acquisition/compression/downlink flow TT&C / OBDH / data-request / decoder-evidence flow
Each example follows the same general OrbitFabric pattern:
Mission Model YAML → lint validation → generated documentation → deterministic scenario execution → explicit scenario evidence
The examples also keep the v0.4.0 contact/downlink model consistent:
mission/contacts.yaml
contains:
contact_profiles link_profiles contact_windows downlink_flows
There is no separate
downlink.yaml.Validation
The minislices are designed to be checked with the standard OrbitFabric workflow:
orbitfabric lint examples/<minislice>/mission orbitfabric gen docs examples/<minislice>/mission orbitfabric sim examples/<minislice>/scenarios/<scenario>.yaml
The constrained-downlink examples intentionally produce warnings where eligible data volume exceeds declared contact capacity.
That is not a bug.
It is the behavior being demonstrated:
contact capacity is limited critical data is prioritized non-critical or requested data remains partially pending scenario evidence explains why
Clean-room note
All examples are synthetic or publicly inspired.
They do not include proprietary mission data, private architectures, private protocols, real operational logs, real ground-station plans, sensitive RF details or non-public payload information.
The objective is to keep OrbitFabric useful as a model-first mission data fabric while staying clearly within a clean-room, public-demo boundary.
This batch of minislices is a useful step for OrbitFabric because it shows the framework from four angles:
baseline mission data contract public CubeSat-inspired specialization payload/imaging workflow communications and TT&C workflow
That makes the project easier to explain, easier to test and easier to extend.
-
v0.4.0 — Contact windows and downlink flow contracts
05/05/2026 at 12:51 • 0 commentsOrbitFabric v0.4.0 extends the mission-data chain beyond payloads, data products and storage intent.
This release is about contact and downlink assumptions.
What v0.4.0 adds
Before this release, OrbitFabric could already model a chain such as:
Payload Contract -> Data Product Contract -> Storage Intent -> Downlink Intent
With v0.4.0, that chain becomes:
Payload Contract -> Data Product Contract -> Storage Intent -> Downlink Intent -> Contact Window Assumption -> Downlink Flow Contract
This does not make OrbitFabric an operational downlink system.
It makes declared assumptions explicit.
The boundary: contract, not runtime
This is an important boundary.
OrbitFabric v0.4.0 does not:
- compute real orbital passes
- schedule real ground contacts
- simulate RF links
- execute downlink
- replace a ground segment
The v0.4.0 model works at contract level.
It asks a narrower question:
if a mission declares that a data product should be stored and later downlinked, are the declared contact and downlink assumptions coherent enough to be reviewed, linted and documented?
What contacts.yaml can express
The optional contacts.yaml domain can describe:
- contact profiles
- link profiles
- contact windows
- declared contact capacity
- downlink flow intent
- eligible data products
This gives the Mission Model a way to express questions such as:
- which contact assumption is being used?
- which link profile applies?
- what capacity is declared for that window?
- which data products are eligible?
- which downlink flow references them?
- does the declared flow reference valid mission objects?
For small spacecraft projects, those assumptions often exist anyway.
They may live in an operations note, a spreadsheet, a test script, a ground-facing configuration file, or simply in the head of the person who planned the first demo pass.
OrbitFabric v0.4.0 tries to move those assumptions into the Mission Data Contract.
Example from the demo mission
A shortened excerpt from the synthetic demo mission looks like this:
contact_windows: - id: demo_contact_001 contact_profile: primary_ground_contact link_profile: uhf_downlink_nominal start: "2026-01-01T00:00:00Z" duration_seconds: 600 assumed_capacity_bytes: 512000 downlink_flows: - id: science_next_available_contact contact_profile: primary_ground_contact link_profile: uhf_downlink_nominal queue_policy: priority_then_age eligible_data_products: - payload.radiation_histogram
This is intentionally simple.
What this example is not
The example is not:
- a real pass
- based on TLE propagation
- derived from a ground station network
- a real RF budget
- an operational schedule
It is a declared contract-level assumption.
That assumption is useful because it connects the data product model to the downlink model.
The demo data product payload.radiation_histogram is produced by a synthetic payload contract, has storage intent, has retention intent, has overflow policy and has downlink intent.
The v0.4.0 contact/downlink model then gives that data product a declared path toward downlink eligibility.
What gets checked
At this stage, the value is consistency.
OrbitFabric should fail early when:
- a downlink flow references an unknown data product
- a contact window references an unknown profile
- a link profile or contact profile is missing
- a mission claims that a data product is intended for downlink but no visible contract-level assumption explains how it becomes eligible
The generated contacts.md artifact is therefore not just documentation.
It is a reproducible view of declared downlink assumptions.
As usual in OrbitFabric, generated artifacts are not the source of truth.
The source of truth remains the Mission Model.
The current flow is:
contacts.yaml -> contact profile validation -> link profile validation -> contact window validation -> downlink flow consistency validation -> generated contact/downlink documentation
Why this stops before runtime
This release deliberately stops before runtime.
That is the correct boundary for now.
The project needs the mission-data chain to be explicit before it makes sense to generate runtime skeletons, ground integration artifacts or adapters for existing tools.
OrbitFabric v0.4.0 is not trying to be impressive through execution.
It is trying to make another part of the engineering contract visible:
not only what the spacecraft produces, but also what the mission assumes can eventually be downlinked.
Feedback is welcome from people who have worked with small spacecraft operations, ground passes, payload data products, downlink planning, contact assumptions or mission-data handover between flight and ground teams.
-
Payload contracts, data products and storage intent
05/05/2026 at 12:50 • 0 commentsIn OrbitFabric, a payload is not treated only as something that produces telemetry.
A payload may also produce mission data products.
That distinction matters.
Payload data is not just telemetry
Telemetry is usually about observability: state, health, counters, measurements, events and operational status.
Mission data products are different.
They are the objects the mission wants to preserve, reason about, store and eventually downlink.
For a small spacecraft project, that difference can easily become blurred.
A payload may expose telemetry.
It may accept commands.
It may raise events.
It may enter lifecycle states.
It may generate faults.
It may produce histograms, images, files, packets, measurements or other mission-specific outputs.If those relationships are only described informally, integration debt appears quickly.
The onboard software may know one version.
The payload documentation may describe another.
The test scenario may assume another.
The storage plan may evolve separately.
The downlink plan may be discussed later.
The generated documentation may lag behind.OrbitFabric tries to make that chain explicit.
The contract chain
The current v0.4.0 model includes optional Payload Contracts and Data Product Contracts.
A payload contract describes mission-facing payload behavior at contract level.
A data product contract describes a mission-data object produced by a payload or subsystem.
The intended chain is:
Payload Contract -> declared payload behavior -> Data Product Contract -> Storage Intent -> Retention Intent -> Overflow Policy -> Downlink Intent
This does not describe payload firmware.
It does not describe payload drivers.
It does not describe hardware buses.
It does not simulate the physical payload.
It describes the mission-facing contract.
Payload contract excerpt
The synthetic demo mission includes a clean-room IOD payload contract.
A shortened excerpt looks like this:
payloads: - id: demo_iod_payload subsystem: payload profile: iod lifecycle: initial_state: READY states: - OFF - READY - ACQUIRING - FAULT telemetry: produced: - payload.acquisition.active commands: accepted: - payload.start_acquisition - payload.stop_acquisition events: generated: - payload.acquisition_started - payload.acquisition_stopped
This tells the model which mission-facing objects belong to that payload contract.
It does not tell OrbitFabric how the payload firmware is implemented.
Data product excerpt
The same demo mission declares one synthetic payload data product.
A shortened excerpt looks like this:
data_products: - id: payload.radiation_histogram producer: demo_iod_payload producer_type: payload type: histogram estimated_size_bytes: 4096 priority: high storage: class: science retention: 7d overflow_policy: drop_oldest downlink: policy: next_available_contact
This is not a real payload product.
It is a clean-room demo object used to exercise the model.
The important point is not the histogram itself.
The important point is that the data product has declared engineering intent:
- who produces it
- what type of product it is
- how large it is expected to be
- how important it is
- where it is intended to be stored
- how long it should be retained
- what happens on overflow
- how it is intended to become eligible for downlink
What gets checked
At this stage, the value is consistency.
OrbitFabric should fail early when:
- a data product references an unknown producer
- a payload contract references missing telemetry, commands, events or faults
- storage intent is malformed or incomplete
- downlink intent is malformed or incomplete
- generated documentation would otherwise hide a contract gap
The generated data_products.md artifact is therefore not the source of truth.
It is a reproducible view of the declared Mission Model.
The source of truth remains the Mission Model.
Why storage intent matters
Storage assumptions tend to spread across many places in real small spacecraft development:
- payload documentation
- OBC software
- mass memory handling
- operational procedures
- ground planning
- test scripts
- data processing expectations
OrbitFabric does not solve all of that.
It does not implement a storage service.
It does not decide where real files are written.
It does not manage onboard memory.
It does not execute downlink.
It does not replace the ground segment.But it can make the declared intent visible early.
What this does not mean
This is contract-level modeling.
It is not:- a runtime
- a scheduler
- a flight stack
The goal is to reduce ambiguity before implementation and integration make ambiguity expensive.
Connection to v0.4.0
For v0.4.0, this becomes more useful because Data Product Contracts now connect naturally to Contact Windows and Downlink Flow Contracts.
That means the model can express a wider chain:
Payload Contract -> Data Product Contract -> Storage Intent -> Downlink Intent -> Contact Window Assumption -> Downlink Flow Contract
Again, this is contract-level modeling, not runtime behavior.
Feedback is welcome from anyone who has worked with payload outputs, onboard storage assumptions, telemetry dictionaries, data product documentation or downlink planning and has seen those assumptions drift apart.
-
From mission model to reproducible artifacts
05/05/2026 at 12:48 • 0 commentsThe core idea behind OrbitFabric is simple.
The Mission Model should be the source of truth.
Not the generated documentation.
Not the test log.
Not a hand-written table.
Not a partially outdated diagram.The model comes first
In many small spacecraft projects, mission data definitions start clean and then drift.
Telemetry is described in one place.
Commands are implemented somewhere else.
Events and faults are listed in a document.
Payload behavior is captured in tests.
Storage assumptions live in a planning sheet.
Downlink assumptions are discussed during integration.
Ground-facing artifacts are created later, often manually.OrbitFabric explores a different flow.
The model comes first.
The current demo mission lives under:
examples/demo-3u/mission/
It contains structured YAML files for the mission contract:
examples/demo-3u/mission/ ├── spacecraft.yaml ├── subsystems.yaml ├── modes.yaml ├── telemetry.yaml ├── commands.yaml ├── events.yaml ├── faults.yaml ├── packets.yaml ├── policies.yaml ├── payloads.yaml ├── data_products.yaml └── contacts.yaml
Those files are not intended to be a pretty configuration layer over an existing implementation.
They are intended to make mission-data assumptions explicit before they become scattered across code, tests, documents and ground tooling.
The current v0.4.0 flow
The current v0.4.0 flow is:
Mission Model YAML -> structural validation -> semantic lint -> engineering lint -> JSON lint report -> generated Markdown documentation -> scenario validation -> deterministic scenario execution -> simulation report -> simulation log
That matters because every generated artifact is derived from the same declared contract.
If a telemetry point is renamed, the documentation should not silently keep the old name.
If a scenario references a command that does not exist, that should fail early.
If a payload data product references an invalid producer, that should be detected.
If a downlink flow references an unknown contact profile or an ineligible data product, that should not remain a hidden integration assumption.
CLI flow
The current CLI reflects this model-first flow.
Typical local checks are:
orbitfabric lint examples/demo-3u/mission/ orbitfabric gen docs examples/demo-3u/mission/ orbitfabric sim examples/demo-3u/scenarios/battery_low_during_payload.yaml
Generated documentation
The generated documentation currently includes mission-facing artifacts such as:
generated/docs/ ├── telemetry.md ├── commands.md ├── events.md ├── faults.md ├── modes.md ├── packets.md ├── payloads.md ├── data_products.md └── contacts.md
These files are generated outputs.
They are useful for review, discussion and integration.
But they are not the source of truth.
The source of truth remains the Mission Model and the scenario definitions.
Scenario evidence
The same applies to simulation reports and logs.
For example, the synthetic demo scenario battery_low_during_payload exercises a declared chain:
payload.start_acquisition -> payload.acquisition_started -> mode transition into PAYLOAD_ACTIVE -> battery voltage degradation -> eps.battery_low -> mode transition into DEGRADED -> automatic payload.stop_acquisition dispatch -> payload.acquisition_stopped -> scenario passed
This is not a physics simulation.
It is not a flight software runtime.
It is not running on an OBC.
It is a deterministic host-side scenario derived from declared mission contracts.
That distinction is intentional.
Why this matters
OrbitFabric is trying to answer a narrow engineering question:
can we keep mission-data assumptions explicit enough that validation, documentation and scenario evidence all come from the same source?
The current answer is still partial, but useful enough to build on.
The v0.4.0 release extends this idea beyond telemetry, commands, payloads and data products by adding contact windows and downlink flow contracts.
That means the model can now describe not only:
what data product exists,
but also:
where it is intended to be stored,
how long it should be retained,
what its downlink intent is,
which contact assumptions exist,
and which downlink flow makes it eligible.Boundary
Again, this is contract-level modeling.
OrbitFabric does not execute real downlink.
It does not schedule real passes.
It does not perform RF simulation.
It does not replace a ground segment.It makes declared assumptions visible, lintable, documentable and testable in deterministic scenarios.
For an early-stage small spacecraft project, that can be valuable before the implementation stack becomes too fragmented.
Feedback is welcome from anyone who has worked with telemetry dictionaries, command tables, payload data products, generated documentation, test scenarios or ground-facing configuration and has seen those artifacts drift apart over time.
-
Why OrbitFabric exists
05/05/2026 at 12:45 • 0 commentsSmall spacecraft projects rarely fail because nobody wrote a YAML file.
They fail, or at least become painful to integrate, when several different descriptions of the same mission behavior start drifting apart.
The problem: mission-data drift
One description lives in the mission document.
Another one lives in onboard software assumptions.
Another one lives in test scripts.
Another one lives in generated reports.
Another one lives in ground-facing configuration.
Another one may exist only in somebody's head.Telemetry, commands, events, faults, packets, payload outputs, storage expectations and downlink assumptions are often treated as separate artifacts.
That separation is where integration debt starts.
What OrbitFabric tries to do
OrbitFabric exists to explore a different approach:
define the mission data contract once,
validate it,
generate documentation from it,
run deterministic host-side scenarios from it,
and later use it as the basis for integration artifacts.The important point is not the file format.
The important point is the engineering boundary.
What does the mission claim to produce?
What commands are expected?
What events and faults can be raised?
What data products exist?
Where are they intended to be stored?
When should they become eligible for downlink?
Which contact assumptions are being used?In a small spacecraft project, those questions should not be answered differently by the README, the onboard code, the test scripts and the ground configuration.
OrbitFabric is an attempt to make those assumptions explicit early, before they become hidden integration debt.
Current v0.4.0 scope
The current v0.4.0 release focuses on the contract layer.
It can model:
- spacecraft structure
- subsystems
- modes
- telemetry
- commands
- events
- faults
- packets
- payload contracts
- data products
- storage intent
- contact windows
- downlink flow contracts
A simplified view of the current idea is:
Mission Model -> validation -> lint report -> generated documentation -> scenario validation -> deterministic scenario execution -> simulation report -> simulation log Optional Payload Contract Model -> payload reference validation -> payload lifecycle validation -> payload documentation generation Optional Data Product Contract Model -> producer reference validation -> storage intent validation -> downlink intent validation -> data product documentation generation Optional Contact and Downlink Contract Model -> contact profile validation -> link profile validation -> contact window validation -> downlink flow consistency validation -> contact/downlink documentation generation
What OrbitFabric is not
The current project is intentionally narrow.
OrbitFabric is not:
- flight software
- OBC firmware
- a ground segment
- a spacecraft dynamics simulator
- a real downlink runtime
- a CCSDS/PUS/CFDP implementation
- a replacement for cFS, F Prime, Yamcs, OpenC3 or OpenMCT
Those may become future integration directions or generated artifact targets, but they are not current capabilities.
Why the boundary matters
This is still a pre-1.0 engineering project.
The examples are synthetic and clean-room.
The current demo mission is not a real spacecraft.
The contact windows are declared assumptions, not real orbital pass predictions.
The downlink flow model is a contract-level consistency layer, not an operational downlink runtime.That boundary matters.
OrbitFabric should be judged as a small open-source attempt to reduce drift between mission design, software assumptions, tests, generated documentation and ground-facing artifacts.
Not as a complete flight stack.
Not as a ground segment.
Not as a simulator.As a mission data contract layer.
Feedback is welcome, especially from people who have seen telemetry, command, payload-data or ground-interface assumptions drift during small spacecraft development.
Fabrizio Rovelli
