agentversion 0.2.1__tar.gz → 0.2.2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of agentversion might be problematic. Click here for more details.
- {agentversion-0.2.1 → agentversion-0.2.2}/CHANGELOG.md +14 -0
- {agentversion-0.2.1 → agentversion-0.2.2}/PKG-INFO +1 -1
- {agentversion-0.2.1 → agentversion-0.2.2}/agentversion/diff.py +3 -3
- {agentversion-0.2.1 → agentversion-0.2.2}/agentversion/manifest.py +16 -11
- {agentversion-0.2.1 → agentversion-0.2.2}/pyproject.toml +1 -1
- agentversion-0.2.2/spec/behavioral-policy.md +56 -0
- agentversion-0.2.1/spec/behavioral-policy.md +0 -51
- {agentversion-0.2.1 → agentversion-0.2.2}/.github/dependabot.yml +0 -0
- {agentversion-0.2.1 → agentversion-0.2.2}/.github/workflows/ci.yml +0 -0
- {agentversion-0.2.1 → agentversion-0.2.2}/.github/workflows/publish.yml +0 -0
- {agentversion-0.2.1 → agentversion-0.2.2}/.gitignore +0 -0
- {agentversion-0.2.1 → agentversion-0.2.2}/CONFORMANCE.md +0 -0
- {agentversion-0.2.1 → agentversion-0.2.2}/CONTRIBUTING.md +0 -0
- {agentversion-0.2.1 → agentversion-0.2.2}/LICENSE +0 -0
- {agentversion-0.2.1 → agentversion-0.2.2}/README.md +0 -0
- {agentversion-0.2.1 → agentversion-0.2.2}/RELEASING.md +0 -0
- {agentversion-0.2.1 → agentversion-0.2.2}/adrs/0000-template.md +0 -0
- {agentversion-0.2.1 → agentversion-0.2.2}/adrs/0001-version-spec-core.md +0 -0
- {agentversion-0.2.1 → agentversion-0.2.2}/agentversion/__init__.py +0 -0
- {agentversion-0.2.1 → agentversion-0.2.2}/agentversion/_shared.py +0 -0
- {agentversion-0.2.1 → agentversion-0.2.2}/agentversion/a2a.py +0 -0
- {agentversion-0.2.1 → agentversion-0.2.2}/agentversion/cli.py +0 -0
- {agentversion-0.2.1 → agentversion-0.2.2}/agentversion/compatibility.py +0 -0
- {agentversion-0.2.1 → agentversion-0.2.2}/agentversion/constants.py +0 -0
- {agentversion-0.2.1 → agentversion-0.2.2}/agentversion/contract.py +0 -0
- {agentversion-0.2.1 → agentversion-0.2.2}/agentversion/dataset.py +0 -0
- {agentversion-0.2.1 → agentversion-0.2.2}/agentversion/decision.py +0 -0
- {agentversion-0.2.1 → agentversion-0.2.2}/agentversion/hasher.py +0 -0
- {agentversion-0.2.1 → agentversion-0.2.2}/agentversion/ids.py +0 -0
- {agentversion-0.2.1 → agentversion-0.2.2}/agentversion/py.typed +0 -0
- {agentversion-0.2.1 → agentversion-0.2.2}/agentversion/refs.py +0 -0
- {agentversion-0.2.1 → agentversion-0.2.2}/agentversion/replay.py +0 -0
- {agentversion-0.2.1 → agentversion-0.2.2}/agentversion/validator.py +0 -0
- {agentversion-0.2.1 → agentversion-0.2.2}/compatibility-tests/environment-region-change/after.json +0 -0
- {agentversion-0.2.1 → agentversion-0.2.2}/compatibility-tests/environment-region-change/before.json +0 -0
- {agentversion-0.2.1 → agentversion-0.2.2}/compatibility-tests/environment-region-change/expected-diff.json +0 -0
- {agentversion-0.2.1 → agentversion-0.2.2}/compatibility-tests/model-runtime-provider-change/after.json +0 -0
- {agentversion-0.2.1 → agentversion-0.2.2}/compatibility-tests/model-runtime-provider-change/before.json +0 -0
- {agentversion-0.2.1 → agentversion-0.2.2}/compatibility-tests/model-runtime-provider-change/expected-diff.json +0 -0
- {agentversion-0.2.1 → agentversion-0.2.2}/compatibility-tests/output-schema-change/after.json +0 -0
- {agentversion-0.2.1 → agentversion-0.2.2}/compatibility-tests/output-schema-change/before.json +0 -0
- {agentversion-0.2.1 → agentversion-0.2.2}/compatibility-tests/output-schema-change/expected-diff.json +0 -0
- {agentversion-0.2.1 → agentversion-0.2.2}/compatibility-tests/prompt-stack-edit/after.json +0 -0
- {agentversion-0.2.1 → agentversion-0.2.2}/compatibility-tests/prompt-stack-edit/before.json +0 -0
- {agentversion-0.2.1 → agentversion-0.2.2}/compatibility-tests/prompt-stack-edit/expected-diff.json +0 -0
- {agentversion-0.2.1 → agentversion-0.2.2}/compatibility-tests/skill-registry-skill-removed/after.json +0 -0
- {agentversion-0.2.1 → agentversion-0.2.2}/compatibility-tests/skill-registry-skill-removed/before.json +0 -0
- {agentversion-0.2.1 → agentversion-0.2.2}/compatibility-tests/skill-registry-skill-removed/expected-diff.json +0 -0
- {agentversion-0.2.1 → agentversion-0.2.2}/compatibility-tests/subagent-handoff-change/after.json +0 -0
- {agentversion-0.2.1 → agentversion-0.2.2}/compatibility-tests/subagent-handoff-change/before.json +0 -0
- {agentversion-0.2.1 → agentversion-0.2.2}/compatibility-tests/subagent-handoff-change/expected-diff.json +0 -0
- {agentversion-0.2.1 → agentversion-0.2.2}/compatibility-tests/tool-rename/after.json +0 -0
- {agentversion-0.2.1 → agentversion-0.2.2}/compatibility-tests/tool-rename/before.json +0 -0
- {agentversion-0.2.1 → agentversion-0.2.2}/compatibility-tests/tool-rename/expected-diff.json +0 -0
- {agentversion-0.2.1 → agentversion-0.2.2}/compatibility-tests/workflow-graph-change/after.json +0 -0
- {agentversion-0.2.1 → agentversion-0.2.2}/compatibility-tests/workflow-graph-change/before.json +0 -0
- {agentversion-0.2.1 → agentversion-0.2.2}/compatibility-tests/workflow-graph-change/expected-diff.json +0 -0
- {agentversion-0.2.1 → agentversion-0.2.2}/examples/.gitkeep +0 -0
- {agentversion-0.2.1 → agentversion-0.2.2}/examples/integrations/decimalai_bridge.py +0 -0
- {agentversion-0.2.1 → agentversion-0.2.2}/examples/integrations/langgraph_example.py +0 -0
- {agentversion-0.2.1 → agentversion-0.2.2}/examples/integrations/otel_mapping.md +0 -0
- {agentversion-0.2.1 → agentversion-0.2.2}/examples/manifest/finance-agent-v1.json +0 -0
- {agentversion-0.2.1 → agentversion-0.2.2}/examples/manifest/finance-agent-v2.json +0 -0
- {agentversion-0.2.1 → agentversion-0.2.2}/examples/scenarios/tool-rename-drift.md +0 -0
- {agentversion-0.2.1 → agentversion-0.2.2}/examples/scenarios/walkthrough.py +0 -0
- {agentversion-0.2.1 → agentversion-0.2.2}/pyrightconfig.json +0 -0
- {agentversion-0.2.1 → agentversion-0.2.2}/schemas/.gitkeep +0 -0
- {agentversion-0.2.1 → agentversion-0.2.2}/schemas/agent-manifest.schema.json +0 -0
- {agentversion-0.2.1 → agentversion-0.2.2}/schemas/compatibility-batch.schema.json +0 -0
- {agentversion-0.2.1 → agentversion-0.2.2}/schemas/compatibility-decision.schema.json +0 -0
- {agentversion-0.2.1 → agentversion-0.2.2}/schemas/compatibility-policy.schema.json +0 -0
- {agentversion-0.2.1 → agentversion-0.2.2}/schemas/compatibility-report.schema.json +0 -0
- {agentversion-0.2.1 → agentversion-0.2.2}/schemas/dataset-snapshot.schema.json +0 -0
- {agentversion-0.2.1 → agentversion-0.2.2}/schemas/episode.schema.json +0 -0
- {agentversion-0.2.1 → agentversion-0.2.2}/schemas/manifest-diff.schema.json +0 -0
- {agentversion-0.2.1 → agentversion-0.2.2}/schemas/replay-job.schema.json +0 -0
- {agentversion-0.2.1 → agentversion-0.2.2}/schemas/replay-result.schema.json +0 -0
- {agentversion-0.2.1 → agentversion-0.2.2}/schemas/step.schema.json +0 -0
- {agentversion-0.2.1 → agentversion-0.2.2}/schemas/task.schema.json +0 -0
- {agentversion-0.2.1 → agentversion-0.2.2}/scripts/release.sh +0 -0
- {agentversion-0.2.1 → agentversion-0.2.2}/spec/a2a-mapping.md +0 -0
- {agentversion-0.2.1 → agentversion-0.2.2}/spec/attestation.md +0 -0
- {agentversion-0.2.1 → agentversion-0.2.2}/spec/compatibility-batch.md +0 -0
- {agentversion-0.2.1 → agentversion-0.2.2}/spec/compatibility-decision.md +0 -0
- {agentversion-0.2.1 → agentversion-0.2.2}/spec/compatibility-policy.md +0 -0
- {agentversion-0.2.1 → agentversion-0.2.2}/spec/data-classification.md +0 -0
- {agentversion-0.2.1 → agentversion-0.2.2}/spec/dataset.md +0 -0
- {agentversion-0.2.1 → agentversion-0.2.2}/spec/diff.md +0 -0
- {agentversion-0.2.1 → agentversion-0.2.2}/spec/environment.md +0 -0
- {agentversion-0.2.1 → agentversion-0.2.2}/spec/evaluation.md +0 -0
- {agentversion-0.2.1 → agentversion-0.2.2}/spec/hashing.md +0 -0
- {agentversion-0.2.1 → agentversion-0.2.2}/spec/ids.md +0 -0
- {agentversion-0.2.1 → agentversion-0.2.2}/spec/lifecycle.md +0 -0
- {agentversion-0.2.1 → agentversion-0.2.2}/spec/manifest.md +0 -0
- {agentversion-0.2.1 → agentversion-0.2.2}/spec/otel-mapping.md +0 -0
- {agentversion-0.2.1 → agentversion-0.2.2}/spec/reference.md +0 -0
- {agentversion-0.2.1 → agentversion-0.2.2}/spec/refs.md +0 -0
- {agentversion-0.2.1 → agentversion-0.2.2}/spec/replay-determinism.md +0 -0
- {agentversion-0.2.1 → agentversion-0.2.2}/spec/replay.md +0 -0
- {agentversion-0.2.1 → agentversion-0.2.2}/spec/versioning-policy.md +0 -0
- {agentversion-0.2.1 → agentversion-0.2.2}/tests/fixtures/frozen_hash_vectors.json +0 -0
- {agentversion-0.2.1 → agentversion-0.2.2}/tests/test_a2a_mapping.py +0 -0
- {agentversion-0.2.1 → agentversion-0.2.2}/tests/test_audit_v020.py +0 -0
- {agentversion-0.2.1 → agentversion-0.2.2}/tests/test_audit_v030.py +0 -0
- {agentversion-0.2.1 → agentversion-0.2.2}/tests/test_behavioral_policy.py +0 -0
- {agentversion-0.2.1 → agentversion-0.2.2}/tests/test_cli.py +0 -0
- {agentversion-0.2.1 → agentversion-0.2.2}/tests/test_component_surface_map.py +0 -0
- {agentversion-0.2.1 → agentversion-0.2.2}/tests/test_conformance.py +0 -0
- {agentversion-0.2.1 → agentversion-0.2.2}/tests/test_contract.py +0 -0
- {agentversion-0.2.1 → agentversion-0.2.2}/tests/test_dataset.py +0 -0
- {agentversion-0.2.1 → agentversion-0.2.2}/tests/test_decision_replay.py +0 -0
- {agentversion-0.2.1 → agentversion-0.2.2}/tests/test_diff.py +0 -0
- {agentversion-0.2.1 → agentversion-0.2.2}/tests/test_environment.py +0 -0
- {agentversion-0.2.1 → agentversion-0.2.2}/tests/test_evaluation.py +0 -0
- {agentversion-0.2.1 → agentversion-0.2.2}/tests/test_examples_runnable.py +0 -0
- {agentversion-0.2.1 → agentversion-0.2.2}/tests/test_extension_hatch.py +0 -0
- {agentversion-0.2.1 → agentversion-0.2.2}/tests/test_frozen_hash_vectors.py +0 -0
- {agentversion-0.2.1 → agentversion-0.2.2}/tests/test_hasher.py +0 -0
- {agentversion-0.2.1 → agentversion-0.2.2}/tests/test_ids.py +0 -0
- {agentversion-0.2.1 → agentversion-0.2.2}/tests/test_lifecycle.py +0 -0
- {agentversion-0.2.1 → agentversion-0.2.2}/tests/test_manifest.py +0 -0
- {agentversion-0.2.1 → agentversion-0.2.2}/tests/test_refs.py +0 -0
- {agentversion-0.2.1 → agentversion-0.2.2}/tests/test_reproducible_replay.py +0 -0
- {agentversion-0.2.1 → agentversion-0.2.2}/tests/test_trust_observability.py +0 -0
- {agentversion-0.2.1 → agentversion-0.2.2}/tests/test_validator.py +0 -0
|
@@ -7,6 +7,20 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
> **Package version ≠ spec version.** This file tracks the **package** version. The on-the-wire `spec_version` is independent and frozen at `1.0.0`; a pre-1.0 package can implement a stable 1.0 spec, which is exactly the situation today.
|
|
9
9
|
|
|
10
|
+
## [0.2.2] - 2026-07-15
|
|
11
|
+
|
|
12
|
+
### Changed
|
|
13
|
+
- **`behavioral_policy` re-scoped as a generic versioned policy-document surface** (docs only).
|
|
14
|
+
The surface previously described itself as bound to skillevaluation's conversation-mode
|
|
15
|
+
`policy_check` state machine; that eval mode was removed (skillevaluation ADR-0007), so the
|
|
16
|
+
docstrings + `spec/behavioral-policy.md` now define it document-agnostically: `policy_hash` is a
|
|
17
|
+
hash of *any* bound policy artifact (refund rules, a safety guardrail set, an escalation SOP…),
|
|
18
|
+
a rule change diffs **breaking**, an unchanged `policy_hash` is non-breaking. **No code or schema
|
|
19
|
+
change**: the `BehavioralPolicy` model still carries `objection_threshold`/`concede_events`/
|
|
20
|
+
`always_forbidden` (now documented as optional, illustrative, back-compat rule fields), the
|
|
21
|
+
`_BEHAVIORAL_POLICY_RULE_FIELDS` diff logic is byte-identical, and every frozen hash-vector +
|
|
22
|
+
the 406-test suite are unchanged. `spec_version` unchanged (1.0.0).
|
|
23
|
+
|
|
10
24
|
## [0.2.1] - 2026-06-24
|
|
11
25
|
|
|
12
26
|
### Fixed
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: agentversion
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.2
|
|
4
4
|
Summary: An open specification for versioning agent runtimes and keeping datasets valid.
|
|
5
5
|
Project-URL: Homepage, https://github.com/decimal-labs/agentversion
|
|
6
6
|
Project-URL: Documentation, https://github.com/decimal-labs/agentversion/tree/main/spec
|
|
@@ -741,9 +741,9 @@ _BEHAVIORAL_POLICY_RULE_FIELDS = (
|
|
|
741
741
|
def _adapt_behavioral_policy(old: dict[str, Any], new: dict[str, Any]) -> tuple[
|
|
742
742
|
Literal["breaking", "non_breaking"], Severity, list[str]
|
|
743
743
|
]:
|
|
744
|
-
"""A change to the
|
|
745
|
-
|
|
746
|
-
|
|
744
|
+
"""A change to the bound behavioral policy RULES is BREAKING: it invalidates any eval set and any
|
|
745
|
+
past traces graded under the old policy. (A bare metadata change with an unchanged ``policy_hash``
|
|
746
|
+
is not a rule change.)
|
|
747
747
|
|
|
748
748
|
Add/remove are asymmetric and handled here so the surface is severitied by its own
|
|
749
749
|
logic in both directions: *introducing* a policy where there was none is additive
|
|
@@ -263,25 +263,30 @@ class Environment(BaseModel):
|
|
|
263
263
|
|
|
264
264
|
|
|
265
265
|
class BehavioralPolicy(BaseModel):
|
|
266
|
-
"""
|
|
266
|
+
"""Versioned BEHAVIORAL-POLICY contract surface.
|
|
267
267
|
|
|
268
|
-
|
|
269
|
-
the customer objects N times, then escalate; never admit liability"
|
|
270
|
-
|
|
268
|
+
Binds the agent to a named policy artifact — the rules it must hold to, e.g. a refund/escalation
|
|
269
|
+
policy ("deny until the customer objects N times, then escalate; never admit liability"), a safety
|
|
270
|
+
guardrail set, or an escalation SOP. The surface is document-agnostic: ``policy_hash`` is the stable
|
|
271
|
+
identity (a hash of whatever policy artifact you bind), and the value carried is opaque to this
|
|
272
|
+
model.
|
|
271
273
|
|
|
272
274
|
Why it is a first-class surface: a behavioral policy lives *inside* the prompt, so a prompt-stack
|
|
273
|
-
hash change is classified ``non_breaking`` — yet flipping the policy (
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
275
|
+
hash change is classified ``non_breaking`` — yet flipping the policy (a threshold 3 → 1, or removing
|
|
276
|
+
a forbidden rule) INVALIDATES any eval set and any past traces graded under the old policy. Hoisting
|
|
277
|
+
the policy to its own surface makes that flip visible and ``breaking`` instead of silently ``keep``.
|
|
278
|
+
|
|
279
|
+
``policy_hash`` is the identity; the structured rule fields below are OPTIONAL and carried only for
|
|
280
|
+
human-readable diffs (a policy artifact needn't populate any of them — ``extra='allow'`` lets a
|
|
281
|
+
richer or differently-shaped policy spec round-trip without forking this model). They remain on the
|
|
282
|
+
model for backward compatibility with policies already bound this way.
|
|
279
283
|
"""
|
|
280
284
|
|
|
281
285
|
model_config = ConfigDict(extra="allow")
|
|
282
286
|
|
|
283
287
|
policy_id: str | None = None
|
|
284
|
-
policy_hash: str | None = None # stable hash of the bound
|
|
288
|
+
policy_hash: str | None = None # stable hash of the bound policy artifact (the identity)
|
|
289
|
+
# Optional structured rule fields — illustrative, kept for back-compat + human-readable diffs.
|
|
285
290
|
objection_threshold: int | None = None
|
|
286
291
|
concede_events: list[str] | None = None
|
|
287
292
|
always_forbidden: list[str] | None = None
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
# `behavioral_policy` surface
|
|
2
|
+
|
|
3
|
+
A contract surface that binds an agent to a **versioned policy document** — the rules it must hold to.
|
|
4
|
+
The surface is document-agnostic: the policy can be a refund/escalation policy (*"deny refunds and offer
|
|
5
|
+
alternatives; only after the customer has objected ≥3 times, escalate to a human; never concede a refund
|
|
6
|
+
yourself, and never admit liability"*), a safety guardrail set, an escalation SOP, or any other bound
|
|
7
|
+
rule artifact.
|
|
8
|
+
|
|
9
|
+
## Why it is a first-class surface
|
|
10
|
+
|
|
11
|
+
A behavioral policy usually lives *inside the system prompt*. Before this surface existed, flipping the
|
|
12
|
+
policy (tightening a threshold, or dropping a forbidden rule) showed up only as a `prompt_stack`
|
|
13
|
+
**hash change**, which the diff classifies **`non_breaking`** → recommended decision **`keep`**. But a
|
|
14
|
+
policy flip **invalidates** any eval set and any past traces that were graded under the old policy.
|
|
15
|
+
Hoisting the policy to its own surface makes that flip **`breaking`** → `replay`/`drop`, instead of
|
|
16
|
+
silently retaining now-wrong data.
|
|
17
|
+
|
|
18
|
+
The `policy_hash` is the canonical identity — a hash of *whatever policy artifact you bind*. The
|
|
19
|
+
structured rule fields below are optional and carried only for human-readable diffs; the surface does not
|
|
20
|
+
interpret them.
|
|
21
|
+
|
|
22
|
+
## Shape
|
|
23
|
+
|
|
24
|
+
```json
|
|
25
|
+
"behavioral_policy": {
|
|
26
|
+
"policy_id": "refund-escalation",
|
|
27
|
+
"policy_hash": "sha256:…", // hash of the bound policy artifact (the identity)
|
|
28
|
+
"objection_threshold": 3, // optional structured rule fields — illustrative,
|
|
29
|
+
"concede_events": ["offered_refund", "escalated"], // carried for readable diffs only
|
|
30
|
+
"always_forbidden": ["admits_liability"]
|
|
31
|
+
}
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
`policy_id` and `policy_hash` are the only load-bearing keys. The structured rule fields
|
|
35
|
+
(`objection_threshold`, `concede_events`, `always_forbidden`) are **optional**, illustrative, and kept
|
|
36
|
+
for backward compatibility with policies already bound this way — a policy artifact needn't populate any
|
|
37
|
+
of them. The model is `extra="allow"`, so a richer or differently-shaped policy spec round-trips without
|
|
38
|
+
forking it.
|
|
39
|
+
|
|
40
|
+
## Diff semantics
|
|
41
|
+
|
|
42
|
+
| Transition | Classification | Rationale |
|
|
43
|
+
|---|---|---|
|
|
44
|
+
| rule change (`policy_hash` differs, or any rule field differs) | **breaking** (`major`) | any eval set + past graded traces are now wrong |
|
|
45
|
+
| `policy_hash` unchanged, only metadata (`policy_id`) differs | `non_breaking` (`minor`) | same policy, no rule changed |
|
|
46
|
+
| introduced (absent → present) | `non_breaking` | the old eval set tested no policy; additive |
|
|
47
|
+
| removed (present → absent) | **breaking** (`major`) | past data graded under the policy is now ungoverned |
|
|
48
|
+
|
|
49
|
+
Reason code: `behavioral_policy_changed`. Configurable per-surface via `CompatibilityPolicy.behavioral_policy`
|
|
50
|
+
(defaults: `on_major` → `drop`).
|
|
51
|
+
|
|
52
|
+
## Hash-safety
|
|
53
|
+
|
|
54
|
+
`behavioral_policy` is **optional and omitted by default**. The `overall_hash` is computed only over the
|
|
55
|
+
surfaces actually present in a contract, so adding this surface to the spec does **not** change the hash
|
|
56
|
+
of any existing (policy-less) manifest. The frozen hash-vectors are unchanged.
|
|
@@ -1,51 +0,0 @@
|
|
|
1
|
-
# `behavioral_policy` surface
|
|
2
|
-
|
|
3
|
-
A contract surface for a multi-turn agent's **behavioral policy** — the rules it must hold *across
|
|
4
|
-
turns*, e.g. a refund/escalation policy: *"deny refunds and offer alternatives; only after the customer
|
|
5
|
-
has objected ≥3 times, escalate to a human; never concede a refund yourself, and never admit liability."*
|
|
6
|
-
|
|
7
|
-
## Why it is a first-class surface
|
|
8
|
-
|
|
9
|
-
A behavioral policy lives *inside the system prompt*. Before this surface existed, flipping the policy
|
|
10
|
-
(`objection_threshold` 3 → 1, or dropping an `always_forbidden` rule) showed up only as a `prompt_stack`
|
|
11
|
-
**hash change**, which the diff classifies **`non_breaking`** → recommended decision **`keep`**. But a
|
|
12
|
-
policy flip **invalidates** the conversation-mode eval set and any past traces that were graded under the
|
|
13
|
-
old policy. Hoisting the policy to its own surface makes that flip **`breaking`** → `replay`/`drop`,
|
|
14
|
-
instead of silently retaining now-wrong data.
|
|
15
|
-
|
|
16
|
-
This binds directly to [skillevaluation](https://github.com/decimal-labs/skillevaluation)'s
|
|
17
|
-
conversation-mode `policy_check` — the deterministic state machine that grades these same rules. The
|
|
18
|
-
`policy_hash` is the canonical identity (a hash of the bound `policy_check` spec); the rule fields are
|
|
19
|
-
carried for human-readable diffs.
|
|
20
|
-
|
|
21
|
-
## Shape
|
|
22
|
-
|
|
23
|
-
```json
|
|
24
|
-
"behavioral_policy": {
|
|
25
|
-
"policy_id": "refund-escalation",
|
|
26
|
-
"policy_hash": "sha256:…", // hash of the bound policy_check spec (the identity)
|
|
27
|
-
"objection_threshold": 3,
|
|
28
|
-
"concede_events": ["offered_refund", "escalated"],
|
|
29
|
-
"always_forbidden": ["admits_liability"]
|
|
30
|
-
}
|
|
31
|
-
```
|
|
32
|
-
|
|
33
|
-
The model is `extra="allow"`, so a richer policy spec round-trips without forking it.
|
|
34
|
-
|
|
35
|
-
## Diff semantics
|
|
36
|
-
|
|
37
|
-
| Transition | Classification | Rationale |
|
|
38
|
-
|---|---|---|
|
|
39
|
-
| rule change (`policy_hash` differs, or any rule field differs) | **breaking** (`major`) | conversation eval set + past graded traces are now wrong |
|
|
40
|
-
| `policy_hash` unchanged, only metadata (`policy_id`) differs | `non_breaking` (`minor`) | same policy, no rule changed |
|
|
41
|
-
| introduced (absent → present) | `non_breaking` | the old eval set tested no policy; additive |
|
|
42
|
-
| removed (present → absent) | **breaking** (`major`) | past data graded under the policy is now ungoverned |
|
|
43
|
-
|
|
44
|
-
Reason code: `behavioral_policy_changed`. Configurable per-surface via `CompatibilityPolicy.behavioral_policy`
|
|
45
|
-
(defaults: `on_major` → `drop`).
|
|
46
|
-
|
|
47
|
-
## Hash-safety
|
|
48
|
-
|
|
49
|
-
`behavioral_policy` is **optional and omitted by default**. The `overall_hash` is computed only over the
|
|
50
|
-
surfaces actually present in a contract, so adding this surface to the spec does **not** change the hash
|
|
51
|
-
of any existing (policy-less) manifest. The frozen hash-vectors are unchanged.
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{agentversion-0.2.1 → agentversion-0.2.2}/compatibility-tests/environment-region-change/after.json
RENAMED
|
File without changes
|
{agentversion-0.2.1 → agentversion-0.2.2}/compatibility-tests/environment-region-change/before.json
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{agentversion-0.2.1 → agentversion-0.2.2}/compatibility-tests/output-schema-change/after.json
RENAMED
|
File without changes
|
{agentversion-0.2.1 → agentversion-0.2.2}/compatibility-tests/output-schema-change/before.json
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{agentversion-0.2.1 → agentversion-0.2.2}/compatibility-tests/prompt-stack-edit/expected-diff.json
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{agentversion-0.2.1 → agentversion-0.2.2}/compatibility-tests/subagent-handoff-change/after.json
RENAMED
|
File without changes
|
{agentversion-0.2.1 → agentversion-0.2.2}/compatibility-tests/subagent-handoff-change/before.json
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{agentversion-0.2.1 → agentversion-0.2.2}/compatibility-tests/tool-rename/expected-diff.json
RENAMED
|
File without changes
|
{agentversion-0.2.1 → agentversion-0.2.2}/compatibility-tests/workflow-graph-change/after.json
RENAMED
|
File without changes
|
{agentversion-0.2.1 → agentversion-0.2.2}/compatibility-tests/workflow-graph-change/before.json
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|