Prerequisites
Complete Run an Example Policy Locally. Use the same starter checkout and run commands from its root.1. Run the Allowed Case
transferOwnership with the current owner. The owner remains unchanged, so the rule passes. The output should include:
assertions/test/OwnableAssertion.t.sol and locate this test. Notice that it registers the assertion before making the external call.
2. Run the Rejected Case
assertions/test/OwnableAssertion.t.sol and find test_assertionOwnershipChanged(). Here, assertionAdopter is the example Ownable contract, initialOwner is its current owner, and newOwner is a different address:
cl.assertion() registers the ownership rule for the transfer under test. vm.prank(initialOwner) makes the call as the current owner, so it satisfies the contract’s onlyOwner check. The assertion still rejects the transfer because the owner would change.
vm.expectRevert("Ownership has changed") checks for that specific rejection. The final assertEq confirms that the attempted transfer was rolled back and the original owner remains in place.
The output should include:
3. Examine a Legitimate Exception
Now consider a planned transfer to a replacement governance contract. The owner would still change, so the same rule would reject it. The example has no input that represents governance approval or an approved destination. Record the results:
The first two rows are test results. The third follows from the rule’s logic and is not an executed test.

