Stellar ControlMission control · by Stellar Systems v0.1.0

Core Concepts

Configuration Repository

Where catalogues, topology, steps, procedures and simulations live, and how changes to them are reviewed and published.

The desired state of the MCS — what the platforms look like, which targets exist and how to reach them, which procedures operators run — lives in a Git repository of plain text files. Changes go through merge requests; the CI checks them with the same compiler as the editor and the services; after the merge, the CI publishes the compiled snapshot, and the reconciler applies it at the next safe points.

The MCS applies what the repository contains and imposes no editing role: who may change a catalogue, and who must approve a procedure, is decided by the review process of your forge (protected branches, required approvals). The MCS only applies the status of the packages.

Layout#

text
topology.yaml                   environments, targets, links, output connectors (optional)
stellar.yaml                    packages taken from other repositories (optional)
packages.lock                   their commit and hash, written by `stellar fetch`
packages/
  platform-v3/catalogue.yaml    a catalogue package
  lab-psu/catalogue.yaml
  obc-v1/catalogue.yaml
  platform-v3-steps/            a library of steps and procedures
    package.yaml                name, version, status, catalogue dependencies
    specification.proc          steps and procedures
    operations.proc
    transfers.proc
    stellar.lock                validated versions, written by `stellar lock`
simulations/                    simulated targets, for dry runs, tests and training
  platform-v3-sim.yaml
  lab-psu-sim.yaml
runs/                           run requests, for dry runs in CI (a convention)
  hot-standby.yaml
PathContentReference
topology.yamlEnvironments and their policies, targets, links, output connectors. Optional: a subsystem repository may publish packages onlyTargets
stellar.yamlPackages taken from other repositories, by git repository, tag and pathSeveral repositories
packages.lockThe commit and the hash of each of them, written by stellar fetchSeveral repositories
packages/<dir>/catalogue.yamlA catalogue package: one version of a platformCatalogue Packages
packages/<dir>/package.yamlThe manifest of a library of steps and proceduresLibraries and Validation
packages/<dir>/*.procSteps and procedures of that librarySteps and Procedures
packages/<dir>/stellar.lockThe validated versions of the steps and procedures of the libraryCompilation, Snapshots and Locks
simulations/<name>.yamlA simulated target, compiled against the catalogue of its platformSimulated Targets
runs/*.yamlRun requests, by convention, for dry runs in CIRunning Procedures

Every directory under packages/ holds one version of one package. The name and version come from the file itself (package: and version:), not from the directory name; to keep two versions of a platform, use two directories.

A catalogue package#

YAML
# packages/lab-psu/catalogue.yaml
package: lab-psu
version: 1.0.0
status: released

components:
  psu:
    description: The bench power supply feeding the platform.
    measures:
      voltage: {type: f32, unit: V, max_age: 5s, description: Output voltage.}
      current: {type: f32, unit: A, max_age: 5s, description: Output current.}
      output_enabled: {type: bool, max_age: 5s, description: Whether the output is on.}
    telecommands:
      output_on:
        description: Switches the output on.
        verify: [{output_enabled: true, within: 3s}]

A catalogue is also an exchange format: it can be generated in the CI of an avionics subsystem from its types, its ICD or its TM/TC database, and published as a versioned package. The compiler validates it like a hand-written one (the example satlink-bench catalogue is generated by a script from the DSL of the bench).

A library#

YAML
# packages/platform-v3-steps/package.yaml
package: platform-v3-steps
version: 1.4.2
status: released
depends:
  platform-v3: 1.4.x
  lab-psu: 1.x

depends lists the catalogue packages the roles of its steps and procedures use, with a version requirement: exact (1.4.0), any patch (1.4.x) or any minor (1.x, or 1). The highest matching version present in the repository is used, and recorded in the lock.

Status of packages#

status is draft (the default) or released. It is a policy applied by the environment:

  • a target engaged in an environment without allow_draft must implement a released catalogue, checked at compile time (topology::draft-not-allowed);
  • a run in such an environment refuses a draft library or catalogue at launch (run::draft-not-allowed).

Moving from draft to released follows your review process.

Versions and immutability#

A published version never changes in place: a change is a new version. Drivers know catalogues by version (platform-v3@^1.4 accepts 1.4.0 and the following 1.x), never by hash. The lock of the libraries that use a catalogue reveals a version modified in place: stellar check --locked fails.

Descriptions (description fields and description "…" lines) are outside of this rule: they travel beside the compiled catalogue, so rewording them changes neither the hash of a catalogue nor the lock of a step. See Compilation, Snapshots and Locks.

Working on the repository#

CommandEffectExit code
stellar check [DIR]Compiles everything; prints diagnostics, then what must be validated again1 on an error
stellar check [DIR] --lockedSame, for CI1 on an error or a pending validation
stellar check [DIR] --format jsonOne JSON object per line: diagnostics, then revalidationsas above
stellar lock [DIR]Rewrites every stellar.lock from the current sources1 on an error
stellar compile [DIR] [--output FILE] [--publish NATS_URL]Writes the snapshot, prints its hash, optionally makes it current1 on an error
stellar run --dry REQUEST --repository DIRRuns a procedure on ephemeral simulated targets1 when the procedure fails
stellar schema <kind>Prints the JSON Schema of catalogue, library, topology or simulation files0

Compilation parameters (executor.default_retry, derived.max_window) come from the global configuration (--config stellar.yaml or STELLAR_CONFIG); defaults apply without it. Use the same values in CI as in the deployment, since the retry policy and the time windows are part of what is validated.

Editors help with the files:

  • The VS Code extension and the language server give live diagnostics, completion and hover in .proc files and the YAML files.
  • The web editor edits a draft branch in the browser and opens the merge request.
  • stellar schema catalogue > catalogue.schema.json gives any YAML editor the schema of catalogues.

The merge request workflow#

sequenceDiagram
    participant A as Author
    participant G as Git forge
    participant CI
    participant N as NATS (stellar_ir)
    participant R as Reconciler
    A->>A: edit, stellar check
    A->>A: stellar lock (when ready for review)
    A->>G: push, open merge request
    G->>CI: stellar check . --locked
    CI-->>G: pass / fail
    G->>G: review and approval (validates the lock diff)
    G->>CI: merge on the default branch
    CI->>N: stellar compile . --publish
    N->>R: current snapshot changes
    R->>R: applies it at the safe points
  1. The author changes catalogues, steps or procedures and runs stellar check, then stellar lock once the change is ready for review.
  2. The merge request shows the stellar.lock diff: every step and procedure it validates again, including the procedures that only use a changed shared step. Approving the merge request is the validation.
  3. CI runs stellar check --locked: it fails on any error, and on any change whose lock was not updated, so an unreviewed change cannot be merged.
  4. After the merge, the CI of the default branch runs stellar compile --publish; the reconciler applies the snapshot at the next safe points.

GitHub Actions#

YAML
jobs:
  check:
    runs-on: ubuntu-latest
    container: ${{ vars.STELLAR_CLI_IMAGE }}   # an image providing `stellar`
    steps:
      - uses: actions/checkout@v4
      - run: stellar fetch .          # packages of other repositories (stellar.yaml), if any
      - run: stellar check . --locked

GitLab CI#

YAML
stellar-check:
  image: $STELLAR_CLI_IMAGE   # an image providing `stellar`
  rules:
    - if: $CI_PIPELINE_SOURCE == "merge_request_event"
  script:
    - stellar fetch .               # packages of other repositories (stellar.yaml), if any
    - stellar check . --locked

stellar-dry-runs:
  image: $STELLAR_CLI_IMAGE   # with a nats-server binary
  rules:
    - if: $CI_PIPELINE_SOURCE == "merge_request_event"
  script:
    - for request in runs/*.yaml; do stellar run --dry "$request" --repository . || exit 1; done

stellar-publish:
  image: $STELLAR_CLI_IMAGE
  rules:
    - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
  script:
    - stellar compile . --publish "$STELLAR_NATS_URL"

Mark the check job as required (protected branch, "Pipelines must succeed") so that a failing check blocks the merge request. No CLI image is published yet: build one providing stellar (cargo install --path tooling/cli), and add a nats-server binary for dry runs. The publish job needs credentials allowed to write stellar_ir and stellar_config: pass them with --nats-credentials (STELLAR_NATS_CREDENTIALS), and --nats-ca for a TLS server.

Several repositories#

A subsystem team can keep its own repository that only holds packages — a catalogue, a library of procedures —, without topology.yaml: stellar check compiles it like any other, and a tag publishes a version. Another repository takes them by declaring them in stellar.yaml:

YAML
# stellar.yaml of the satellite repository
packages:
  hsc-100:                      # the name of the package
    git: https://github.com/stellar-systems-eu/control-usecase-payload-integration
    tag: v1.0.0                 # or `rev:` a commit or a branch
    path: packages/hsc-100      # its directory in that repository
  hsc-100-ops:
    git: https://github.com/stellar-systems-eu/control-usecase-payload-integration
    tag: v1.0.0
    path: packages/hsc-100-ops
Shell
stellar fetch                   # into the cache, commits and hashes in packages.lock
stellar check --locked          # as in CI
stellar fetch --update          # take the current commit of each tag or revision
  • Fetched once, read offline. stellar fetch is the only command that reaches the network, through git and its credentials. It keeps a mirror of each repository and checks the package out at the commit of its tag in the cache: $STELLAR_CACHE, else $XDG_CACHE_HOME/stellar, else ~/.cache/stellar. Nothing is copied into the repository. The compiler, the editor and the language server read the packages from the cache.
  • Locked. packages.lock, to commit, records for each package its declaration, the commit of its tag and the hash of its files. stellar fetch keeps the commit locked even when the tag moved; --update takes the new one. A package whose files in the cache no longer match its hash is refused (package::external-changed), and stellar fetch checks it out again.
  • Resolved like the others. uses and depends resolve the packages of stellar.yaml as those of packages/: the platform imports the camera, the libraries depend on it, and their locks hold its hash as for a local package.
  • Read-only and released. A package taken from another repository must be the one declared (package::external-name) and status: released (package::external-draft). To change it, publish a new version in its own repository.
CodeWhen
package::external-invalidNeither or both of tag and rev
package::external-unlockedDeclared but not in packages.lock as declared: run stellar fetch
package::external-not-fetchedLocked but not in the cache: run stellar fetch
package::external-changedIts files in the cache no longer match the lock
package::external-name, package::external-draftNot the package declared, or a draft

In CI, run stellar fetch before stellar check --locked, and keep the cache between jobs (STELLAR_CACHE) to work without the network once it is filled. The playground of the onboarding, which compiles in the browser, does not fetch packages of other repositories.

The example repository#

examples/config in the source repository is a complete, CI-checked example: the platform-v3, lab-psu, obc-v1 and satlink-bench catalogues, a topology with simulated, bench, flatsat and flight targets, the platform-v3-steps library with the procedures of the specification, two simulations and a run request. Your First Procedure uses it.

Stellar Control · v0.1.0

↑↓ to moveEnter to open