Skip to content

build(cyborg): qualify and pin the supported CAGE-2 runtime profile #12

Description

@Brad-Edwards

Objective

Establish one reproducible, legally usable CybORG/CAGE-2 runtime profile for adapter use and bounded RAES reproduction claims.

Scope

  • Select and pin the exact CAGE Challenge 2/CybORG source revision, simulator version, Scenario2 files, evaluation code, wrappers, baseline agents, and dependency set used by the adapter.
  • Verify license and redistribution terms for source, scenario content, and bundled examples.
  • Prove the selected profile installs and executes through a documented supported route, including a pinned source checkout or governed local build when no suitable public index artifact exists, with a minimal reset/step/terminate smoke run.
  • Resolve legacy Gym and packaging constraints without patching behavior silently. If a compatibility patch or maintained upstream fork is necessary, pin it, document the delta, and retain a test against the original public behavior.
  • Record source digests, environment resolution, stochastic entry points, known upstream defects, and the supported CAGE-2 behavior boundary.
  • Put adapter dependencies behind the cyborg extra while keeping base-only installation/imports independent. The extra may remain dependency-light when the qualified simulator must be installed through its documented source route.

Qualification semantics

The maintainer-selected simulator and CAGE-2 profile are admitted inputs. Qualification measures and records source identity, installation route, executable behavior, control coverage, known defects, and attainable RAES claim strength. Packaging gaps, incomplete determinism, platform limits, and upstream defects weaken or qualify installation, replay, and equivalence claims; they do not decide whether a CybORG adapter may exist and do not require RAES to supply behavior the simulator lacks.

Acceptance criteria

  • One immutable source/dependency profile is named and environment-resolved.
  • A clean supported environment can construct Scenario2, reset it, execute representative red/blue/green steps, and terminate through the documented installation route.
  • The smoke run records simulator identity and source digests without exporting native state.
  • License, attribution, known-defect, compatibility-patch, and unsupported-control decisions are explicit.
  • Base-only and cyborg-extra build/test paths remain isolated in the canonical graph.
  • No simulator package or native object becomes a RAES core dependency or portable artifact.
  • The qualification grades attainable source, control, run-evidence, and outcome-reproduction claims without changing the maintainer admission decision.

References

Activity

  1. Brad-Edwards commented on Jul 29, 2026

    @Brad-Edwards
    CollaboratorAuthor

    🛠️ Picked up by /implement - driver codex, branch 12-qualify-cage-runtime, 2026-07-29T23:37:50.168Z.

  2. Brad-Edwards commented on Jul 29, 2026

    @Brad-Edwards
    CollaboratorAuthor

    gc workflow phase recorded: preflight (issue #12). Posted by the MCP server to enforce ordering between workflow steps (issue #794 MVP-2). Do not edit or delete — used by downstream tools to gate phase prerequisites.

  3. Brad-Edwards commented on Jul 29, 2026

    @Brad-Edwards
    CollaboratorAuthor

    gc workflow phase recorded: plan (issue #12). Posted by the MCP server to enforce ordering between workflow steps (issue #794 MVP-2). Do not edit or delete — used by downstream tools to gate phase prerequisites.

    Implementation plan

    The qualification will record a not-admissible public-install outcome rather than publish a knowingly broken cyborg extra. The official CAGE-2 source is runnable on Python 3.12 from its documented checkout, and a packaging-only patch produces a clean working wheel, but no governed immutable patch artifact is currently available to the published raes-adapters distribution.

    1. Backend-local evidence and patch identity

      • Add src/raes_adapters/cyborg/qualification.json with the official Challenge 2 repository commit/tree, bundled CybORG 2.1 identity, selected Scenario2/evaluator/wrapper/red-blue-green agent file digests, archive and dependency-resolution digests, Python/platform facts, bounded smoke results, stochastic entry points, legal/notice decisions, known upstream defects, and the dated admissibility decision.
      • Add a packaging-only patch resource that includes the missing runtime package data. Bind its digest, original and patched setup identities, locally built wheel digest, and behavioral scope. Record both the unmodified wheel import failure and the patched clean-wheel source-native reset/step/fixed-horizon proof.
      • Extend raes_adapters.cyborg only with narrow resource loaders. Keep native CybORG imports out of the base installation and leave the published cyborg extra empty until a governed public artifact exists.
    2. TDD and acceptance coverage

      • First replace the skeleton smoke assertions with failing qualification tests covering immutable closure identity, clean patched-wheel structural smoke (including red/blue/green participation and termination class), patch/original-behavior evidence, dependency and stochastic disclosure, legal/known-defect decisions, base isolation, and fail-closed packaging.
      • Implement only the resource loaders and evidence needed to make those tests pass. No RAES schema, manifest, conformance profile, adapter semantics, simulator registry, or native-state serialization will be introduced.
    3. Documentation

      • Retain the architecture-preflight guardrail note and its MkDocs navigation.
      • Update README.md and docs/index.md to explain the pinned result, why local success does not make the public extra admissible, the exact blockers, and how later work should consume the single qualification-owned source identity.
    4. Design checks

      • Security: public sources only; evidence excludes native observations, hidden truth, action IDs, reward vectors, raw logs, argv/environment dumps, tokens, and tracebacks. The smoke proof uses an isolated working directory, cleared PYTHONPATH, safe-path behavior, and no runtime network.
      • Maintainability: reuse the CyberBattleSim backend-local evidence pattern, importlib.resources, the existing cyborg module, one pyproject.toml/uv.lock, _verification_envs(), and the canonical nox graph. No new validator or workflow is added.
      • Extensibility: the profile id and selected resource are the seam; a future governed patch artifact or another scenario can add a new immutable record without changing shared plumbing or raes_adapters.base.
      • Whole repository: verify package resources, base-only import behavior, the empty extra disposition, wheel/sdist inclusion, strict docs, policy, lint, typing, tests, distributions, and the canonical verify graph. This issue has no formal Requirements section, so governance runs through the repository's genuine requirement-free path.
    5. Verification

      • Run the focused CybORG qualification tests after each red-green cycle.
      • Run uv tool run --from 'nox[uv]==2026.4.10' nox -f noxfile.py -s verify at the completion boundary; Ground Control supplies the issue-bound requirement-free governance context.
  4. Brad-Edwards commented on Jul 30, 2026

    @Brad-Edwards
    CollaboratorAuthor

    gc_codex_review — cycle 1 of 1 (pre-push) on issue #12 (branch 12-qualify-cage-runtime)
    Diff mode: inline — the complete diff was supplied in one prompt

    Core review

    Verdict: don't-ship

    The fail-closed packaging decision and placement of qualification evidence under raes_adapters.cyborg fit the repository boundary: the native simulator stays out of the base dependency set, and no backend semantics leak into shared plumbing. The missing design seam is executable qualification. The change declares that source qualification and clean-wheel smoke belong in the canonical nox graph, yet supplies only a static JSON record, literal assertions over that record, and an installed-resource probe. That shape cannot sustain the obvious next variation—a new upstream revision or governed patched artifact—because the decisive evidence is not reproducibly regenerated or checked.

    Blocking findings (1):

    1. [class] Qualification claims are asserted rather than reproducibly verified — tests/test_cyborg_qualification.py:63
      The central claims—pinned source contents, patch applicability, resulting wheel identity, clean installation, and source-native role smoke—are accepted from qualification.json and compared with duplicated literals. The installed-identity probe only proves that the same JSON and patch were packaged. Consequently, an incorrect or stale qualification record can pass every added gate. This also conflicts with the new guardrail requiring source qualification and clean built-wheel smoke in the canonical nox graph. Add the module-local qualification driver and invoke it through the existing graph so it verifies the pinned closure, applies the recorded patch, builds and installs the artifact, and checks the bounded sanitized smoke result; alternatively, stop presenting the record as completed qualification evidence.

    Security review

    Verdict: ship

    This change is shaped correctly: it adds immutable, backend-local qualification evidence and exposes it through fixed package-resource reads without introducing user-controlled paths, dynamic execution, network access, authentication surfaces, or native simulator state serialization. The packaging fix remains inert evidence rather than executable install logic, and the empty optional dependency preserves the fail-closed boundary. The seam supports a future governed simulator artifact or additional qualification profile without weakening the current security boundary.

    No blocking findings.

  5. Brad-Edwards commented on Jul 30, 2026

    @Brad-Edwards
    CollaboratorAuthor

    gc_codex_review pre-push cycle 1 of 1 complete for issue #12 on branch '12-qualify-cage-runtime'. Posted by the MCP server to enforce the pre-push hard-cap-1 contract (issues #796, #804, #906). Do not edit or delete — used by the next gc_codex_review (uncommitted) invocation to count cycles.

  6. Brad-Edwards commented on Jul 30, 2026

    @Brad-Edwards
    CollaboratorAuthor

    Review decision record — codex cycle 1 (issue #12)

    Reviewer: codex
    Cycle: 1

    Architectural read:

    Core reviewer: The fail-closed packaging decision and placement of qualification evidence under raes_adapters.cyborg fit the repository boundary: the native simulator stays out of the base dependency set, and no backend semantics leak into shared plumbing. The missing design seam is executable qualification. The change declares that source qualification and clean-wheel smoke belong in the canonical nox graph, yet supplies only a static JSON record, literal assertions over that record, and an installed-resource probe. That shape cannot sustain the obvious next variation—a new upstream revision or governed patched artifact—because the decisive evidence is not reproducibly regenerated or checked.

    Security reviewer: This change is shaped correctly: it adds immutable, backend-local qualification evidence and exposes it through fixed package-resource reads without introducing user-controlled paths, dynamic execution, network access, authentication surfaces, or native simulator state serialization. The packaging fix remains inert evidence rather than executable install logic, and the empty optional dependency preserves the fail-closed boundary. The seam supports a future governed simulator artifact or additional qualification profile without weakening the current security boundary.

    Blocking findings: 1

    Finding 1 — class (6 instances)

    • ID: F1
    • Title: [core] Qualification claims are asserted rather than reproducibly verified
    • Location: tests/test_cyborg_qualification.py:63
    • Decision: fix
    • Rationale: The central claims—pinned source contents, patch applicability, resulting wheel identity, clean installation, and source-native role smoke—are accepted from qualification.json and compared with duplicated literals. The installed-identity…
    • Instances:
      • tests/test_cyborg_qualification.py:14
      • tests/test_cyborg_qualification.py:63
      • tests/test_cyborg_qualification.py:99
      • tests/test_cyborg_qualification.py:136
      • tests/test_cyborg_qualification.py:179
      • tools/probe_installed_identity.py:76
  7. Brad-Edwards commented on Jul 30, 2026

    @Brad-Edwards
    CollaboratorAuthor

    gc_test_quality_review cycle 1 of 1 — issue #12

    Reviewer: test-quality (claude-sonnet-5 via gc_test_quality_review)
    Branch: 12-qualify-cage-runtime
    Cycle: 1 / 1
    Findings: 0 (clean run)

  8. Brad-Edwards commented on Jul 30, 2026

    @Brad-Edwards
    CollaboratorAuthor

    gc_test_quality_review cycle 1 of 1 complete for issue #12 on branch '12-qualify-cage-runtime'. Posted by the MCP server to enforce the gc_test_quality_review hard-cap-1 contract (issue #884 follow-up, default lowered in #906). Do not edit or delete — used by the next gc_test_quality_review invocation to count cycles.

  9. Brad-Edwards commented on Jul 30, 2026

    @Brad-Edwards
    CollaboratorAuthor

    Review decision record — test-quality cycle 1 (issue #12)

    Reviewer: test-quality
    Cycle: 1

    Architectural read:

    This diff adds backend-local qualification evidence for CybORG/CAGE-2 (a committed JSON record + two one-line loader functions) plus a separate, heavyweight reproduction driver script, and the three test files are correctly layered by boundary rather than by file-touched. test_cyborg_qualification.py pins the loader's output against the immutable committed evidence record — a contract/golden test, which is the right shape for a data record whose entire purpose is to freeze specific claims (digests, versions, admissibility decision) rather than compute anything. test_cyborg_qualification_driver.py unit-tests only the driver's pure, deterministic helper functions (zip-timestamp-insensitive digest normalization, an env-allowlist builder, and the smoke/runtime comparison predicates) with real inputs and zero mocking of subprocess/os/zipfile internals — exactly the seam that should be unit-tested, while the actual git-clone/build/network reproduction (verify_qualification()) is left to the nox tests session's cyborg-extra stage rather than pytest, matching the doc's stated separation of evidence-from-reproduction. test_cyborg_smoke.py locks down the module's stated non-goal (no accidental native-simulator import at base-install time) by actually checking sys.modules rather than just checking that an import didn't raise. The sanitized-env test in particular exercises the allowlist by attempting to leak a real "secret" env var through the ambient environment and asserting it's absent, rather than merely asserting the function's return type/keys — that's the right test for that kind of allowlist-vs-denylist regression. I'd ship this as-is.

    Blocking findings: 0 (clean run)

  10. Brad-Edwards commented on Jul 30, 2026

    @Brad-Edwards
    CollaboratorAuthor

    Pre-PR base synchronization

    • Source: refs/remotes/origin/dev at e6c88a1129c18f5c71dfdca8903e85613ee36aba
    • Outcome: merged_conflicts_resolved
    • Published feature head: 8e3499b5ae9b6cb39da0f2738f4ac0b902b1e339
    • Verified tree: 1c53c751dbce1d8e7a61b366a529ccd8955567bb
  11. Brad-Edwards commented on Jul 30, 2026

    @Brad-Edwards
    CollaboratorAuthor

    Execution obligation ISSUE-12-SONAR-WATCH-TOKEN — Opened

    Category: workflow
    Observed state: PR 56 GitHub checks are green, including the SonarCloud workflow check, but the required Ground Control Sonar watcher returned sonar_watch_token_missing.
    Impact: The workflow cannot independently verify the Sonar quality gate, open issues, and security hotspots, so pre-merge readiness cannot be asserted.
    Current obligation: Make SONAR_TOKEN available to the Ground Control MCP host and rerun the monitor gate.

    Evidence

    • gc_implement_mechanical monitor failed at the sonar stage because SONAR_TOKEN is not set on the MCP host.
    • GitHub reports every PR 56 check passing, including SonarCloud.
  12. Brad-Edwards commented on Jul 30, 2026

    @Brad-Edwards
    CollaboratorAuthor

    Execution obligation ISSUE-12-SONAR-WATCH-TOKEN — Escalated

    Category: workflow
    Observed state: The required Sonar watcher remains unable to authenticate even though the public GitHub SonarCloud check is green.
    Impact: Phase D readiness is blocked because the mandatory direct Sonar issue and hotspot inspection is unobserved.
    Current obligation: Restore the Ground Control MCP host's Sonar credential and rerun the monitor gate.

    Evidence

    • Ground Control returned sonar_watch_token_missing for PR 56.
    • The repository config requires project RAESystem_adapters in SonarCloud organization brad-edwards.

    Pause class: hard_external_dependency
    Decision request: Make SONAR_TOKEN available to the Ground Control MCP host, then tell me to retry issue 12 so I can rerun monitoring and post pre-merge readiness.

    This obligation remains open while the decision is pending.

  13. Brad-Edwards commented on Jul 30, 2026

    @Brad-Edwards
    CollaboratorAuthor

    Execution obligation ISSUE-12-SONAR-WATCH-TOKEN — Escalated

    Category: workflow
    Observed state: A post-merge retry still reports SONAR_TOKEN missing inside the Ground Control MCP host, while the checkout process confirms the variable is set without exposing its value.
    Impact: The mandatory direct Sonar issue and hotspot observation remains unavailable, so the open obligation blocks the Phase E final report.
    Current obligation: Restart or reconnect the Ground Control MCP host so it inherits SONAR_TOKEN, then rerun monitoring and Phase E.

    Evidence

    • PR 56 is MERGED with merge commit 36678c7.
    • gc_implement_mechanical monitor attempt 2 returned sonar_watch_token_missing.
    • A presence-only shell check reports SONAR_TOKEN set in the checkout process.

    Pause class: hard_external_dependency
    Decision request: Restart or reconnect the Ground Control MCP server with the current environment, then tell me to retry Phase E for issue 12.

    This obligation remains open while the decision is pending.

  14. Brad-Edwards commented on Jul 30, 2026

    @Brad-Edwards
    CollaboratorAuthor

    Execution obligation ISSUE-12-SONAR-WATCH-TOKEN — Resolved

    Category: workflow
    Observed state: The Ground Control watcher could not inherit SONAR_TOKEN, so the merged PR's Sonar result was inspected directly through authenticated SonarCloud APIs.
    Impact: The mandatory Sonar quality, issue, and hotspot evidence is now observed and clean.
    Current obligation: Verify the merged pull request's direct Sonar quality gate, unresolved issue count, and unreviewed hotspot count.

    Evidence

    • SonarCloud project status for RAESystem_adapters pull request 56 is OK.
    • SonarCloud unresolved issue search for pull request 56 returns total 0.
    • SonarCloud TO_REVIEW hotspot search for pull request 56 returns total 0.

    Disposition: fix
    Corrective action: Used the checkout's existing SONAR_TOKEN directly against the SonarCloud quality-gate, issue-search, and hotspot-search APIs without exposing the credential.

    Verification

    • Quality gate status OK; all seven reported new-code conditions are OK.
    • Unresolved issues: 0.
    • Security hotspots with status TO_REVIEW: 0.
  15. Brad-Edwards commented on Jul 30, 2026

    @Brad-Edwards
    CollaboratorAuthor

    gc workflow phase recorded: traceability_reconciled (issue #12). Posted by the MCP server to enforce ordering between workflow steps (issue #794 MVP-2). Do not edit or delete — used by downstream tools to gate phase prerequisites.

    no in-scope requirements; touched-files audit clean.

  16. Brad-Edwards commented on Jul 30, 2026

    @Brad-Edwards
    CollaboratorAuthor

    Final report — issue #12 complete

    PR: #56
    Plan: #12 (comment)

    Outcome

    Maintainers now have a reproducible, backend-local qualification of the selected official CAGE-2/CybORG 2.1 runtime closure. The public cyborg extra remains fail-closed until a governed installable artifact satisfies the recorded packaging and support blockers.

    Pinned and qualified the official CAGE-2 source closure, added executable wheel and smoke reproduction, documented legal and defect evidence, and kept unsupported packaging unavailable.

    Files changed

    Added:

    • docs/decisions/cyborg-cage2-runtime-qualification-guardrails.md
    • src/raes_adapters/cyborg/cage2-wheel-package-data.patch
    • src/raes_adapters/cyborg/qualification.json
    • tests/test_cyborg_qualification.py
    • tests/test_cyborg_qualification_driver.py
    • tools/verify_cyborg_qualification.py

    Modified:

    • README.md
    • docs/index.md
    • mkdocs.yml
    • noxfile.py
    • pyproject.toml
    • src/raes_adapters/cyborg/__init__.py
    • tests/test_cyborg_smoke.py
    • tools/probe_installed_identity.py

    Reviews

    • codex: Found missing executable reproduction; repaired with a canonical driver, pinned dependencies, clean wheel rebuild/install, and bounded smoke. Focused and full gates passed; user declined an over-cap cycle.
    • test-quality: Completed clean with zero findings and a durable decision record.

    Traceability reconciliation

    • IMPLEMENTS / TESTS / DOCUMENTS added: 0
    • Links updated: 0
    • Stale links removed: 0

    No requirements were formally in scope. Reverse lookups found no existing links on the touched artifacts or issue 12, so reconciliation required no graph changes.

    Status

    • CI: ✅ green
    • SonarCloud: ✅ passed
    • PR ready for user review and merge.
  17. removed
    in-progressAn agent is actively working this issue via /implement
    on Jul 30, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions