gate

package
v0.17.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 3, 2026 License: MIT Imports: 3 Imported by: 0

README

gate

import "github.com/kitsunium/sdk/framework/gate"

Package gate decides whether one invocation of a distributed binary may run.

A product that verifies an entitlement at start-up answers three questions before it does any work, and they are usually answered by hand, in a root command, in code nobody revisits:

  • Is THIS invocation subject to the check at all?
  • The vendor mandates a newer build. Refuse, upgrade, or warn?
  • When the answer is no, what should the process do about it?

This package owns the first two as values and leaves the third to you.

It performs nothing

Decide does not verify — that is framework/entitlement. It does not upgrade — that is framework/selfupdate. And it never ends your process. It reads what your verifier returned and says what to do; the effects stay in your control flow, where they can be refused, logged or tested.

decision := gate.Decide(policy, invocation.Path[1:], func() error {
	_, err := service.Verify(time.Now())
	return err
})
switch decision.Outcome {
case gate.OutcomeAllow:
	// run the command; decision.FloorUnmet may still want reporting
case gate.OutcomeUpgrade:
	// upgrade AT MOST ONCE, then re-run
default:
	fmt.Fprintln(os.Stderr, decision.Cause)
	os.Exit(errs.ExitCodeOf(decision.Cause))
}
The policy refuses to be unsafe

Policy.Validate reports every fault at once rather than the first, and two of them are lockouts rather than typos: a policy that exempts nothing cannot be repaired from inside the binary, and a policy that gates its own recovery command leaves a machine whose entitlement lapsed with no path back short of reinstalling. Policy.RecoveryPaths is what turns the second from a comment into a construction-time refusal.

Index

Constants

CodePolicyInvalid identifies a gate policy that could not be used as written.

const CodePolicyInvalid errs.Code = coregate.CodePolicyInvalid

type Decision

Decision is what the gate concluded about one invocation. It carries no method that acts.

type Decision = coregate.DecisionValue

func Decide
func Decide(policy *Policy, path []string, verify func() error) Decision

Decide classifies one invocation.

Exemption is checked FIRST, and verify is not CALLED when it holds — which is why this takes a function rather than an error. A shell-completion hook or a `license status` on a machine whose licence is broken must not pay for a network round trip, and neither should have to remember not to run one.

The version floor is checked BEFORE a refusal is propagated, because an out-of-date binary must be told to upgrade whether or not its entitlement is also in order.

It takes policy, your gate policy — a nil one refuses everything, including a verification that would have passed; path, the command path relative to the root with the root itself NOT included, where nil is the bare root invocation; and verify, your entitlement verification, CALLED AT MOST ONCE and only when the invocation is not exempt, with a nil verify refusing.

It returns what to do, and everything the verifier said.

type Outcome

Outcome is what the caller should do with an invocation. Its zero value is unclaimed, so a decision nobody made never reads as "allow".

type Outcome = coregate.Outcome

OutcomeAllow runs the invocation.

const OutcomeAllow Outcome = coregate.OutcomeAllow

OutcomeRefuse stops the invocation; Decision.Cause says why.

const OutcomeRefuse Outcome = coregate.OutcomeRefuse

OutcomeUpgrade asks the caller to upgrade and re-run.

const OutcomeUpgrade Outcome = coregate.OutcomeUpgrade

type Policy

Policy is one product's gate policy: what runs unchecked, what must never be gated, and what a mandated upgrade does. Its zero value is refused by Validate.

type Policy = coregate.PolicyValue

type UpdateAction

UpdateAction is what happens when the vendor mandates a newer build. Its zero value is unclaimed, because refusing and upgrading are opposite answers.

type UpdateAction = coregate.UpdateAction

UpdateApply asks the caller to upgrade and re-run the invocation.

const UpdateApply UpdateAction = coregate.UpdateApply

UpdateRefuse stops the invocation and reports the floor.

const UpdateRefuse UpdateAction = coregate.UpdateRefuse

UpdateWarn runs the invocation anyway and reports the floor alongside it.

const UpdateWarn UpdateAction = coregate.UpdateWarn

Generated by gomarkdoc

Documentation

Overview

Package gate decides whether one invocation of a distributed binary may run.

A product that verifies an entitlement at start-up answers three questions before it does any work, and they are usually answered by hand, in a root command, in code nobody revisits:

  • Is THIS invocation subject to the check at all?
  • The vendor mandates a newer build. Refuse, upgrade, or warn?
  • When the answer is no, what should the process do about it?

This package owns the first two as values and leaves the third to you.

It performs nothing

Decide does not verify — that is framework/entitlement. It does not upgrade — that is framework/selfupdate. And it never ends your process. It reads what your verifier returned and says what to do; the effects stay in your control flow, where they can be refused, logged or tested.

decision := gate.Decide(policy, invocation.Path[1:], func() error {
	_, err := service.Verify(time.Now())
	return err
})
switch decision.Outcome {
case gate.OutcomeAllow:
	// run the command; decision.FloorUnmet may still want reporting
case gate.OutcomeUpgrade:
	// upgrade AT MOST ONCE, then re-run
default:
	fmt.Fprintln(os.Stderr, decision.Cause)
	os.Exit(errs.ExitCodeOf(decision.Cause))
}

The policy refuses to be unsafe

Policy.Validate reports every fault at once rather than the first, and two of them are lockouts rather than typos: a policy that exempts nothing cannot be repaired from inside the binary, and a policy that gates its own recovery command leaves a machine whose entitlement lapsed with no path back short of reinstalling. Policy.RecoveryPaths is what turns the second from a comment into a construction-time refusal.

Index

Constants

View Source
const CodePolicyInvalid errs.Code = coregate.CodePolicyInvalid

CodePolicyInvalid identifies a gate policy that could not be used as written.

Variables

This section is empty.

Functions

This section is empty.

Types

type Decision

type Decision = coregate.DecisionValue

Decision is what the gate concluded about one invocation. It carries no method that acts.

func Decide

func Decide(policy *Policy, path []string, verify func() error) Decision

Decide classifies one invocation.

Exemption is checked FIRST, and verify is not CALLED when it holds — which is why this takes a function rather than an error. A shell-completion hook or a `license status` on a machine whose licence is broken must not pay for a network round trip, and neither should have to remember not to run one.

The version floor is checked BEFORE a refusal is propagated, because an out-of-date binary must be told to upgrade whether or not its entitlement is also in order.

It takes policy, your gate policy — a nil one refuses everything, including a verification that would have passed; path, the command path relative to the root with the root itself NOT included, where nil is the bare root invocation; and verify, your entitlement verification, CALLED AT MOST ONCE and only when the invocation is not exempt, with a nil verify refusing.

It returns what to do, and everything the verifier said.

type Outcome

type Outcome = coregate.Outcome

Outcome is what the caller should do with an invocation. Its zero value is unclaimed, so a decision nobody made never reads as "allow".

const OutcomeAllow Outcome = coregate.OutcomeAllow

OutcomeAllow runs the invocation.

const OutcomeRefuse Outcome = coregate.OutcomeRefuse

OutcomeRefuse stops the invocation; Decision.Cause says why.

const OutcomeUpgrade Outcome = coregate.OutcomeUpgrade

OutcomeUpgrade asks the caller to upgrade and re-run.

type Policy

type Policy = coregate.PolicyValue

Policy is one product's gate policy: what runs unchecked, what must never be gated, and what a mandated upgrade does. Its zero value is refused by Validate.

type UpdateAction

type UpdateAction = coregate.UpdateAction

UpdateAction is what happens when the vendor mandates a newer build. Its zero value is unclaimed, because refusing and upgrading are opposite answers.

const UpdateApply UpdateAction = coregate.UpdateApply

UpdateApply asks the caller to upgrade and re-run the invocation.

const UpdateRefuse UpdateAction = coregate.UpdateRefuse

UpdateRefuse stops the invocation and reports the floor.

const UpdateWarn UpdateAction = coregate.UpdateWarn

UpdateWarn runs the invocation anyway and reports the floor alongside it.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL