Skip to content

feat: a standing grant, and the judgment of one call under it (greenhouse decisions/0615) - #81

Merged
rodrigoteamx merged 3 commits into
mainfrom
feat/standing-grant-judgment
Oct 11, 2026
Merged

rodrigoteamx merged 3 commits into
mainfrom
feat/standing-grant-judgment

Conversation

@rodrigoteamx

@rodrigoteamx rodrigoteamx commented Oct 11, 2026 •

Copy link
Copy Markdown
Contributor

The contract behind greenhouse decisions/0615 (stage 3 of decisions/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 the milpa/app-runtime pull 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 — null for 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 of actsOn.
  • 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

StandingGrant refuses, at construction: a ceiling with an unclassified axis; a ceiling above compensatable; a ceiling whose authority is above write_as_user; covering any standing.* operation; a grant with no condition; a falsifier nothing watches; and any key it does not read. These are the floors decided for decisions/0615; the last is how "money cannot be expressed" is made honest — a "budget": 50 is 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:

  • The floor «never an operation that itself gives authority» was a word the host looked for. Measured on the published catalogue: 13 operations declare institutional authority and only 4 ask for that word. A ceiling above write_as_user on the authority axis is now refused here.
  • 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 (reproduced: it passed). 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, because it is a class of acts, and free is refused there.
  • A grant that supersedes a suspended one may say which suspension it lifts (lifts), so that a host can hold superseding to the standard of reinstating.

What it does not do

  • Money. There is no effect axis for it, so no ceiling bounds spend, and nothing says an operation spends. The README says so.
  • instrumentDigest() carries the limit handlerDigest() already declares: a handler that delegates changes behaviour without changing the digest.
  • What a grant covers matches when each fixed argument is carried with that value; arguments it does not fix are free. Instruments and watchers are matched closed.

Checked

  • vendor/bin/phpunit --testsuite Command: 338 tests, 1049 assertions; line coverage 100.00% (1270/1270).
  • php-cs-fixer, PHPStan, the docblock gate and the attribution gate pass.
  • Mutation self-test (greenhouse scripts/lab/standing-grant-1194/mutants.php with mutants-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.
  • The tests were written after the code, not red first; the mutants are what shows they distinguish.

Compatibility

Additive. actsOn is the last optional constructor argument of Operation; positional callers are untouched. handlerDigest() answers as before.

…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.
@rodrigoteamx
rodrigoteamx merged commit a7a87a9 into main Oct 11, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant