Repository navigation
feat: a standing grant, and the judgment of one call under it (greenhouse decisions/0615) - #81
Merged
Merged
Conversation
…ouse decisions/0615) The only way to let a seat repeat an act was to hand it the scope whole: no ceiling, no condition, nothing to take it back when the evidence changes. This is the contract of something narrower, with no I/O in it. - Operation::$actsOn declares what content a call acts on, as a digest derived from the bytes; actsOnDigest() reads it, and instrumentDigest() pins the operation that measures (its declaration, its handler, what it says it acts on). - StandingGrant is the document a person signs: seats, named calls, an effect ceiling, conditions each measured by an operation, how an act is undone, a watched falsifier. It refuses, at construction, a ceiling with an unclassified axis or above compensatable, covering any standing.* operation, a grant with no condition, a falsifier nothing watches, and any key it does not read. - ConditionReceipt is the fact a measurement leaves: which operation, over which content, said what, as which instrument. - StandingJudge::judge() asks seven things in order and only refuses or lets pass: named, signature, in force, watched, subject, ceiling, conditions. A grant that does not name the call says so and nothing else. A measurement and an act are joined by content, never by clock. Money is not expressible: there is no effect axis for it, and the README says so.
…es it One grant that passes used to be enough. That let a second grant walk around a suspension, which is the permissive reading and runs against the asymmetry: shrinking wins. StandingJudge::among() now says how the answers of several grants combine: - a grant that names the call and is suspended refuses it, whatever another would lend, until a person lifts that suspension or gives a grant that supersedes it by name; - expired, revoked and superseded grants stop nobody; - otherwise one grant that passes is enough, and when none does the refusal that got furthest speaks, the later grant's on a tie. It adds no criterion to the judgment of any single grant.
…, instruments matched closed, a lifted suspension named Three things a security review found in the contract, each reproduced before it was fixed (greenhouse decisions/0615): - The floor «never an operation that itself gives authority» was left to a word the host looked for. A ceiling above write_as_user on the authority axis is now refused here: measured on the published catalogue, thirteen operations declare institutional authority and four of them ask for that word. - A condition's instrument and a falsifier's watcher matched any call that carried the fixed arguments, so a later green run with an argument that weakens it covered a red one. They are now matched closed (NamedCall::matchesExactly): besides the fixed arguments a call may carry only those listed in «free». What a grant covers stays open — it is a class of acts — and «free» is refused there, where nothing would read it. - A grant that supersedes a suspended one may now say which suspension it lifts («lifts»), so that a host can ask of superseding what it asks of reinstating.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The contract behind greenhouse
decisions/0615(stage 3 ofdecisions/0613): a standing grant, the receipt of a condition, and the judgment of one call under a grant. No I/O in any of it — the host that enforces it is themilpa/app-runtimepull request that depends on this one.Why
The only way to let a seat repeat an act was to hand it the scope whole: no ceiling, no condition, nothing to take it back when the evidence changes. Two things happened on one day because of that — a condition of a mandate was measured after the act it guarded, and a class of acts went on being exercised after its mandate had suspended itself. This is the shape of something narrower.
What is added
Operation::$actsOn(last constructor argument, optional): what content a call acts on, as a digest derived from the bytes its arguments lead to.actsOnDigest()reads it —nullfor every way of not knowing.instrumentDigest()pins an operation as the instrument it is today: its identity, inputs, declared effects, the body of its handler and the body ofactsOn.Standing\StandingGrant: the document a person signs — seats, named calls, an effect ceiling, conditions (each measured by a named call), how an act is undone, a watched falsifier, an optional expiry. One canonical spelling and a digest.Standing\ConditionReceipt: which operation, over which content, said what, as which instrument.Standing\StandingJudge::judge(): seven checks in order — named, signature, in force, watched, subject, ceiling, conditions. It refuses or lets pass; it never grants, widens or restores. A grant that does not name the call says exactly that.Standing\StandingJudge::among(): one call under every grant a host holds. Shrinking wins: a grant that names the call and is suspended refuses it, whatever another would lend, until a person lifts that suspension or gives a grant that supersedes it by name. Expired, revoked and superseded grants stop nobody. Otherwise one grant that passes is enough; when none does, the refusal that got furthest speaks, the later grant's on a tie.A measurement and an act are joined by content, never by clock.
What cannot be written at all
StandingGrantrefuses, at construction: a ceiling with an unclassified axis; a ceiling abovecompensatable; a ceiling whose authority is abovewrite_as_user; covering anystanding.*operation; a grant with no condition; a falsifier nothing watches; and any key it does not read. These are the floors decided fordecisions/0615; the last is how "money cannot be expressed" is made honest — a"budget": 50is refused rather than ignored.After an independent security review
The reviewer traced code and ran nothing, so each finding was reproduced by a red test (or by execution) before it was fixed. Three of them were in this contract:
write_as_useron the authority axis is now refused here.NamedCall::matchesExactly(): besides the fixed arguments a call may carry only those listed infree. What a grant covers stays open, because it is a class of acts, andfreeis refused there.lifts), so that a host can hold superseding to the standard of reinstating.What it does not do
instrumentDigest()carries the limithandlerDigest()already declares: a handler that delegates changes behaviour without changing the digest.Checked
vendor/bin/phpunit --testsuite Command: 338 tests, 1049 assertions; line coverage 100.00% (1270/1270).scripts/lab/standing-grant-1194/mutants.phpwithmutants-command.json): 38 mutants — one per check of the judge, one per floor, the matching and digest rules, nine for how several grants combine, and seven for the review's fixes — each caught by the suite. The instrument's own controls hold: the untouched tree passes, and a mutant that changes nothing is reported as surviving.Compatibility
Additive.
actsOnis the last optional constructor argument ofOperation; positional callers are untouched.handlerDigest()answers as before.