Metadata-Version: 2.4
Name: prior-release-controller
Version: 1.0.0
Summary: Auditable relative-Global granularity control for learner-conditioned prior release
License-Expression: MIT
Keywords: adaptive control,hybrid learning,prior release,risk estimation,robotics
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: Intended Audience :: Science/Research
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3 :: Only
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Typing :: Typed
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
Requires-Python: >=3.10
Description-Content-Type: text/markdown
License-File: LICENSE
Dynamic: license-file

# Prior-Release Controller

`prior-release-controller` is an auditable engineering implementation of a
relative-Global release-granularity controller. It chooses among Global,
Grouped, Diagonal, and Spectral release after comparing every refinement with
Global on the same prespecified independent evaluation units.

The package consumes frozen, cross-fitted risk summaries. It does not fit the
endpoint predictor, estimate a Spectral basis from selection outcomes, or
provide a universal uncertainty multiplier.

## Install

After the distribution is published:

```bash
python -m pip install prior-release-controller
```

For a local release candidate:

```bash
python -m pip install dist/prior_release_controller-1.0.0-py3-none-any.whl
```

## Decision rule

For candidate family `m`, define:

```text
paired_excess[m] = risk[m] - risk[Global]
radius[m]        = q * paired_standard_error[m]
```

The candidate is eligible only when:

```text
paired_excess[m] + radius[m] + safety_margin < 0
```

The radius is used once, for eligibility. Eligible candidates are ranked by
their paired point excess; a frozen complexity order breaks ties. If no
refinement passes, the controller returns Global.

## Calibration contract for `q`

`q` is required and must be strictly positive. The package deliberately has no
universal default. Before observing deployment outcomes, the caller must freeze
a multiplier or candidate-specific radius appropriate for:

- the desired one-sided error criterion;
- the number and dependence of candidate families;
- any repeated selection over budgets or conditions; and
- the prespecified resampling or calibration design.

A conventional single-comparison value such as `1.96` is not automatically a
joint guarantee after comparing several release families. If calibrated radii
are produced outside the package, supply `radius` directly. When both `radius`
and `paired_se` are present, the package verifies `radius = q * paired_se`.

`safety_margin` and `point_tolerance` use the same units as the reported risk.
The paired estimator's `scale_floor=0` default adds no finite-sample floor; a
nonzero floor must be frozen by the caller when required by the protocol.

## Python API

```python
import os

from prior_release_controller import CandidateEstimate, select_granularity

FROZEN_JOINT_Q = float(os.environ["PRIOR_RELEASE_Q"])  # prespecified policy value

common = {
    "n_units": 40,
    "risk_geometry_id": "shared-H-v1",
    "evaluation_id": "outer-folds-v1",
}
candidates = [
    CandidateEstimate("global", 0.0, paired_se=0.0, **common),
    CandidateEstimate("diagonal", -0.08, paired_se=0.01, **common),
    CandidateEstimate(
        "spectral", -0.10, paired_se=0.04, basis_frozen=True, **common
    ),
]

decision = select_granularity(
    candidates,
    q=FROZEN_JOINT_Q,
    condition_id="robot-A_n40",
)
print(decision.selected_family)
print(decision.policy_id)
print(decision.decision_id)
print(decision.to_json(indent=2))
```

When raw candidate and Global losses are available on the same independent
units, `candidate_from_paired_losses(...)` constructs a candidate summary. Do
not treat autocorrelated rows as independent units; use prespecified complete
trajectories, sessions, subjects, or blocks.

## Batch CLI

```bash
prior-release-controller decide \
  --input candidates.csv \
  --decisions decisions.csv \
  --audit audit.jsonl \
  --q "$PRIOR_RELEASE_Q"
```

The CLI is strict by default:

- input, decision, and audit paths must be pairwise distinct;
- existing outputs are not replaced unless `--overwrite` is explicit;
- outputs are staged in their destination directories and atomically replaced;
- candidate contract exclusions produce status `3` after audit files are written;
- `--allow-contract-errors` explicitly accepts candidate-level exclusions; and
- all JSON is emitted with strict finite-number semantics.

The compact CSV is intended for orchestration. JSONL contains the complete
candidate trace. Both include `controller_version`, full `policy_id`, and full
`decision_id`. Exact columns are documented in `docs/CSV_SCHEMA.md`.

## Safety boundary

- Global is mandatory, admissible, and has zero paired excess.
- All candidates share the same independent units, risk geometry, and evaluation ID.
- At least two independent units are required.
- Spectral is ineligible unless its basis was frozen before outer-risk evaluation.
- Numeric inputs must be finite; Boolean assertions must be actual Boolean values.
- Missing, inconsistent, or incomparable refinements are removed and audited.
- No eligible refinement means an explicit Global fallback.

These are software-contract checks, not a physical-system safety certificate.
The package cannot prove that a caller truthfully cross-fitted predictions,
prespecified independent units, or froze a learned basis.

## Schemas and verification

Versioned schemas are bundled in the wheel:

```python
from prior_release_controller import load_schema

decision_schema = load_schema("decision")
candidate_schema = load_schema("candidate_estimate")
```

Run the complete source-distribution audit with:

```bash
python -m unittest discover -s tests -v
python scripts/verify_release.py
```

The tests include a seeded 10,000-case differential comparison with the frozen
point-after-gate rule and exact replay of all 20 archived Berkeley UR5 Stage-A
task-by-budget decisions.

The replay establishes software equivalence to the stored decision kernel. It
is not an independent scientific replication, prospective hardware
confirmation, or general safety certificate. The full boundary statement is in
`docs/EVIDENCE_BOUNDARY.md`.

## Anonymous review status

Author, maintainer, manuscript, DOI, citation, and identifying project-link
metadata are intentionally omitted during double-blind review. This omission is
tracked in `ANONYMITY.md` and must be resolved before a named archival release.

## License

MIT. See `LICENSE`.
