DeclaredAuthorityPolicy
An institutional policy declared as a rule table — in reviewed code, like the certifier's public key (greenhouse decisions/0051): a path the forgery of `evidence/0249` does not control. Deliberately small. A rule says: for THIS operation, a principal whose verified scopes include ALL of these gets THIS effective authority. Anything the table does not say is a refusal, not a default — `evidence/0237` measured that the only gate treating the bot and the human alike was the one that denied by default.
DeclaredAuthorityPolicy::__construct()
public function __construct(string $id, array $rules):Parameters
| Name | Type | Description |
|---|---|---|
| $id | string | who this policy is, for the receipt |
| $rules | array<string, array{scopes: list<string>, authority: Authority}> | operation → what its rule demands and grants |
DeclaredAuthorityPolicy::judge()
public function judge(Milpa\Command\Effect\ContextFacts $facts, Milpa\Command\Effect\CallSubject $subject): ?Milpa\Command\Effect\AuthorityClaimJudge this call against the declared table, or refuse — and refusal is the default. The three refusals are deliberate and ordered: hearsay first (unverified facts judge nothing), then the missing rule (deny by default), then the missing scope. No judgment means no claim, and without a claim the authority axis does not come down.
Parameters
| Name | Type | Description |
|---|---|---|
| $facts | Milpa\Command\Effect\ContextFacts | |
| $subject | Milpa\Command\Effect\CallSubject |
DeclaredAuthorityPolicy::digest()
public function digest(): stringThe exact version of the rules doing the judging. Scopes and operations are sorted before hashing so the digest names the RULES, not the order someone happened to type them in — editing a rule re-versions the policy, reordering it does not (the same canonicalisation lesson the signed certificate paid for in decisions/0051).