Skip to content

Commit cc28cdc

Browse files
committed
Add project-level contract policy support and related documentation
Introduce a new contract policy feature allowing project-level contract pinning and deprecation controls. Update README.md to include usage examples and details on the contract policy schema. Enhance CI workflows to verify contract policy examples and add new configuration files for contract policies. Update analysis and report schemas to incorporate contract policy decisions, ensuring better handling of deprecated contracts. Adjust documentation to reflect these changes and improve clarity on contract management processes.
1 parent 4b2435d commit cc28cdc

22 files changed

Lines changed: 904 additions & 34 deletions

.github/workflows/schema-contract.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,3 +36,6 @@ jobs:
3636
3737
- name: Verify compatibility manifest
3838
run: sh scripts/ci/check-compatibility-manifest.sh
39+
40+
- name: Verify contract policy fixtures
41+
run: sh scripts/ci/check-contract-policy-example.sh

README.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,12 @@ sheaft run --model <artifact.json> --analysis configs/analysis.example.yaml --ou
3232
sheaft serve --config configs/sheaft.example.yaml
3333
```
3434

35+
Project-level contract pinning can be added on top:
36+
37+
```bash
38+
sheaft run --model <artifact.json> --analysis configs/analysis.example.yaml --contract-policy configs/contract-policy.example.yaml --out-dir out
39+
```
40+
3541
## Supported Upstream Contracts
3642

3743
Sheaft validates artifacts against an explicit whitelist.
@@ -43,6 +49,7 @@ Pinned URIs, digests, and release-line support are tracked in [docs/compatibilit
4349
The machine-readable compatibility contract is [compatibility-manifest.json](compatibility-manifest.json).
4450

4551
Unknown contracts are rejected with an error that lists the supported contracts. There is no silent fallback for unsupported upstream schemas.
52+
Project-level narrowing and deprecation behavior can be layered on top with `--contract-policy` or inline `contract_policy` config.
4653

4754
## Quickstart
4855

@@ -150,6 +157,7 @@ docs architecture, methodology, migration, and config docs
150157
- [Architecture](docs/architecture.md)
151158
- [Methodology](docs/methodology.md)
152159
- [Configuration and Schemas](docs/configuration.md)
160+
- [Contract Policy Schema](api/schema/contract-policy.schema.json)
153161
- [Consumer Semantics v1](docs/consumer-semantics-v1.md)
154162
- [CI Gate](docs/ci-gate.md)
155163
- [Compatibility Matrix](docs/compatibility-matrix.md)
@@ -169,6 +177,8 @@ docs architecture, methodology, migration, and config docs
169177
- Rich report sample: [examples/outputs/posture-generated/report.json](examples/outputs/posture-generated/report.json)
170178
- Rich summary sample: [examples/outputs/posture-generated/summary.md](examples/outputs/posture-generated/summary.md)
171179
- Predicate overlay: [configs/predicate-contract.example.yaml](configs/predicate-contract.example.yaml)
180+
- Contract policy: [configs/contract-policy.example.yaml](configs/contract-policy.example.yaml)
181+
- Deprecated contract policy example: [configs/contract-policy.deprecated.example.yaml](configs/contract-policy.deprecated.example.yaml)
172182
- GitHub Actions CI template: [examples/ci/github-actions.sheaft.yml](examples/ci/github-actions.sheaft.yml)
173183
- GitLab CI template: [examples/ci/gitlab-ci.sheaft.yml](examples/ci/gitlab-ci.sheaft.yml)
174184
- Jenkins CI template: [examples/ci/Jenkinsfile](examples/ci/Jenkinsfile)

api/schema/analysis.schema.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,9 @@
6161
}
6262
}
6363
},
64+
"contract_policy": {
65+
"$ref": "contract-policy.schema.json"
66+
},
6467
"profiles": {
6568
"type": "array",
6669
"minItems": 1,
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
{
2+
"$schema": "https://json-schema.org/draft/2020-12/schema",
3+
"$id": "https://github.com/MB3R-Lab/Sheaft/api/schema/contract-policy.schema.json",
4+
"title": "SheaftContractPolicy",
5+
"type": "object",
6+
"properties": {
7+
"allowed_kinds": {
8+
"type": "array",
9+
"items": {
10+
"type": "string"
11+
},
12+
"uniqueItems": true
13+
},
14+
"allowed_contracts": {
15+
"type": "array",
16+
"items": {
17+
"$ref": "#/$defs/selector"
18+
}
19+
},
20+
"deprecated_action": {
21+
"type": "string",
22+
"enum": ["warn", "fail"]
23+
},
24+
"deprecated_contracts": {
25+
"type": "array",
26+
"items": {
27+
"$ref": "#/$defs/deprecatedSelector"
28+
}
29+
}
30+
},
31+
"$defs": {
32+
"selector": {
33+
"type": "object",
34+
"required": ["name"],
35+
"properties": {
36+
"kind": {
37+
"type": "string"
38+
},
39+
"name": {
40+
"type": "string"
41+
},
42+
"versions": {
43+
"type": "array",
44+
"items": {
45+
"type": "string"
46+
},
47+
"minItems": 1,
48+
"uniqueItems": true
49+
}
50+
},
51+
"additionalProperties": false
52+
},
53+
"deprecatedSelector": {
54+
"type": "object",
55+
"required": ["name"],
56+
"properties": {
57+
"kind": {
58+
"type": "string"
59+
},
60+
"name": {
61+
"type": "string"
62+
},
63+
"versions": {
64+
"type": "array",
65+
"items": {
66+
"type": "string"
67+
},
68+
"minItems": 1,
69+
"uniqueItems": true
70+
},
71+
"action": {
72+
"type": "string",
73+
"enum": ["warn", "fail"]
74+
},
75+
"message": {
76+
"type": "string"
77+
}
78+
},
79+
"additionalProperties": false
80+
}
81+
},
82+
"additionalProperties": false
83+
}

api/schema/report.schema.json

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,33 @@
150150
"input_artifact": {
151151
"type": "object"
152152
},
153+
"contract_policy": {
154+
"type": "object",
155+
"required": [
156+
"status",
157+
"action"
158+
],
159+
"properties": {
160+
"status": {
161+
"type": "string",
162+
"enum": [
163+
"current",
164+
"deprecated"
165+
]
166+
},
167+
"action": {
168+
"type": "string",
169+
"enum": [
170+
"allow",
171+
"warn",
172+
"fail"
173+
]
174+
},
175+
"message": {
176+
"type": "string"
177+
}
178+
}
179+
},
153180
"provenance": {
154181
"type": "object"
155182
},
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
allowed_kinds:
2+
- model
3+
- snapshot
4+
5+
allowed_contracts:
6+
- kind: model
7+
name: io.mb3r.bering.model
8+
versions:
9+
- "1.0.0"
10+
- kind: snapshot
11+
name: io.mb3r.bering.snapshot
12+
versions:
13+
- "1.0.0"
14+
15+
deprecated_action: warn
16+
deprecated_contracts:
17+
- kind: snapshot
18+
name: io.mb3r.bering.snapshot
19+
versions:
20+
- "1.0.0"
21+
message: snapshot 1.0.0 remains supported, but this example project policy warns until the next approved release line is adopted
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
allowed_kinds:
2+
- model
3+
- snapshot
4+
5+
allowed_contracts:
6+
- kind: model
7+
name: io.mb3r.bering.model
8+
versions:
9+
- "1.0.0"
10+
- kind: snapshot
11+
name: io.mb3r.bering.snapshot
12+
versions:
13+
- "1.0.0"

docs/ci-gate.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ This repository validates the CI handoff contract in three layers:
8282

8383
- `sh scripts/ci/check-ci-handoff-templates.sh` verifies that the example templates and docs keep the agreed handoff paths, retention windows, artifact publishing steps, and smoke workflow references.
8484
- `sh scripts/ci/smoke-ci-handoff.sh native` runs the same handoff layout locally via `go run ./cmd/sheaft`.
85-
- `sh scripts/ci/smoke-ci-handoff.sh docker` exercises the Docker execution path used by the example templates.
85+
- `sh scripts/ci/smoke-ci-handoff.sh docker` exercises the Docker execution path used by the example templates, including local runs from Windows Git Bash.
8686

8787
The GitHub Actions workflow at `.github/workflows/ci-template-smoke.yml` runs both smoke modes on every pull request and on pushes to `main`.
8888

docs/compatibility.md

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,44 @@ Recommended checks:
3838
3. reject mismatches before promotion, or let Sheaft reject them at execution time;
3939
4. treat the manifest as compatibility data, not as schema ownership.
4040

41+
## Project-Level Contract Policy
42+
43+
Global runtime support and project-level acceptance are separate.
44+
45+
- Global support is the explicit registry in `internal/modelcontract/contract.go`.
46+
- Project-level acceptance is narrower and can be configured with `contract_policy`.
47+
48+
The project policy supports:
49+
50+
- `allowed_kinds`
51+
- `allowed_contracts`
52+
- `deprecated_action`
53+
- `deprecated_contracts`
54+
55+
Usage examples:
56+
57+
```bash
58+
sheaft run \
59+
--model examples/outputs/snapshot.sample.json \
60+
--analysis configs/analysis.example.yaml \
61+
--contract-policy configs/contract-policy.example.yaml \
62+
--out-dir out
63+
```
64+
65+
```yaml
66+
contract_policy:
67+
allowed_kinds: [model, snapshot]
68+
allowed_contracts:
69+
- kind: snapshot
70+
name: io.mb3r.bering.snapshot
71+
versions: ["1.0.0"]
72+
```
73+
74+
When a contract is still supported globally but deprecated for a given project, Sheaft can either:
75+
76+
- continue and mark the report with `contract_policy.status=deprecated` plus `action=warn`
77+
- fail before simulation with a contract policy error when `deprecated_action=fail`
78+
4179
## Current Scope
4280

4381
- Bering owns upstream schema publication and evolution.

docs/configuration.md

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ Key sections:
2222
- `endpoint_weights`
2323
- `baselines`
2424
- `predicate_contract`
25+
- `contract_policy`
2526
- `gate`
2627

2728
## Serve Config
@@ -40,6 +41,16 @@ For legacy models that only expose `success_predicate_ref`, supply:
4041

4142
The overlay can also carry endpoint weights.
4243

44+
## Contract Policy
45+
46+
Use project-level contract pinning and deprecation controls when a deployment wants to accept only a subset of the globally supported Bering contracts:
47+
48+
- [configs/contract-policy.example.yaml](../configs/contract-policy.example.yaml)
49+
- [configs/contract-policy.deprecated.example.yaml](../configs/contract-policy.deprecated.example.yaml)
50+
- [api/schema/contract-policy.schema.json](../api/schema/contract-policy.schema.json)
51+
52+
The same structure can be embedded inline under `analysis.contract_policy`, or passed separately at runtime with `--contract-policy`.
53+
4354
## Artifact Schemas
4455

4556
- Plain model schema: [api/schema/model.schema.json](../api/schema/model.schema.json)
@@ -50,9 +61,10 @@ Report output now carries both:
5061

5162
- `provenance`: artifact/overlay origin for predicates and weights
5263
- `parameters`: resolved simulation inputs plus source attribution (`default`, `policy`, `override`, `external`) and calibration fallback markers
64+
- `contract_policy`: whether the accepted contract is current or deprecated for this project, plus the effective action (`allow`, `warn`, `fail`)
5365

5466
## Migration Rule of Thumb
5567

5668
- keep `--policy` when one profile and simple thresholds are enough
57-
- move to `--analysis` when you need profiles, weights, baselines, or overlays
69+
- move to `--analysis` when you need profiles, weights, baselines, overlays, or contract pinning
5870
- use `serve` when posture must stay current as new artifacts arrive

0 commit comments

Comments
 (0)