revisions
strands_teams.revisions ¶
Facet-level review reconciliation + the promote_artifact CAS tool (spec 005).
This module sits on top of the immutable, content-addressed :class:~strands_teams.models.ArtifactRevision store owned by :class:~strands_teams.layout.TeamsLayout. It ships three things (ASTR §4.8, §6.4, §12.6):
- :func:
semantic_diff— a facet-level diff of two revisions returning the set of facets whose content changed (AC-3-2). - :func:
invalidates_review/ :func:reconcile_reviews— the selective invalidation rule: a bound review is invalidated ONLY when the facets it covers intersect the facetssemantic_diffreports as changed; otherwise it is carried forward and reused rather than recomputed (AC-3-3, AC-3-4, AC-3-6). Anew_revisionwhose lineage does not supersede the review's bound revision is a lineage error, not a silent verdict (AC-3-5). - :func:
promote_artifact— the@toolwrapping the layout's optimistic compare-and-set, returning a :class:~strands_teams.models.PromotionResultJSON string (AC-2-2..AC-2-6). A stale CAS surfaces as a structured error result rather than an exception crossing the tool boundary.
A review here is anything carrying a revision binding and covered facets: either the Phase 1 :class:~strands_teams.models.Finding (extended in this phase with reviewed_revision / reviewed_facets) or the lightweight :class:Review model. Both are consumed structurally via :func:_review_binding.
ReviewStatus module-attribute ¶
Outcome of evaluating a bound review against a new revision.
valid— the changed facets do not intersect the review's covered facets; the review is carried forward and reused (AC-3-4).invalidated— the changed facets intersect the covered facets; the review is re-opened (AC-3-3).error— thenew_revisionlineage does not supersede the review's bound revision, so no reuse/invalidation verdict can be trusted (AC-3-5).
ReviewBinding ¶
Bases: Protocol
Structural interface for a revision-bound review (AC-3-1).
Any object carrying reviewed_revision (the revision_id the review was produced against) and reviewed_facets (the facets it covers) satisfies this — including the Phase 1 :class:~strands_teams.models.Finding and the lightweight :class:Review model. A runtime_checkable Protocol checks attribute presence only.
Review ¶
Bases: FrozenModel
A lightweight revision-bound review (AC-3-1).
A minimal record for callers that want to bind a review to an artifact revision without producing a full :class:~strands_teams.models.Finding. Immutable; reviewed_revision is the revision_id the review was produced against and reviewed_facets are the facets it covers (empty = the whole artifact).
Attributes:
| Name | Type | Description |
|---|---|---|
review_id | str | Identifier of the review. |
reviewed_revision | str | The |
reviewed_facets | list[str] | The artifact facets this review covers (empty = whole artifact — any changed facet invalidates it). |
summary | str | Optional human-readable summary of the review. |
ReviewVerdict ¶
Bases: FrozenModel
The structured outcome of :func:invalidates_review (AC-3-3, AC-3-4, AC-3-5).
Attributes:
| Name | Type | Description |
|---|---|---|
status | ReviewStatus |
|
reason | str | Human-readable explanation of the verdict. |
changed_facets | list[str] | Facets |
intersecting_facets | list[str] | The changed facets that the review covers (the invalidation trigger; empty when |
ReviewReconciliation ¶
Bases: FrozenModel
Result of reconciling a set of bound reviews against a promoted revision (AC-3-6).
Attributes:
| Name | Type | Description |
|---|---|---|
carried_forward | list[ReviewVerdict] | Reviews :func: |
reopened | list[ReviewVerdict] | Reviews reported as invalidated — must be recomputed against the new revision. |
errored | list[ReviewVerdict] | Reviews whose bound revision is not in the new revision's lineage (AC-3-5) — surfaced, never silently dropped. |
semantic_diff ¶
Return the set of artifact facets whose content changed between two revisions (AC-3-2).
Compares the two revisions' per-facet content hashes (:attr:~strands_teams.models.ArtifactRevision.facets). A facet is changed when its hash differs between the revisions, when it exists in only one of them (added or removed), and unchanged when both hashes are equal. The comparison is over hashes, not raw content, so it is exact and cheap.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
old_revision | ArtifactRevision | The earlier revision. | required |
new_revision | ArtifactRevision | The later revision. | required |
Returns:
| Type | Description |
|---|---|
set[str] | The set of changed facet names. Empty when the two revisions carry |
set[str] | identical facet content. |
Source code in packages/strands-teams/src/strands_teams/revisions.py
invalidates_review ¶
Decide whether new_revision invalidates a review bound to old_binding (AC-3-3..5).
Runs :func:semantic_diff between the revisions and intersects the changed facets with the facets the review covers:
- invalidated when the intersection is non-empty — a facet the review examined changed, so the review must be re-opened (AC-3-3).
- valid when the intersection is empty — the review's facets are untouched, so it is carried forward and reused rather than recomputed (AC-3-4). A review that covers no specific facets (empty
reviewed_facets) is treated as covering the WHOLE artifact, so any changed facet invalidates it. - error when
new_revision's lineage does not supersede the review's bound revision — the verdict cannot be trusted, so it is reported as an error rather than silently treated as valid or invalidated (AC-3-5).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
old_binding | ArtifactRevision | The revision the review was produced against. | required |
new_revision | ArtifactRevision | The candidate new revision. | required |
review | ReviewBinding | Any | A revision-bound review — a :class: | required |
Returns:
| Name | Type | Description |
|---|---|---|
A | ReviewVerdict | class: |
ReviewVerdict | intersecting facet sets. |
Source code in packages/strands-teams/src/strands_teams/revisions.py
reconcile_reviews ¶
Partition bound reviews into carried-forward, re-opened, and errored (AC-3-6).
When a re-run promotes a new revision of a logical artifact, every bound review that :func:invalidates_review reports as still valid is carried forward (reused), only the invalidated reviews are re-opened, and any lineage-mismatch review is surfaced as an error (AC-3-5, AC-3-6).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
old_binding | ArtifactRevision | The revision the reviews were produced against. | required |
new_revision | ArtifactRevision | The newly promoted revision. | required |
reviews | Iterable[ReviewBinding | Any] | The bound reviews to reconcile. | required |
Returns:
| Name | Type | Description |
|---|---|---|
A | ReviewReconciliation | class: |
Source code in packages/strands-teams/src/strands_teams/revisions.py
promote_artifact ¶
Promote a new revision of a logical artifact by optimistic compare-and-set.
Makes proposed_revision the current revision of logical_name ONLY when expected_current_revision still matches the alias's stored current revision — a durable optimistic lock. If another promotion changed the current revision since you read it, this returns a status="stale" error and leaves the alias unchanged; re-read the current revision and retry. Pass the sentinel "∅" as expected_current_revision for the FIRST promotion of a logical name.
The proposed revision's content is content-addressed: supply its content as proposed_revision={"facets": {"<facet>": "<content>", ...}} (preferred, so facet-level review invalidation works) or {"body": "<content>"}; the revision id and content hash are computed from that content. On success the prior current revision is recorded in the new revision's supersedes lineage.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
logical_name | str | The logical artifact to promote (e.g. | required |
expected_current_revision | str | The revision id you believe is current, or the sentinel | required |
proposed_revision | dict[str, Any] | The new revision's content as a JSON dict — | required |
tool_context | ToolContext | Framework-injected run context (invocation state). | required |
Returns:
| Type | Description |
|---|---|
str | On success, a JSON object with |
str |
|
str | when this was the first revision). On a failed compare-and-set, |
str |
|
str | you can re-read and retry. |