The validation looks correct, I've tested this in my dev org. If you want to make it more clever like to allow you to change the Level to "Archived" after it has been "Closed", you can add something like this:
AND(
$Profile.Name <> 'System Administrator',
NOT(ISNEW()),
OR(
AND(
ISPICKVAL(PRIORVALUE(Level__c), "Closed"),
NOT(ISPICKVAL(Level__c, "Archived"))
),
ISPICKVAL(PRIORVALUE(Level__c), "Archived")
)
)
Also ensure that you have no other processes that run after you update the field, that in turn also update the opportunity record. If that is the case you will need to add the fields that are being updated as exceptions in the validation. (Or extent the process to also lock the record as advised above)
The system will evaluate custom validation rules and allow you to save the record. If after your changes are done an automated process runs and updates the same record, validation rules will fire again at which point PRIORVALUE() function is the current value. This could be confusing but everything happens at the same time you are waiting for it to be saved. https://architect.salesforce.com/fundamentals/architecture-basics
Also, to help with testing and reduce confusion, remove this line $Profile.Name <> 'System Administrator' from your validation and use the Active checkbox on your validation during testing. Once you have it working for all profiles then you can add the line back with the exception.
Hope this helps. Seems like you are on the correct track anyways.
Lever
is set to Archived or Closed. We are using a standard record locking for closed opportunities and this could be set by Approval, Process Builder or in Apex code (e.g. in a trigger) - let me know if you are interested to get more details.