decision-scope
What a claim declares about its own boundary, and whether that declaration holds up.
uv tool install decision-scope
decision-scope check manifests/ # before a run: do its declarations contradict?
decision-scope score audits/ # after: what does the record settle?
An evaluation result is produced under a particular model version, task distribution, operating environment, and measurement procedure. It is then used elsewhere — in a deployment decision, a safety report, a regulatory filing. That use assumes the conditions under which the result was obtained still describe the setting where it is applied.
This separates three operations over those conditions. A declaration states the condition. A check compares it against the artifacts that produced the evidence. A verification measures whether it holds where the result is used.
Before a run
A run is launched with a boundary, a configuration, and a task. All three are values the operator holds at launch, so a contradiction between them is decidable before execution.
decision-scope check examples/manifests/
DL-v1 containment FAIL the task requires reaching 10.20.5.7, which the
declaration places out of scope via 10.20.0.0/16;
task and declaration cannot both be satisfied
DL-v2 containment pass named as an explicit carve-out
safety-eval configuration FAIL results are reported under sha256:9f2c1ab4e7d05836
but the run was provisioned as sha256:41bd7e0c9a3f5528
Exit status is 1 when any predicate is unsatisfiable, so it gates a launch.
A manifest is YAML, written from values the harness already holds:
run_id: DL-v1
boundary:
in_scope: ["10.10.1.0/24", "10.10.2.0/24", "10.10.3.0/24"]
out_of_scope: ["10.20.0.0/16"]
carve_out: []
configuration:
declared: sha256:9f2c1ab4e7d05836
actual: sha256:9f2c1ab4e7d05836
task:
required_hosts: ["10.20.5.7"]
Every field is optional. A predicate with nothing to compare reports itself as unchecked
rather than passing, so an empty manifest cannot read as a clean run.
After the fact
A scorecard records one published claim at every cell of the lattice.
decision-scope score examples/scorecards/
Prep. [documentation] ok
METR [documentation] ok
Polyg. [documentation] ok
Mythos [documentation] ok
AISI [documentation] ok
5 scorecard(s), 0 with problems
Stage Cells D PD DA F U N/A N/R
--------------------------------------------------------------
declare 30 20 5 5
check 30 5 1 12 5 2 5
verify 30 1 2 21 1 5
declare satisfied: 20 of 30
check satisfied: 0 of 30
verify satisfied: 0 of 30
The operations are ordered, so a dimension whose declaration failed has unreachable rather
than failed cells below it. score enforces that in both directions: a failed declaration
requires N/R below it, and N/R is refused wherever the declaration did not fail.
decision-scope table emits the same matrix as a LaTeX tabular, with the satisfied counts
recomputed from the cells rather than written by hand.
The lattice
| Dimension | The condition it states |
|---|---|
| Referent | What is being claimed, and under what rule it is the same thing elsewhere |
| Claim form and unit | The form of the assertion and the unit it is counted in |
| Population | The population the result was measured over |
| Operating envelope | The environment the result was produced in |
| Version | The versions of model, task suite, and instrument in force |
| Measurement relation | How the assay relates to the target it stands for |
| Status | Meaning |
|---|---|
D |
Satisfied by the published record |
PD |
Performed in prose, not recorded as a separable artifact |
DA |
The auditor's argument substitutes for the operation |
F |
Nothing in the record performs the operation |
U |
Unassessable at the audit's access tier |
N/A |
Inapplicable to this claim type |
N/R |
Unreachable, because the dimension's declaration failed |
decision-scope lattice prints this.
As a library
from pathlib import Path
from decision_scope import load_scorecard, audit, totals
cards = [load_scorecard(p) for p in Path("audits").glob("*.yaml")]
problems = [p for card in cards for p in audit(card)]
print(totals(cards)["check"].satisfied)
Files become models at the edge, so a malformed card raises CardFileError naming the file
and the field rather than a KeyError from somewhere the caller cannot see. --json on
check and score emits the same values for a harness that does not want to import.
What it will not do
It cannot detect a declaration that is well-formed and false. A manifest records what the operator declared and provisioned, which makes it accurate about the evaluation and silent about the world the evaluation ran in.
Claude Code plugin
/plugin marketplace add elliottower/decision-scope
/plugin install decision-scope@decision-scope
Development
uv run --with pydantic --with pyyaml --with pytest python -m pytest tests/
License
MIT
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file decision_scope-0.2.0.tar.gz.
File metadata
- Download URL: decision_scope-0.2.0.tar.gz
- Upload date:
- Size: 19.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
1ab02136a6005ee316bfb2ae7b15729f9485b7a072f8f275681b433c3fa64d3c
|
|
| MD5 |
56455db9d32a154296816c1e0e020973
|
|
| BLAKE2b-256 |
120ec608b5acbb71edb46b1b01728850b813b77c0d9dd7369680485990aba2c4
|
Provenance
The following attestation bundles were made for decision_scope-0.2.0.tar.gz:
Publisher:
publish.yml on elliottower/decision-scope
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
decision_scope-0.2.0.tar.gz -
Subject digest:
1ab02136a6005ee316bfb2ae7b15729f9485b7a072f8f275681b433c3fa64d3c - Sigstore transparency entry: 2586487601
- Sigstore integration time:
-
Permalink:
elliottower/decision-scope@af95e109db1125d421d6fca37260689d2019da03 -
Branch / Tag:
refs/tags/v0.2.0 - Owner: https://github.com/elliottower
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@af95e109db1125d421d6fca37260689d2019da03 -
Trigger Event:
release
-
Statement type:
File details
Details for the file decision_scope-0.2.0-py3-none-any.whl.
File metadata
- Download URL: decision_scope-0.2.0-py3-none-any.whl
- Upload date:
- Size: 17.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
0ba97c9732170a416d41743182e94fd05fe2573362b77a4efd62a2b54d19c3f0
|
|
| MD5 |
a7398ceba50356765a38488d3df27662
|
|
| BLAKE2b-256 |
407238da12847c4a490098bbfb5733fa6c481a6e359f2ef9dd51813b00d5d17d
|
Provenance
The following attestation bundles were made for decision_scope-0.2.0-py3-none-any.whl:
Publisher:
publish.yml on elliottower/decision-scope
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
decision_scope-0.2.0-py3-none-any.whl -
Subject digest:
0ba97c9732170a416d41743182e94fd05fe2573362b77a4efd62a2b54d19c3f0 - Sigstore transparency entry: 2586488140
- Sigstore integration time:
-
Permalink:
elliottower/decision-scope@af95e109db1125d421d6fca37260689d2019da03 -
Branch / Tag:
refs/tags/v0.2.0 - Owner: https://github.com/elliottower
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@af95e109db1125d421d6fca37260689d2019da03 -
Trigger Event:
release
-
Statement type: