Rulealize.RuleSet.Request 1.0.0

dotnet add package Rulealize.RuleSet.Request --version 1.0.0
                    
NuGet\Install-Package Rulealize.RuleSet.Request -Version 1.0.0
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Rulealize.RuleSet.Request" Version="1.0.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Rulealize.RuleSet.Request" Version="1.0.0" />
                    
Directory.Packages.props
<PackageReference Include="Rulealize.RuleSet.Request" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Rulealize.RuleSet.Request --version 1.0.0
                    
#r "nuget: Rulealize.RuleSet.Request, 1.0.0"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package Rulealize.RuleSet.Request@1.0.0
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Rulealize.RuleSet.Request&version=1.0.0
                    
Install as a Cake Addin
#tool nuget:?package=Rulealize.RuleSet.Request&version=1.0.0
                    
Install as a Cake Tool

Rulealize.RuleSet.Request

One request, raised over something and then granted or denied — a Rulealize rule set written to be held.

Rule set id Rulealize.RuleSet.Request
Package Rulealize.RuleSet.Request
Inputs raise grant deny
Holds nothing
Draws on TypeSchema, State, Comparison, Logic, Binding
"uses": [
  { "ruleSet": "Rulealize.RuleSet.Request", "version": "^1.0", "as": "req" }
]

The identifier is the package identifier, so nothing has to look it up.

What it is a request for

Not in this document. subjects is state, not schema: the rule set says a request is raised over one of the things that may be requested, and which things those are arrives in the state document.

"req": {
  "ruleSet": "Rulealize.RuleSet.Request@1.0.0",
  "data": {
    "subjects": ["mon-am", "mon-pm", "tue-am"],
    "stage": "draft",
    "subject": null
  }
}

A roster's shifts, an order's line items and a deployment's environments are three state documents and this one rule set.

That is also why state.initial names no subjects. A held rule set opens where it opens — a composite cannot write its component's initial state — so a demonstration instance written into this document would be forced on every document that ever holds it. An empty subjects offers no raise, which is the right answer for a case nobody has said anything about yet.

What a holder gets

rec.at($req, "stage") draft, review, granted or denied
rec.at($req, "subject") what was requested, or null before raise

and two things it may do, which are the whole of what holding a rule set is. example/roster.json is a working document that does both.

Refuse. held is asked with the candidate in scope under the name this document gave its parameter, so this is where a guard that spans both states is written:

"held": {
  "req": {
    "raise": {
      "when": {
        "op": "logic.not",
        "value": {
          "op": "seq.any", "source": "$filled", "as": "f",
          "predicate": { "op": "cmp.eq", "left": "@f", "right": "@subject" }
        }
      }
    }
  }
}

Do not raise a request for a shift already filled — the guard neither half could write alone, because the request half cannot see the roster and the roster half has never heard of a request. It may only refuse. held is asked after this document's own guard, so nothing written there grants a request that would not otherwise have been offered.

Drive. fires lets one of your inputs take a component's, so that granting the request and acting on it are one decision rather than two states:

"held":   { "req": { "grant": { "when": false } } },

"inputs": {
  "fill": {
    "fires":   [ { "held": "req", "input": "grant" } ],
    "effects": [ … your own write … ]
  }
}

"when": false hides req.grant so the only route to it is fill. The fired input still goes through its own guard, so driving one is never a way past a rule this document wrote.

Where it fits

Anywhere a thing may only happen once somebody said yes. The subject is a string and what it means is the holder's business:

The subject is and the holder
a shift fills it once the request is granted the example
an environment deploys to it once the release is approved
a discount applies it once it is authorised
a document publishes it once review passed

One request is one request. A component holds one state, so holding this once gives one request: several subjects to choose between, one asked for, and the case over when it is settled. Two shapes for needing more:

  • uses may name it more than once, under a different as each time, and each alias gets a state field of its own. Two independent grants over one subject is four-eyes approval written without a second document
  • an unbounded number is a case per request, which is what a component being one state is telling you

What it deliberately does not carry. No reason on deny — that is presentation, and a holder that needs one has its own state. No actor, no timestamps, no audit trail: those are facts about a case that outlive the rule set that produced them, and the holder is what knows where they go.

The three inputs

raise(subject) from draft. The domain is subjects, read out of the state. Records subject and moves to review
grant from review. Ends at granted
deny from review. Ends at denied

A request is one request. subject is written once and never again; a second request is a second case, not a second raise. And deny carries no reason — a reason is presentation, this document is a gate, and a holder that needs reasons has its own state to keep them in.

Trying it

Needs Rulealize.Cli: dotnet tool install -g Rulealize.Cli.

On its own.

rulealize restore src/Rulealize.RuleSet.Request/ruleset/request.json
rulealize play    src/Rulealize.RuleSet.Request/ruleset/request.json --state state/example.json
Rulealize.RuleSet.Request@1.0.0 from 'state/example.json'
Choose by number. 'state' prints the position, 'q' stops.

    1. raise(subject: mon-am)
    2. raise(subject: mon-pm)
    3. raise(subject: tue-am)
>

Run it without --state and there is no legal input at all — the same document saying it has not been told what may be requested.

Held. --rulesets says where the documents a composite holds are, so the example resolves this one out of the package folder rather than a copy of its own:

rulealize restore example/roster.json --rulesets src/Rulealize.RuleSet.Request/ruleset
rulealize play    example/roster.json --rulesets src/Rulealize.RuleSet.Request/ruleset \
                  --state example/roster-state.json
    1. req.raise(subject: mon-am)
    2. req.raise(subject: mon-pm)

Take one, and fill is the only move left besides req.denyreq.grant is hidden, because the roster drives it. Take fill and the request is granted and the shift filled in one transition:

rulealize apply example/roster.json "req.raise(subject: mon-am)" \
  --rulesets src/Rulealize.RuleSet.Request/ruleset --state example/roster-state.json > r1.json
rulealize apply example/roster.json "fill" \
  --rulesets src/Rulealize.RuleSet.Request/ruleset --state r1.json
fill applied to 'r1.json' -- terminal (granted)

apply writes the state to standard output and everything else to standard error, so redirect with > and not 2>&1.

Building the package

dotnet pack src/Rulealize.RuleSet.Request -c Release

A package with no lib folder, holding this one document under ruleset/. What each property in the project file is for.

License

Apache-2.0. The document is the package's content and is covered by it, as is everything else in this repository.

There are no supported framework assets in this package.

Learn more about Target Frameworks and .NET Standard.

This package has no dependencies.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
1.0.0 175 8/30/2026