orbitforge fleet save
Synopsis
orbitforge fleet save --state <PATH> [OPTIONS]Description
Stores a fleet state as an immutable, content-addressed snapshot. The identifier is derived from the content, so identical states always produce the same identifier and any change produces a different one.
Snapshots can name the snapshot they supersede, which builds a chain recording how a fleet’s intended configuration evolved and why.
Options
| Parameter | Type | Unit | Default | Required | Description |
|---|---|---|---|---|---|
--state | path | n/a | — | Yes | Path to a FleetState JSON file. See the schema below. |
--created | string | RFC 3339 UTC | 2026-01-01T00:00:00Z | No | Creation timestamp recorded with the snapshot. |
--note | string | n/a | empty | No | Free-form note. This is the only place the reason for a change is recorded; use it. |
--parent | string | n/a | — | No | Identifier of the snapshot this one supersedes. Full identifier or an unambiguous prefix. |
--store | path | n/a | fleet-store | No | Store directory. |
Fleet state schema
{
"name": "demo-fleet",
"slots": [
{
"id": "demo-s0-p00-sat00",
"elements": {
"semi_major_axis_km": 6928.0,
"eccentricity": 0.001,
"inclination_deg": 53.0,
"raan_deg": 0.0,
"argument_of_perigee_deg": 0.0,
"true_anomaly_deg": 0.0
}
}
]
}A slot is an as-designed position: the orbit a satellite is meant to occupy, identified by the design satellite identifier. The fleet state is the set of slots the fleet must fill, which is what reconciliation compares the as-flown catalog against.
Worked example
Saving a baseline:
orbitforge fleet save \
--state fleet.json \
--note "initial design baseline"Saved fleet `demo-fleet` as 8d063f302793 (2026-01-01T00:00:00Z).Then recording a correction that supersedes it:
orbitforge fleet save \
--state fleet2.json \
--created 2026-02-01T00:00:00Z \
--note "phasing corrected after drift" \
--parent 8d063f302793Saved fleet `demo-fleet` as 564f2234b82b (2026-02-01T00:00:00Z).The second snapshot differs from the first by a single satellite’s true anomaly, changed from 36.0 to 37.5 degrees. That one field produces an entirely different identifier, which is the property that makes the store trustworthy.
Content addressing
The identifier is a hash of the content, which has three consequences worth understanding:
| Property | Consequence |
|---|---|
| Identical content, identical identifier | Saving the same state twice does not create a second snapshot |
| Any change, different identifier | A modified state cannot masquerade as the original |
| Identifiers are not sequential | 564f... being saved after 8d06... is not deducible from the identifiers; ordering comes from --created and --parent |
Because the identifier is derived from content alone, two snapshots with different
--note or --created values but identical state are the same snapshot. The note is
metadata about the save, not part of the addressed content. If you need to record a
different rationale for an unchanged state, the state has not actually changed and the
note belongs elsewhere.
Using the parent chain
--parent is what turns a pile of snapshots into a history. Without it the store
records what states existed; with it, the store records the order they were
adopted in and which superseded which.
The discipline that makes this valuable is writing a real note. "phasing corrected after drift" tells a future reader why the change happened.
"update" does not, and by the time anyone reads it the reason is gone.
See also
fleet listto see stored snapshots.fleet showto print one by identifier.
main (pre-release)