Define the protocol-neutral responsibility contract - #136
Conversation
|
Warning Review limit reachedYou’ve reached a temporary PR review limit under our Fair Usage Limits Policy. Next review available in: 40 minutes Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available. How can I continue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews. How do review limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (10)
📝 WalkthroughSummary by CodeRabbit
WalkthroughAdded protocol-neutral contracts for reusable delegation. The change adds fail-closed catalog validation, resolved action context, reviewed scopes, delegation evidence, owner review requests, responsibility manifests, drift assessment, tests, and OpenSpec records. ChangesResponsibility contract
Estimated code review effort: 4 (Complex) | ~60 minutes Sequence Diagram(s)sequenceDiagram
participant Kernel
participant ActionCatalog
participant OwnerReviewRequest
participant ResponsibilityManifest
Kernel->>ActionCatalog: resolve and validate delegation descriptors
ActionCatalog-->>Kernel: return validated action and implementation data
Kernel->>OwnerReviewRequest: bind resolved context, scope, and evidence
OwnerReviewRequest->>ResponsibilityManifest: create digest-bound review object
ResponsibilityManifest-->>Kernel: report Compatible or NeedsReview
Possibly related issues
Possibly related PRs
Poem
Caution Pre-merge checks failedPlease resolve all errors before merging. Addressing warnings is optional.
❌ Failed checks (2 errors)
✅ Passed checks (4 passed)
📋 Issue PlannerBuilt with CodeRabbit's Coding Plans for faster development and fewer bugs. View plan used: ✨ Finishing Touches 💡 1📝 Generate docstrings 💡
🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: a259a03931
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| if input.limits.quota.max == 0 | ||
| || input.limits.quota.window_secs <= 0 | ||
| || input.limits.rate.max == 0 | ||
| || input.limits.rate.window_secs <= 0 | ||
| || input.limits.expires_after_secs <= 0 | ||
| { |
There was a problem hiding this comment.
Enforce catalog bounds on reviewed limits
When a proposal supplies explicit or narrowed limits, this validation accepts every positive quota, rate, window, and expiry. validate_policy only checks catalog defaults, so a review can be successfully constructed and digest-bound with values above the action's DelegationPolicyBounds—for example, quota 21 for the email.create_draft maximum of 20 or an expiry beyond 90 days. Validate ReviewLimits against the selected action policy before returning a review request.
Useful? React with 👍 / 👎.
| impl ProposalProvenance { | ||
| pub fn from_evidence(evidence: &DelegationEvidence, summary: String) -> Self { | ||
| Self { | ||
| schema_version: 1, | ||
| kind: evidence.kind(), | ||
| summary, | ||
| evidence_digest: evidence.provenance_digest().clone(), | ||
| evidence_count: evidence.evidence_count(), | ||
| } |
There was a problem hiding this comment.
Reject invalid evidence when creating provenance
When evidence has been rehydrated from storage, this constructor copies its claimed kind, count, and digest without calling integrity_is_valid(). A tampered repeated-approval record—for example, one whose approval_count was changed while retaining the old evidence-set digest—therefore produces provenance that OwnerReviewRequest::try_new accepts and binds as if it were valid. Make provenance construction fail for evidence that does not pass its integrity check.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
Actionable comments posted: 8
🧹 Nitpick comments (7)
openspec/openspine-change-sequence.md (1)
504-517: 🗄️ Data Integrity & Integration | 🔵 Trivial | ⚡ Quick winKeep effect-executor failures on the post-approval path.
State that
effect-executoris separate fromActionHandlerRegistry. Apply typed missing-executor failures to approved or delegated effect execution and readiness checks. Preserve the honest stub for known allowed actions without direct handlers.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@openspec/openspine-change-sequence.md` around lines 504 - 517, Update unify-approved-and-delegated-effect-execution to explicitly separate the kernel-owned effect-executor registry from ActionHandlerRegistry. Apply typed missing-executor failures only to post-approval approved/delegated effect execution and its readiness checks, while preserving the honest successful stub for known allowed actions that lack direct handlers.crates/openspine-schemas/tests/responsibility_contract.rs (2)
180-187: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick winAssert the exact mismatch set.
The loop checks membership only. An implementation that reported every dimension as mismatched would still pass. The four changed inputs are
connector_instance_id,account_identity_digest,target_refs[0].id, andworkflow_id, so the expected set is exact.🧪 Proposed assertion
- for expected in [ - ReviewedScopeDimension::ConnectorInstance, - ReviewedScopeDimension::AccountIdentity, - ReviewedScopeDimension::Target, - ReviewedScopeDimension::Workflow, - ] { - assert!(dimensions.contains(&expected)); - } + assert_eq!( + dimensions, + BTreeSet::from([ + ReviewedScopeDimension::ConnectorInstance, + ReviewedScopeDimension::AccountIdentity, + ReviewedScopeDimension::Target, + ReviewedScopeDimension::Workflow, + ]) + );🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@crates/openspine-schemas/tests/responsibility_contract.rs` around lines 180 - 187, Update the assertions around the ReviewedScopeDimension loop to verify that dimensions contains exactly the four expected values—ConnectorInstance, AccountIdentity, Target, and Workflow—with no additional mismatches. Use an exact set comparison or equivalent length-and-membership checks rather than membership assertions alone.
190-207: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winAdd coverage for
validate_policyrejection branches.The tests cover descriptor completeness, scope breadth, and dark-window allow. They do not reach
validate_policy.DelegationEligibilityError::InvalidPolicyBoundsandDelegationEligibilityError::DefaultOutOfBoundshave no test, andvalidate_policyis the check that keeps catalog-authored quota, rate, and lapse values sane.Useful cases: an inverted quota range, a zero
policy_version, a default quota abovemaximum_max, a defaultexpires_after_secsabovemaximum_lapse_secs, andExplicitLimitsRequiredcombined withSome(defaults).I can generate these tests if you want.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@crates/openspine-schemas/tests/responsibility_contract.rs` around lines 190 - 207, Add tests exercising validate_policy rejection branches in the existing responsibility-contract test module: cover inverted quota bounds, zero policy_version, defaults exceeding maximum_max or maximum_lapse_secs, and ExplicitLimitsRequired with Some(defaults). Assert each case returns the appropriate DelegationEligibilityError variant, reusing the existing policy/catalog builders and validation entry points.crates/openspine-schemas/tests/responsibility_review_contract.rs (2)
251-263: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winAdd coverage for the required-decision and required-control rejections.
The test supplies all four decisions and all four lifecycle controls, so
try_newalways takes the success path.OwnerReviewRequestError::MissingRequiredDecisionsandOwnerReviewRequestError::MissingRequiredControlsare never exercised.These two checks guarantee that the owner always keeps
RejectandRevokeavailable. RemovingOwnerReviewDecision::Rejectfromavailable_decisions, and removingResponsibilityLifecycleControl::Revokefromlifecycle_controls, would pin that property.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@crates/openspine-schemas/tests/responsibility_review_contract.rs` around lines 251 - 263, Extend the responsibility review contract tests around try_new to cover missing required entries: create cases that omit OwnerReviewDecision::Reject and assert OwnerReviewRequestError::MissingRequiredDecisions, and omit ResponsibilityLifecycleControl::Revoke and assert OwnerReviewRequestError::MissingRequiredControls. Keep the existing complete-set success case unchanged.
32-133: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueConsider sharing the test fixtures.
digest,descriptor,implementation, andcontext_inputare near-duplicates ofcrates/openspine-schemas/tests/responsibility_contract.rslines 18-115. Only the version literals differ, and that divergence is deliberate so thatassesscan distinguish which version drifted.A shared
tests/common/mod.rswith version parameters would remove the duplication and keep the intentional differences explicit.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@crates/openspine-schemas/tests/responsibility_review_contract.rs` around lines 32 - 133, Share the duplicated test fixtures digest, descriptor, implementation, and context_input through tests/common/mod.rs, parameterizing the version literals needed by each contract test. Update responsibility_review_contract.rs and responsibility_contract.rs to reuse these helpers while keeping their deliberate version differences explicit so assess can still detect which version drifted.crates/openspine-schemas/src/owner_review.rs (1)
225-244: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winConsider deriving the digest input from serialization.
The digest map lists all 16 public fields explicitly. The list is correct today. A future field added to
OwnerReviewRequestbut not to this map would silently drop out of the binding, and no compiler error or test would report it.Building the digest input from
serde_json::to_value(self)and removing thebinding_digestkey keeps the coverage automatic. The same pattern applies toReviewedActionScope::calculate_context_class_digest, which already digests its whole field set.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@crates/openspine-schemas/src/owner_review.rs` around lines 225 - 244, Update OwnerReviewRequest::calculate_binding_digest to derive its digest input from serde_json::to_value(self), remove the binding_digest field from the resulting object, and digest the remaining serialized fields instead of maintaining an explicit field list. Apply the same serialization-based approach to ReviewedActionScope::calculate_context_class_digest, preserving its existing digest behavior.crates/openspine-kernel/src/action_catalog.rs (1)
97-97: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winConsider a completeness test for delegation descriptor ids.
The comment at lines 80-83 states the catalog convention: an id added without its row must be a review-visible failure. Delegation descriptors have no equivalent assertion. If a future descriptor names an id that is absent from
ids,validated_delegation_contractreturnsUnknownActionand delegation silently never becomes available for that action.The behavior fails closed, so this is coverage, not a defect.
🧪 Proposed test
#[test] fn every_delegation_descriptor_names_a_catalogued_action() { let catalog = canonical_catalog(); for descriptor in action_catalog_data::delegation_descriptors() { assert!( catalog.contains(&descriptor.action_id), "delegation descriptor {} is not a catalogued action", descriptor.action_id ); } }🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@crates/openspine-kernel/src/action_catalog.rs` at line 97, Add a completeness test alongside the existing catalog tests for `canonical_catalog` that iterates over `action_catalog_data::delegation_descriptors()` and asserts each descriptor’s `action_id` is present in the catalog, including the action id in any failure message.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In @.raw/openspine-decision-log.md:
- Line 3514: Update the date in the D-146 changelog entry to 2026-08-02 so it
matches the current date and archive directory convention; leave the rest of the
entry unchanged.
In `@crates/openspine-schemas/src/delegation_contract.rs`:
- Around line 84-94: Update DataDestination::is_communication_or_connector_write
to include Self::ExternalService in the matched destinations, ensuring
validate_delegation_contract applies the conservative reviewed-scope
requirements and rejects DarkWindowPolicy::BoundedAllow for external-service
destinations.
- Around line 295-311: The communication scope floor in the descriptor
eligibility check must require ReviewedScopeDimension::Counterparty. Add it to
the minimum dimensions used by is_communication_or_connector_write(), and add a
regression test covering a CounterpartyCommunication descriptor that omits
Counterparty and is rejected.
In `@crates/openspine-schemas/src/owner_review.rs`:
- Around line 163-170: Update OwnerReviewRequest::try_new to accept the
applicable DelegationPolicyBounds and validate quota and rate limits with
BudgetWindowBounds::contains, while rejecting expiry values above the policy
ceiling as well as existing non-positive values before constructing the review
request. Make BudgetWindowBounds::contains public so owner_review.rs can perform
this validation, and update the constructor signature for future callers.
In `@crates/openspine-schemas/src/resolved_context.rs`:
- Around line 108-113: Update try_new_with_classifications so egress_class,
disclosure_class, and output_channels are sourced from the ActionCatalog
declaration rather than trusted caller-provided ResolvedActionClassifications;
alternatively, explicitly restrict this constructor to kernel-only use and
enforce that callers provide catalog-derived values. Preserve
reviewed_scope::value_for behavior and the catalog-ownership rule for
enforcement.
- Around line 48-51: Remove the `Deserialize` derive from
`ResolvedActionContext` to preserve its sealed construction path through
`try_new`, keeping the existing `Serialize` support and validation guarantees
intact.
In `@crates/openspine-schemas/src/responsibility.rs`:
- Around line 79-89: Update ResponsibilityManifest::assess to evaluate the
manifest’s lifecycle status before returning compatibility; ensure Revoked,
Expired, and Paused statuses cannot produce
ResponsibilityAssessment::Compatible, while preserving the existing context,
scope, and version checks for active responsibilities.
In `@openspec/specs/kernel-registries/spec.md`:
- Around line 101-111: Scope the fail-closed catalog behavior to requests for
reusable-delegation readiness, preserving existing composition for
known-but-unimplemented actions and stub responses for missing direct handlers.
Apply this clarification in the requirement and scenario at
openspec/specs/kernel-registries/spec.md lines 101-111 and the corresponding
archived requirement at
openspec/changes/archive/2026-08-02-define-responsibility-contract/specs/kernel-registries/spec.md
lines 5-15.
---
Nitpick comments:
In `@crates/openspine-kernel/src/action_catalog.rs`:
- Line 97: Add a completeness test alongside the existing catalog tests for
`canonical_catalog` that iterates over
`action_catalog_data::delegation_descriptors()` and asserts each descriptor’s
`action_id` is present in the catalog, including the action id in any failure
message.
In `@crates/openspine-schemas/src/owner_review.rs`:
- Around line 225-244: Update OwnerReviewRequest::calculate_binding_digest to
derive its digest input from serde_json::to_value(self), remove the
binding_digest field from the resulting object, and digest the remaining
serialized fields instead of maintaining an explicit field list. Apply the same
serialization-based approach to
ReviewedActionScope::calculate_context_class_digest, preserving its existing
digest behavior.
In `@crates/openspine-schemas/tests/responsibility_contract.rs`:
- Around line 180-187: Update the assertions around the ReviewedScopeDimension
loop to verify that dimensions contains exactly the four expected
values—ConnectorInstance, AccountIdentity, Target, and Workflow—with no
additional mismatches. Use an exact set comparison or equivalent
length-and-membership checks rather than membership assertions alone.
- Around line 190-207: Add tests exercising validate_policy rejection branches
in the existing responsibility-contract test module: cover inverted quota
bounds, zero policy_version, defaults exceeding maximum_max or
maximum_lapse_secs, and ExplicitLimitsRequired with Some(defaults). Assert each
case returns the appropriate DelegationEligibilityError variant, reusing the
existing policy/catalog builders and validation entry points.
In `@crates/openspine-schemas/tests/responsibility_review_contract.rs`:
- Around line 251-263: Extend the responsibility review contract tests around
try_new to cover missing required entries: create cases that omit
OwnerReviewDecision::Reject and assert
OwnerReviewRequestError::MissingRequiredDecisions, and omit
ResponsibilityLifecycleControl::Revoke and assert
OwnerReviewRequestError::MissingRequiredControls. Keep the existing complete-set
success case unchanged.
- Around line 32-133: Share the duplicated test fixtures digest, descriptor,
implementation, and context_input through tests/common/mod.rs, parameterizing
the version literals needed by each contract test. Update
responsibility_review_contract.rs and responsibility_contract.rs to reuse these
helpers while keeping their deliberate version differences explicit so assess
can still detect which version drifted.
In `@openspec/openspine-change-sequence.md`:
- Around line 504-517: Update unify-approved-and-delegated-effect-execution to
explicitly separate the kernel-owned effect-executor registry from
ActionHandlerRegistry. Apply typed missing-executor failures only to
post-approval approved/delegated effect execution and its readiness checks,
while preserving the honest successful stub for known allowed actions that lack
direct handlers.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 61ef53e5-8e87-4037-8e5c-ce94d950f5ed
📒 Files selected for processing (23)
.raw/openspine-decision-log.mdcrates/openspine-kernel/src/action_catalog.rscrates/openspine-kernel/src/action_catalog_data.rscrates/openspine-schemas/src/action.rscrates/openspine-schemas/src/delegation_contract.rscrates/openspine-schemas/src/delegation_evidence.rscrates/openspine-schemas/src/lib.rscrates/openspine-schemas/src/owner_review.rscrates/openspine-schemas/src/resolved_context.rscrates/openspine-schemas/src/responsibility.rscrates/openspine-schemas/src/reviewed_scope.rscrates/openspine-schemas/tests/responsibility_contract.rscrates/openspine-schemas/tests/responsibility_review_contract.rsopenspec/changes/archive/2026-08-02-define-responsibility-contract/design.mdopenspec/changes/archive/2026-08-02-define-responsibility-contract/proposal.mdopenspec/changes/archive/2026-08-02-define-responsibility-contract/specs/core-runtime-schemas/spec.mdopenspec/changes/archive/2026-08-02-define-responsibility-contract/specs/kernel-registries/spec.mdopenspec/changes/archive/2026-08-02-define-responsibility-contract/specs/responsibility-contract/spec.mdopenspec/changes/archive/2026-08-02-define-responsibility-contract/tasks.mdopenspec/openspine-change-sequence.mdopenspec/specs/core-runtime-schemas/spec.mdopenspec/specs/kernel-registries/spec.mdopenspec/specs/responsibility-contract/spec.md
| | 2026-07-24 | Added D-123 (production adoption at ambiguous route resolution), D-124 (canonical tied candidate ids), D-125 (lexicographic within-class selection), D-126 (invalid/failed competitors escalate), D-127 (all-non-applicable ties are silent non-matches), D-128 (rated-egress production guard), and D-129 (persist the selected composition snapshot), settled while implementing `wire-authority-equivalence-selection`. | | ||
| | 2026-07-24 | Added D-130–D-141 (pure proposed-only miner boundary, authenticated bounded grants, verified encrypted-reference evidence, derived exact-match repetition, correction/probe separation, fail-closed provenance, independent durable budgets, scoped consolidation, declarative scheduled grant composition, and owner-bound cross-grant evidence), settled while implementing `implement-reflection-miner`. | | ||
| | 2026-07-24 | Added D-142 (native OAuth 2.0 PKCE authentication), D-143 (encrypted vault storage in SecretStore), D-144 (preemptive single-flight background token refresher), and D-145 (gateway bearer token resolution with automatic single-retry on 401), settled while implementing `implement-model-provider-oauth-onboarding`. | | ||
| | 2026-08-03 | Added D-146 (protocol-neutral two-axis responsibility contract; responsibility remains a reference view over workflow/standing-rule inputs; communication dark-window Allow forbidden; drift fails to `needs_review`), settled while implementing `define-responsibility-contract`. | |
There was a problem hiding this comment.
📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win
Use a consistent change-log date.
Line 3514 records 2026-08-03, but the current date is August 2, 2026 and the archive directory is dated 2026-08-02. Change the entry to 2026-08-02.
Proposed fix
-| 2026-08-03 | Added D-146 ...
+| 2026-08-02 | Added D-146 ...📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| | 2026-08-03 | Added D-146 (protocol-neutral two-axis responsibility contract; responsibility remains a reference view over workflow/standing-rule inputs; communication dark-window Allow forbidden; drift fails to `needs_review`), settled while implementing `define-responsibility-contract`. | | |
| | 2026-08-02 | Added D-146 (protocol-neutral two-axis responsibility contract; responsibility remains a reference view over workflow/standing-rule inputs; communication dark-window Allow forbidden; drift fails to `needs_review`), settled while implementing `define-responsibility-contract`. | |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In @.raw/openspine-decision-log.md at line 3514, Update the date in the D-146
changelog entry to 2026-08-02 so it matches the current date and archive
directory convention; leave the rest of the entry unchanged.
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@crates/openspine-schemas/tests/responsibility_contract.rs`:
- Line 275: Update each ReviewedActionScope::derive call in the affected test
cases to pass both required arguments, descriptor and context, in the order
required by the method signature. Apply this at the calls around lines 275, 310,
and 368 while preserving the existing test setup and assertions.
- Around line 319-338: Update
resolved_context_fails_closed_without_catalog_classifications to match the
current ResolvedActionContext::try_new signature by passing only its three
accepted arguments, and assert the corresponding existing
ResolvedActionContextError variant for missing catalog classifications instead
of the undefined MissingCatalogEgressDeclaration variant.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 6c4cff41-34b7-47dd-9fbf-2548b61e6500
📒 Files selected for processing (1)
crates/openspine-schemas/tests/responsibility_contract.rs
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 5e8233e8b2
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| let provenance = | ||
| ProposalProvenance::try_from_evidence(&input.evidence, input.provenance_summary) | ||
| .map_err(|_| OwnerReviewRequestError::InvalidEvidence)?; |
There was a problem hiding this comment.
Bind repeated evidence to the reviewed scope
When valid repeated-approval evidence is supplied with a context_class_digest different from input.reviewed_scope.context_class_digest(), this constructor still accepts and digest-binds the review. This lets approvals observed for one context be presented as provenance for a different connector, account, target, or workflow scope; explicitly compare these digests for RepeatedApprovals before constructing the review.
Useful? React with 👍 / 👎.
| Ok(Self { | ||
| schema_version: 1, | ||
| kind: evidence.kind(), | ||
| summary, | ||
| evidence_digest: evidence.provenance_digest().clone(), | ||
| evidence_count: evidence.evidence_count(), |
There was a problem hiding this comment.
Prevent non-pattern evidence from claiming a pattern
When the evidence is an explicit owner request, correction proposal, or manual artifact, callers can still set summary to text such as “Lyra noticed a pattern,” and this semantic owner-review object accepts and binds that misleading claim. Although supports_pattern_claim() exists, it is never enforced here, so pattern provenance needs a structured flag or validation that only permits it for repeated approvals.
Useful? React with 👍 / 👎.
Summary
Defines the protocol-neutral responsibility contract required by #126.
email.create_draftwhile deliberately failing closed until Unify approved and delegated effect execution; fail closed on missing executors #127 provides the shared reusable implementation;TDD
Red
Green
Verification
cargo fmt --check;cargo clippy --workspace --all-targets -- -D warnings;openspec validate --all --strict— 44/44;git diff --check.Closes #126.