Releases: OpenAdaptAI/openadapt-types
Release list
v0.9.0
v0.8.0
v0.8.0 (2026-07-29)
Features
Add a versioned signed task contract for qualification-approved entity labels. Preserve V1 bytes, bind the qualification project and exact step, keep a neutral fallback, and use a strict cross-language timestamp and action contract.
Detailed Changes: v0.7.0...v0.8.0
v0.7.0
v0.7.0 (2026-07-29)
Chores
Features
Add the portable attended-reconciliation and Execute v1 contracts. Regenerate the public schemas and keep the source boundary intact.
Detailed Changes: v0.6.4...v0.7.0
v0.6.4
v0.6.4 (2026-07-28)
Bug Fixes
ActionType.DONE is a successful terminal outcome: a runner that sees it ends the episode as complete. Every parse and conversion failure in this package produced exactly that value, so "the model said it finished" and "we could not read the model's output at all" were the same Action.
-
openadapt_types/parsing.py: the_done()helper behind all 19 failure paths now returnsAction(type=ActionType.FAIL)carrying the reason inreasoningand inraw[PARSE_ERROR_KEY]. This also repairsparse_action, which usedtype != DONEas its own success test and so re-parsed a legitimate{"type": "done"}as DSL before returning it. -
openadapt_types/_compat.py:from_benchmark_action,from_ml_actionandfrom_omnimcp_action_decisiondefaulted a missing type to"done"and mapped every unrecognized type toDONEwith no log at all. An unconvertible record became a successful terminal step in converted training data. They now return FAIL withraw[UNCONVERTIBLE_ACTION_KEY]and the source dict. -
openadapt_types/computer_state.py:get_childrenreturned[]both for a node with no children and for a node_id that is not in the state. An unknown node now raises KeyError. -
openadapt_types/__init__.py:__version__was the literal "0.1.0" against a package on 0.6.3. It is now read from installed distribution metadata.
Existing tests that asserted the DONE-on-failure behaviour are updated to assert FAIL; they enshrined the defect. tests/test_no_false_success.py adds the direct regressions, and every production change was reverted individually to confirm the matching test fails against pre-fix code.
Claude-Session: https://claude.ai/code/session_01NyCHrzA1psrKMFfroYbzaM
Co-authored-by: Claude Opus 5 noreply@anthropic.com
Detailed Changes: v0.6.3...v0.6.4
v0.6.3
v0.6.3 (2026-07-28)
Bug Fixes
The attended vocabulary was closed at continue/skip/teach/escalate. An operator who looked at the live application and concluded the engine was right to stop had no way to say so: escalate PARKS the run for a colleague and reads as "I don't know", and continue asserts a repair that did not happen. Disagreement therefore had no channel, so the recorded answer distribution could not report how often a halt was correct -- the exact measurement needed before anyone tunes a halt rate.
Add reject to HumanDecisionAction and the terminal rejected / rejected_by_operator pair to the receipt. Reject and escalate stay separate members because they do opposite things to the run: escalate leaves the durable pause resumable, reject ends it. Collapsing them is cheaper and destroys the signal.
allowed_actions widens from four to five entries, which is the size of the vocabulary rather than a policy: a pause that is skippable, re-verifiable, rejectable, teachable and escalatable is legitimate, and a stale bound would have refused to issue that task at all.
The cause of a rejection is a closed enum with one member. A reason taxonomy would be more informative, but there is no evidence yet for what its members should be -- the reject rate is the data that would design them -- and adding members later is additive, whereas a free-text reason could never be closed again.
Chores
.private/ is the workspace-wide convention for material that must never be published. It was not ignored here, so a directory created inside this checkout was one stray git add from being committed. Ignore it mechanically rather than relying on that never happening.
Claude-Session: https://claude.ai/code/session_01NyCHrzA1psrKMFfroYbzaM
Co-authored-by: Claude Opus 5 noreply@anthropic.com
Detailed Changes: v0.6.2...v0.6.3
v0.6.2
v0.6.2 (2026-07-27)
Bug Fixes
The signed human-decision task contract shipped in 0.6.0/0.6.1, but the receipt that closes the round trip did not. openadapt-flow already returns a terminal receipt from its console decision route and had to define its own half locally, so no consumer outside Flow can validate the shape Flow actually produces. Cloud cannot check the one payload that reports whether an operator's decision resumed, halted, or may have been delivered.
HumanDecisionReceiptV1 closes that gap. It is a closed type in which protected content is structurally unrepresentable rather than stripped on send: no free-text field, reason_code a closed enum, every string closed by a pattern/const/enum, unknown fields rejected, RFC 3339 timestamps, and uncertainty a first-class terminal state.
Claude-Session: https://claude.ai/code/session_01NyCHrzA1psrKMFfroYbzaM
Co-authored-by: Claude Opus 5 noreply@anthropic.com
Detailed Changes: v0.6.1...v0.6.2
v0.6.1
v0.6.1 (2026-07-27)
Bug Fixes
The signed human-decision task contract shipped in 0.6.0 is already strict, closed, and Cloud-safe in Python. Two narrow gaps remained against the mobile attended-decision design, both about consumers that are not Python.
created_at and expires_at were the only declared strings with no pattern. Python rejected non-timestamps through the model validator, but the packaged human-decision-task-v1.json -- the artifact a TypeScript or other-language consumer validates against -- constrained them only by length, so it accepted up to 40 characters of arbitrary text in two fields. Free text is how PHI escapes, so the RFC 3339 shape now lives in the field pattern and therefore in the exported schema.
Canonicalization was correct but undocumented and unpinned: a reimplementer had to infer the rules from json.dumps keyword arguments. The rules are now normative in the module docstring, and a frozen vector pins the exact canonical bytes, digest, and signature hex so a cross-language implementation can self-check and a future change fails loudly instead of silently re-signing.
Tests now enumerate each forbidden evidence category -- screenshots, OCR, expected/observed values, free text, identifiers, unknown fields -- against the task and both nested models, and a structural guard walks the exported schema to fail on any string not closed by a pattern, const, or enum. That guard is what stops a later field addition from quietly reopening the hole.
No signed byte changes: the pinned vector was computed before this change and still matches. Every timestamp format Flow's _iso() emits still validates.
Claude-Session: https://claude.ai/code/session_01NyCHrzA1psrKMFfroYbzaM
Co-authored-by: Claude Opus 5 noreply@anthropic.com
Detailed Changes: v0.6.0...v0.6.1
v0.6.0
v0.5.0
v0.5.0 (2026-07-25)
Bug Fixes
- Separate runtime geometry from renderer mapping (
9b88122)
Documentation
- Clarify browser target geometry scope (
4e2fa41)
Features
- Add exact overlay target tracking contract (
22b9cbb)
Detailed Changes: v0.4.0...v0.5.0
v0.4.0
v0.4.0 (2026-07-25)
Documentation
Adds the standard lifecycle banner used across the org (matching the banner wave on openadapt-capture, openadapt-grounding, etc.), derived from this repo's classification in the repository lifecycle registry (OpenAdaptAI/.github repository-lifecycle.yml, reviewed 2026-07-15): Experimental.
Existing README content is unchanged below the banner.
Co-authored-by: Claude Fable 5 noreply@anthropic.com
Refresh the README to the shared OpenAdapt house style: governed demonstration compiler positioning, a consistent "The OpenAdapt stack" section cross-linking the sibling packages, docs.openadapt.ai and the main OpenAdapt repo links, first-class substrate framing with honest maturity, and no em dashes. Claims verified against the package code.
Claude-Session: https://claude.ai/code/session_01NyCHrzA1psrKMFfroYbzaM
Co-authored-by: Claude Opus 4.8 noreply@anthropic.com
Features
- Add shared control overlay contract (
ca1c85c)
Detailed Changes: v0.3.1...v0.4.0