Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 22 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,14 +30,16 @@ and never define the shared semantic boundary (ADR-002).
pip install raes-adapters # shared base plumbing + qualification evidence
```

The `cyborg` extra key is reserved but intentionally empty. Issue
The selected CybORG backend is admitted and usable through its documented
source installation. The `cyborg` extra key is reserved but currently empty. Issue
[#12](https://github.com/RAESystem/adapters/issues/12) qualified the official
CAGE Challenge 2 source and a packaging-only fix, but the upstream wheel omits
the version and Scenario2 runtime data. The fixed wheel passed a clean Python
3.12 smoke locally, but it is not a governed public artifact and the
distribution's declared Python/platform range is not yet qualified. Advertising
an editable checkout, install-time clone, or unpublished wheel as the extra
would hide those blockers.
3.12 smoke. Until that fix is published, install the pinned CAGE-2 source at
commit `26ce1c1253fa9e2e73f25e6a7f2da32860c11257`, apply
`src/raes_adapters/cyborg/cage2-wheel-package-data.patch`, and install its
`CybORG/` package into the environment. The adapter validates the installed
version and selected source-file digests before constructing the backend.

There is also intentionally no `cyberbattlesim` extra. The
[qualification record](src/raes_adapters/cyberbattlesim/qualification.json)
Expand Down Expand Up @@ -168,11 +170,23 @@ and sanitized red/blue/green smoke result. The accompanying
[packaging patch](src/raes_adapters/cyborg/cage2-wheel-package-data.patch) is
qualification evidence only; it is not silently applied or published.

Issue [#15](https://github.com/RAESystem/adapters/issues/15) supplies a
provisioning-only RAES target for that backend. `create_cyborg_target()` accepts
admitted RAES provisioning plans and deterministically generates the native
CybORG scenario: RAES switches become subnets, VM multiplicity becomes hosts,
infrastructure links become subnet membership, and supported OS families select
digest-verified CybORG images. The portable compiled plan entries and
configuration-bound realization-envelope identity remain in the RAES snapshot;
native CybORG objects stay private. Unsupported or lossy node facts fail before
construction. Action stepping, participant-relative observations, and evaluation
are added by the following roadmap issues rather than being claimed by this
first manifest.

The separate
[architecture guardrails](docs/decisions/cyborg-cage2-runtime-qualification-guardrails.md)
define the boundary: the result is not an adapter manifest, conformance claim,
replication claim, or permission to place native CybORG state in portable RAES
artifacts.
define the qualification boundary: source installation and known losses limit
strong replay/equivalence claims, but do not veto adapter construction or
permission to retain an honest partial reproducibility record.

## Development

Expand Down
141 changes: 141 additions & 0 deletions docs/decisions/cyborg-cage2-provisioner-manifest-guardrails.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
# CybORG/CAGE-2 Provisioner and manifest guardrails

GitHub issue #15 owns the first usable RAES boundary around the maintainer-
selected CybORG backend. The purpose is incremental: a researcher who uses
CybORG through RAES should retain more portable information about the scenario
and backend selection than a direct invocation retains, even before later
issues add action, observation, evaluation, and equivalence evidence.

## Authority and admission

The maintainer selected the pinned CAGE-2/CybORG profile, so the backend is
admitted. Qualification records source identity, installation mechanics,
known defects, and attainable claim strength. It does not decide whether an
adapter may exist.

The current packaging fact is narrower: the official CybORG 2.1 wheel omits
runtime data, while the qualified packaging-only fix has not been published as
an index artifact. Users can and do install CybORG from source. The adapter
therefore supports that documented source-install route and validates the
installed version and selected runtime-file digests. The empty optional extra
discloses an automatic-installation limitation; it is not an admission veto.

## Backend boundary

CybORG is the simulator backend. A RAES `RuntimeTarget` is only the RAES object
that groups the backend adapter's components and manifest. Issue #15 supplies
the Provisioner component:

- an admitted `ProvisioningPlan` enters the backend adapter;
- the adapter projects the complete desired state into a generated CybORG
scenario and privately owns the resulting simulator;
- the RAES snapshot retains copied portable plan entries and the selected
realization-envelope identity; and
- no native CybORG object or output crosses the portable boundary.

Issues #16–18 add logical stepping/action translation, participant episodes and
observations, and reward/evaluation projection. The issue #15 manifest must not
claim those components early.

## Honest partial reproducibility

The first useful record is intentionally modest. It identifies the admitted
RAES scenario descriptor, selected CybORG source profile, backend manifest, and
realization envelope. That is already more reproducible than an unrecorded
direct constructor call.

The native Scenario2 file is qualification evidence, not the adapter's runtime
scenario. Construction is a deterministic projection of admitted RAES
resources:

- each `network` compiled from a RAES switch becomes one CybORG subnet;
- each `node` compiled from a RAES VM becomes one or more CybORG hosts
according to its admitted `count`;
- RAES infrastructure links become CybORG subnet memberships; and
- Linux and Windows OS-family requests select the pinned
`linux_decoy_host` and `windows_user_host1` image definitions.

The projection uses the complete desired resource set, never a fixed native
scenario selected behind one descriptor. Two different admitted topologies
therefore produce different native scenario documents. Count expansion is
bounded normalization (`host` becomes `host-0`, `host-1`, ... when count is
greater than one). CybORG 2.1 allocates private CIDRs itself, so authored
network addresses are descriptor-substituted rather than falsely reported as
exact. Image selection is an explicit default/image substitution.

The realization envelope binds those transformations, the selected source
profile, the mapping version, and the configured seed into its configuration
digest. It marks resource allocation, content, accounts, feature bindings,
services, and ACL realization unsupported.
Requests for explicit images, OS versions, resource allocations, asset values,
runtime state, services, features, accounts, ACLs, or unattached hosts reject
before native construction rather than being silently dropped. Constructor
success is not action, observation, replay, scoring, or outcome-equivalence
evidence.

## Configuration and source checks

Target configuration is closed. The adapter validates the selected profile id,
source commit, simulator version, mapping-ledger resource, bounded seed,
realization-envelope identity, compiled resource shapes, link closure, native
name uniqueness, and supported semantic subset before native construction.

The default driver imports only the fixed `CybORG` package surface. It does not
accept an import path, caller-supplied native scenario path,
environment-selected revision, runtime download, subprocess, or secret. Before
import it verifies the complete Python source tree and every selected runtime
file—including the image catalogue and selected images—against qualification
digests. It then copies the package into a private runtime snapshot while
excluding installed bytecode and native import artifacts, verifies the copied
source and selected data again, and imports from that snapshot. Python therefore
executes the bytes whose identity was checked rather than an unverified cache.
The driver writes the generated scenario as a private canonical JSON document
accepted by CybORG's YAML loader, constructs synchronously, and deletes the
document immediately afterward.

CybORG 2.1 uses Python's process-global random generator while building native
subnets and addresses. Construction therefore runs under a backend-local lock,
seeds before the constructor when configured, repeats the seed before reset,
and restores the caller's global random state. An unseeded target is explicitly
identified as unseeded in the realization envelope.

## Atomic ownership and cleanup

CybORG is one aggregate in-process backend, not one native object per RAES plan
operation. The Provisioner interprets the complete desired state and performs
one prepare/replace transition under a lock.

- Validation completes before construction.
- `UNCHANGED` does not create another backend.
- A failed construction leaves the baseline snapshot unchanged.
- Replacement publishes the candidate only after old-state cleanup succeeds.
- A candidate whose compensation fails remains privately owned for retry.
- A failed old-state cleanup marks that backend unavailable; an unchanged apply
cannot report it healthy and instead must complete cleanup and reconstruct the
desired state.
- Mixed deletes and updates rebuild from the complete desired state; removed
resources cannot survive through a stale aggregate descriptor.
- Delete removes the aggregate backend only when the desired state is empty.
- Repeated cleanup is harmless and retries previously unconfirmed cleanup.

Portable snapshots, results, receipts, diagnostics, stores, and logs may
contain only published RAES values and bounded adapter messages. Native
handles, ids, tuples, arrays, object representations, paths, logs, exception
text, and tracebacks remain process-private.

## Manifest evidence

The backend uses published RAES `BackendManifest`,
`BackendRealizationEnvelopeModel`, `ProvisionerCapabilities`,
`RealizationSupportDeclaration`, and `ConceptBinding` types. It publishes
through `backend_manifest_v2_model`/`backend_manifest_payload`; there is no
parallel schema or serializer.

The manifest is provisioning-only and names only contract versions exercised
by the target/control-plane path. Tests validate the rendered
`backend-manifest-v2`, SDL-to-plan-to-native differential projection, count and
link preservation, every configuration rejection, fail-closed lossy facts,
seed-bound identity, temporary-document deletion, snapshot portability,
construction/cleanup lifecycle, failed compensation, and source-installed
default-driver smoke. Stronger claims arrive only with their executable
evidence.
26 changes: 17 additions & 9 deletions docs/decisions/cyborg-cage2-runtime-qualification-guardrails.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,16 @@
# CybORG/CAGE-2 runtime qualification guardrails
# CybORG/CAGE-2 backend qualification guardrails

Issue #12 is the authority for the qualification outcome. This note fixes the
repository and contract boundaries that outcome must respect; it does not select
an upstream revision, define a runtime-profile schema, or describe an
implementation plan.

Maintainer selection admits the CybORG backend. Qualification grades the
selected source, installation path, controls, known losses, and attainable
reproduction claims; it does not veto adapter implementation. A source-installed
backend can be supported while automatic installation through the optional
extra remains unavailable.

## Keep the source closure coherent

The CAGE Challenge 2 repository contains a bundled `CybORG/` source tree,
Expand Down Expand Up @@ -64,10 +70,12 @@ root license is not by itself evidence that every nested or separately sourced
asset can be redistributed. Dependency licenses and notice obligations remain
part of the resolved profile.

The `cyborg` extra must be installable from the published `raes-adapters`
artifact on the declared Python/platform boundary. A successful editable
checkout, local path dependency, floating branch or tag, install-time clone, or
warm user cache is not that proof. If official source cannot produce a
If the `cyborg` extra is populated and advertised as an automatic installation
route, it must be installable from the published `raes-adapters` artifact on the
declared Python/platform boundary. A successful editable checkout, local path
dependency, floating branch or tag, install-time clone, or warm user cache is
not proof of that packaging claim. Keeping the extra empty does not prohibit
the documented source-install route. If official source cannot produce a
publishable immutable dependency, any governed repackaging or maintained fork
must preserve notices and bind:

Expand Down Expand Up @@ -119,10 +127,10 @@ the portability claim of the RAES contracts themselves.
| Durable state | RAES `ControlPlaneStore` | Qualification uses checked-in immutable evidence and explicit ephemeral temporary directories; it introduces no database, cache authority, or evidence repository. |
| Workflow gates | the `policy`, `typecheck`, `tests`, `distributions`, `docs`, and `verify` nox sessions | Keep one canonical graph. Any new CI job would also have to join the `PR Gate` `needs` contract, so qualification belongs in the existing sessions unless isolation cannot otherwise be achieved. |

The release workflow already installs the public
`raes-adapters[cyborg]` artifact on Python 3.12. It remains the public-index
check; source qualification and clean built-wheel smoke belong in the canonical
nox graph, not a second release path.
The release workflow installs the public `raes-adapters[cyborg]` artifact on
Python 3.12. While the extra is empty, that is a distribution-isolation check,
not a claim that it installs CybORG. Source qualification and clean built-wheel
smoke belong in the canonical nox graph, not a second release path.

## Native smoke and observability boundary

Expand Down
8 changes: 4 additions & 4 deletions docs/decisions/cyborg-cage2-source-ledger-guardrails.md
Original file line number Diff line number Diff line change
Expand Up @@ -206,9 +206,9 @@ contract catalog.
Any affected mapped fact must retain a source row and an appropriately tiered
loss.
- Do not let a mapped row, a complete ledger, a green validator, or a source
digest upgrade the qualification's `not-admissible` decision or imply an
installable extra, backend support, deterministic replay, or outcome
equivalence.
digest imply an installable extra, implemented backend capability,
deterministic replay, or outcome equivalence. Backend admission comes from
maintainer selection; each stronger claim still requires its own evidence.
- Do not put semantic values into free-form metadata, `mapping_rule`,
`verification`, comments, logs, or Markdown because the intended RAES target
is inconvenient.
Expand All @@ -226,5 +226,5 @@ contract catalog.
- No native simulator execution, hidden-state capture, raw log retention,
environment scan, privileged host operation, or runtime network service is
added for ledger validation.
- No existing qualification blocker, known defect, legal conclusion, source
- No existing qualification limitation, known defect, legal conclusion, source
revision, or equivalence claim is changed merely to make the mapping easier.
7 changes: 4 additions & 3 deletions docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ concrete simulator backends to published RAES contracts. It ships shared base
plumbing plus backend modules whose dependencies can live behind separate
extras in one lock once qualified. The reserved `cyborg` extra remains empty
because the selected upstream source needs an unpublished packaging fix.
Backend-local qualification evidence ships fail-closed without making the
native simulator a base dependency.
The maintainer-admitted backend is supported through its documented source
installation without making the native simulator a base dependency.

The shared `raes_adapters.base` module provides plumbing only. RAES remains the
semantic and protocol authority.
Expand All @@ -16,8 +16,9 @@ semantic and protocol authority.
- [Repository overview](https://github.com/RAESystem/adapters#readme)
- [Contribution guide](https://github.com/RAESystem/adapters/blob/dev/CONTRIBUTING.md)
- [Architecture decisions](decisions/adrs/README.md)
- [CybORG/CAGE-2 runtime qualification guardrails](decisions/cyborg-cage2-runtime-qualification-guardrails.md)
- [CybORG/CAGE-2 backend qualification guardrails](decisions/cyborg-cage2-runtime-qualification-guardrails.md)
- [CybORG/CAGE-2 source-ledger guardrails](decisions/cyborg-cage2-source-ledger-guardrails.md)
- [CybORG/CAGE-2 provisioner and backend-manifest guardrails](decisions/cyborg-cage2-provisioner-manifest-guardrails.md)
- [CyberBattleSim qualification guardrails](decisions/cyberbattlesim-qualification-guardrails.md)
- [CyberBattleSim scenario and source-ledger guardrails](decisions/cyberbattlesim-scenario-ledger-guardrails.md)
- [Project services](maintainers/project-services.md)
Expand Down
3 changes: 2 additions & 1 deletion mkdocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,9 @@ nav:
- Overview: decisions/adrs/README.md
- Template: decisions/adrs/TEMPLATE.md
- Shared simulator-adapter plumbing guardrails: decisions/base-plumbing-guardrails.md
- CybORG/CAGE-2 runtime qualification guardrails: decisions/cyborg-cage2-runtime-qualification-guardrails.md
- CybORG/CAGE-2 backend qualification guardrails: decisions/cyborg-cage2-runtime-qualification-guardrails.md
- CybORG/CAGE-2 source-ledger guardrails: decisions/cyborg-cage2-source-ledger-guardrails.md
- CybORG/CAGE-2 provisioner and manifest guardrails: decisions/cyborg-cage2-provisioner-manifest-guardrails.md
- CyberBattleSim qualification guardrails: decisions/cyberbattlesim-qualification-guardrails.md
- CyberBattleSim scenario and source-ledger guardrails: decisions/cyberbattlesim-scenario-ledger-guardrails.md
- ADR 003 — Single distribution and Trusted Publishing: decisions/adrs/adr-003-single-distribution-and-trusted-publishing.md
Expand Down
10 changes: 5 additions & 5 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -36,11 +36,10 @@ classifiers = [
dependencies = ["raes==2.0.0"]

[project.optional-dependencies]
# Reserved CybORG backend key. Issue #12 found the official CAGE-2 source
# runnable only after a packaging-data patch that has no governed public
# artifact. Keep the extra empty rather than publish an editable checkout,
# install-time clone, or ungoverned wheel; the backend-local qualification
# record carries the exact source, patch, dependency, and smoke evidence.
# Reserved CybORG backend key. The selected backend is supported through the
# documented source-install route. Issue #12 found the official wheel needs a
# packaging-data patch that is not yet published, so the extra remains empty
# instead of hiding that installation limitation behind a runtime clone.
cyborg = []

[project.urls]
Expand Down Expand Up @@ -99,6 +98,7 @@ mypy_path = ["src"]
[tool.pytest.ini_options]
testpaths = ["tests"]
addopts = "-q"
pythonpath = ["."]

[tool.coverage.run]
branch = true
Expand Down
Loading
Loading