Simulation code and evaluation scripts for the paper:
Xue Qin, Simin Luan, John See, Zeyd Boukhers, Cong Yang, Zhijun Li. "Governed Capability Evolution: Lifecycle-Time Compatibility Checking and Rollback for AI-Component-Based Systems, with a Proof-of-Concept Evaluation on Embodied Agents." 2026. arXiv: 2604.08059
This repository contains the experiment code for evaluating governed capability evolution — a framework for safely upgrading AI capability modules through compatibility checking, sandbox testing, shadow execution, and rollback under runtime drift. The evaluation instantiates the framework on an embodied manipulation stack, in a behavioral simulation with a PyBullet physics backend that replicates the strategy ordering.
Upgrade candidates come from a seeded fault-operator generator (45 per capability family and seed, including out-of-taxonomy probes), and compatibility thresholds are calibrated on a disjoint development set. Both the generator and the calibration are in this repository.
| Experiment | Description |
|---|---|
| E1: Upgrade Screening | Compatibility checking detects faulty candidates (BADR, FAR) |
| E2: Performance-Safety | Task performance and safety across upgrade rounds, against static, naive, canary and blue-green baselines (SR, UAR, PVR) |
| E3: Shadow Effectiveness | Sandbox vs shadow detection complementarity |
| E4: Rollback Under Drift | Rollback success under runtime perturbations (RSR) |
| E5: Cross-Profile | Governance outcomes across three deployment profiles on paired dynamic evidence |
Python 3.11 or newer. Runtime dependencies are numpy, scipy (analysis) and
pybullet (physics backend only); matplotlib and pandas are used by optional plotting.
Install the declared ranges:
pip install -r requirements.txtTo reproduce the shipped results exactly, install the versions they were generated with instead:
pip install -r constraints-tested.txtThe shipped results were produced on Python 3.11.15 / NumPy 2.4.6 / SciPy 1.17.1 / PyBullet 3.2.5 (macOS, Apple silicon). The behavioral backend is deterministic and reproduces byte-for-byte across processes on that stack; timing measurements are hardware-dependent and are shipped as a fixed record rather than a reproducible artifact.
Regenerate the shipped behavioral results (all five experiments, 15 seeds). Note the
explicit --output-dir: the default is results/, while the shipped tree lives in data/.
python -m governed_upgrade.run_all --output-dir dataRun a subset of experiments. Write these to a scratch directory: the output file is named
after the backend, so a subset run pointed at data/ would overwrite the complete shipped
result with a partial one.
python -m governed_upgrade.run_all --experiments E1 E2 --output-dir /tmp/subsetRegenerate the PyBullet physics track. The shipped physics file contains E2 only, so pass the experiment set explicitly; this run is orders of magnitude slower than the behavioral backend because every task steps a physics simulation.
python -m governed_upgrade.run_all --experiments E2 --backend pybullet \
--output-dir data/pybullet_validationCompute every statistic the paper reports (paired Wilcoxon tests with Holm-Bonferroni correction, Wilson intervals, per-category and per-hook-state breakdowns):
python scripts/analyze_results.py data/experiment_results_simulated.json --out data/analysis_summary.jsonThe physics track has its own summary:
python scripts/analyze_results.py data/pybullet_validation/experiment_results_pybullet.json \
--out data/pybullet_validation/analysis_summary.jsonReproduce the sensitivity analyses (benign-heavy pool, policy-aware canary variant, threshold sweep, sandbox envelope sweep):
python scripts/run_sensitivity.py --out-dir dataRecalibrate the compatibility thresholds on the disjoint development set:
python scripts/calibrate_thresholds.pyRegenerate the pipeline ablation (per-candidate variant outcomes):
python scripts/run_ablation.py --out data/ablation_screening.jsonRe-measure the per-stage wall-clock overhead reported in the paper (twenty timed repetitions after a discarded warm-up; writes raw repetitions and environment metadata):
python scripts/benchmark_overhead.py --out-dir /tmp/overhead --repeats 20data/overhead_benchmark.json is a fixed record of the run the paper reports, so the command
above writes elsewhere by default. Timing is hardware- and load-dependent: a fresh run on
different hardware will not match it, and that is expected.
| Metric | Value |
|---|---|
| BADR, compatibility screening alone (E1) | 60.3% +/- 4.7% |
| FAR (E1) | 0.0% +/- 0.0% |
| Final-round SR (E2, governed) | 68.7% |
| Mean UAR over upgrade rounds (E2, governed) | 1.3% |
| Mean UAR over upgrade rounds (E2, canary / blue-green) | 61.3% / 64.0% |
| RSR under injected drift (E4) | 72.4% +/- 5.4% |
| In-taxonomy detection, full pre-activation stack (E5) | 97.3-100% across the three profiles |
E1 measures compatibility screening in isolation; the higher E5 figure is the full pre-activation stack (screening, sandbox, shadow, gated activation).
The experiment results are deterministic given the same 15 seeds and reproduce byte-for-byte across processes. The timing record is not: see the note under the benchmark command.
governed_upgrade/
├── run_all.py # Main entry point
├── config.py # Experiment configuration
├── compatibility/ # Compatibility checker (four dimensions)
├── ecm/ # ECM definitions, candidates, fault-operator generator
│ └── generator.py # Seeded fault operators and out-of-taxonomy probes
├── environment/ # Simulated and PyBullet environments
├── governance/ # Deployment profiles and the governance state model
├── metrics/ # Metric computation (BADR, FAR, UAR, SR, RSR, PVR)
├── pipeline/ # Upgrade pipeline stages
│ ├── sandbox.py # Sandbox execution
│ ├── shadow.py # Shadow execution
│ ├── activation.py # Activation control
│ ├── monitor.py # Online monitoring
│ └── rollback.py # Rollback manager
└── runners/ # Per-experiment runners (E1-E5)
scripts/
├── analyze_results.py # Every statistic reported in the paper
├── run_ablation.py # Pipeline ablation, per-candidate variant outcomes
├── run_sensitivity.py # Sensitivity analyses and baseline variants
├── benchmark_overhead.py # Per-stage wall-clock overhead, with raw repetitions
└── calibrate_thresholds.py # Threshold calibration on the development set
data/ # Shipped results. All but the timing record regenerate
# byte-for-byte from the commands above.
├── experiment_results_simulated.json
├── analysis_summary.json
├── ablation_screening.json
├── overhead_benchmark.json # Fixed record of the timing run the paper reports
├── sensitivity_*.json, threshold_sensitivity.json, sandbox_envelope_sensitivity.json
└── pybullet_validation/ # Physics track (E2 only)
Licensed under the Apache License, Version 2.0. See LICENSE for details.
@article{qin2026governed,
title={Governed Capability Evolution: Lifecycle-Time Compatibility Checking and Rollback for AI-Component-Based Systems, with a Proof-of-Concept Evaluation on Embodied Agents},
author={Qin, Xue and Luan, Simin and See, John and Boukhers, Zeyd and Yang, Cong and Li, Zhijun},
journal={arXiv preprint arXiv:2604.08059},
year={2026}
}