Skip to content

feat(status): on-behalf v→V/d→D assertion and Vendor-implies-V invariant - #3102

Open
sei-ahouseholder wants to merge 3 commits into
mainfrom
task/3057-on-behalf-rm-state-assertion
Open

feat(status): on-behalf v→V/d→D assertion and Vendor-implies-V invariant#3102
sei-ahouseholder wants to merge 3 commits into
mainfrom
task/3057-on-behalf-rm-state-assertion

Conversation

@sei-ahouseholder

Copy link
Copy Markdown
Contributor

Summary

Implements ADR-0084's narrow externally-evidenced on-behalf assertion exceptions
and the Vendor-participation-implies-V invariant, closing the vendor-awareness
gap (CONCERN-2087).

Changes

  • vultron/core/predicates/participants.py: vendor_vf_invariant_ok(roles, vf_state) predicate — returns False when a VENDOR-role actor asserts CS_vf.vf (AC-4, PRM-06-002)
  • vultron/core/behaviors/case/nodes/vfd_role_guards.py: CheckOnBehalfAuthorizedNode (gates CM/CO for on-behalf path) and EnsureOnBehalfParticipantExistsNode (creates minimal CaseParticipant with required roles when absent) (AC-1/AC-2)
  • vultron/core/behaviors/case/nodes/participant/trigger_validation.py: _check_vf_role enforces Vendor-implies-V invariant via predicate (AC-4)
  • vultron/core/behaviors/case/nodes/participant/status.py: _check_vf_precondition enforces Vendor-implies-V invariant (AC-4)
  • vultron/core/use_cases/triggers/requests.py: AddOnBehalfStatusTriggerRequestvf_state=CS_vf.VF rejected at boundary (AC-3); all-None request rejected (requires ≥1 dimension)
  • vultron/core/behaviors/case/add_on_behalf_status_trigger_tree.py (new): BT tree for on-behalf assertion (AC-1/AC-2, BT-15-001)
  • vultron/core/use_cases/triggers/case/add_on_behalf_status.py (new): SvcAddOnBehalfStatusUseCase (AC-1/AC-2)
  • specs/participant-role-management.yaml: PRM-06 group — 5 new spec entries for self-declaratory default, Vendor-implies-V invariant, v→V/d→D on-behalf MAY, and f→F Vendor-only MUST NOT (AC-5)
  • Tests: 8 new predicate tests, 8 new use-case tests; updated existing test to use CS_vf.Vf for vendor (now required by AC-4)

Deferred findings

Verification

  • 8289 unit tests pass (8 new), 1254 integration tests pass
  • Black, flake8, mypy, pyright all clean

ahouseholder and others added 2 commits September 2, 2026 21:11
…ant (closes #3057)

Implements ADR-0084's narrow externally-evidenced on-behalf exceptions
and the Vendor-participation-implies-V invariant:

- AC-1/AC-2: SvcAddOnBehalfStatusUseCase + AddOnBehalfStatusTriggerRequest
  let a Case Manager or Case Owner assert v→V (CS_vf.Vf) or d→D on behalf
  of a notified-but-not-joined vendor/deployer.
- AC-3: f→F (CS_vf.VF) is rejected at the request boundary.
- AC-4: vendor_vf_invariant_ok predicate enforced on both trigger and BT paths.
- AC-5: PRM-06 group added to specs/participant-role-management.yaml.
- AC-6: Tests in test_participants.py and test_add_on_behalf_status.py.

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
- FAIL: EnsureOnBehalfParticipantExistsNode required_role → required_roles
  (list) so combined vf+d on-behalf requests create a participant with both
  VENDOR and DEPLOYER roles instead of silently failing the DEPLOYER check.
- FAIL: AddOnBehalfStatusTriggerRequest now requires at least one of vf_state
  or d_state to be non-None; an all-None request is rejected at the model
  boundary with a clear ValidationError.
- IMPROVE: _create_and_attach_participant import moved from tick-time (inside
  update()) to module level in vfd_role_guards.py so renames are visible to
  static analysis.

Filed #3100 (cross_machine_violations bypass paths) and #3101 (stale
BB_LEDGER_PAYLOAD_OBJECT_OVERRIDE) as pre-existing DEFER findings.

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
…VultronValidationError (#3100, #3103)

Under the new completeness doctrine these first-order findings in files already
touched by this PR are fixed now rather than deferred.

- #3100: CreateParticipantStatusNode._validate_transitions() now calls
  cross_machine_violations() after per-dimension checks, so bypass callers
  (DevelopFixNode, DeployFixNode, etc.) cannot persist a state that
  ValidateTriggerTransitionsNode._validate_entailments() would have refused.
  Adds eff_rm parameter through the call chain.
- #3103: ValidateTriggerTransitionsNode.update() now catches
  VultronValidationError from resolve_participant_state_from_dl() via a
  _resolve_current_state() helper, returning Status.FAILURE with a diagnostic
  message. The PXA check is also extracted to _check_pxa_transition() to keep
  update()'s McCabe complexity at or below the project limit of 10.
- 2 new regression tests in test_add_participant_status.py.

Deferred: #3101 (BB_LEDGER_PAYLOAD_OBJECT_OVERRIDE stale on case-not-found path)
is second-order and entangled with open concern #2711; requires careful
port-ownership reasoning beyond this PR's scope.

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:M 51-300 diff lines or 3-6 ACs

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Implement on-behalf v→V / d→D awareness assertion and enforce Vendor-implies-V invariant

2 participants