composer

package
v0.8.4 Latest Latest
Warning

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

Go to latest
Published: Oct 1, 2026 License: Apache-2.0 Imports: 8 Imported by: 0

Documentation

Overview

Posture-gated autonomy, arithmetic half. The api half — the gate that refuses a request shape and derives a hold — is internal/api/runs_autonomy.go; everything here is PURE, so launch and the Review dry run fold the same inputs to the same answer by construction.

The comparator for "which ceiling grant bounds this proposed grant". Lives here because composer holds the RUNTIME clamp and internal/api (the WRITE-TIME comparator) imports composer, not the reverse — one definition, two callers.

SECURITY invariant: both callers must ask it the same way — some single ceiling grant must dominate the proposal on every axis. A per-kind map must never supply the bound instead: the LAST same-kind ceiling grant would win, so a ceiling listing two ssh_key grants (normal for two forges) could clamp a proposal naming the STRICT forge's pairing to the PERMISSIVE forge's posture, answering differently by slice order.

Index

Constants

View Source
const WarnResourcesCapped = "resources capped to operator maximum"

ClampRunConfinement raises a proposed run's confinement class to the policy floor (never lowers) so the composer can't emit a run that handleCreateRun would 422 for advertising a weaker class than its own inline_policy floor (invariant 5); empty/unknown ranks 0 and is also raised. WarnResourcesCapped is shared with dispatch's own ephemeral-disk clamp (runs_dispatch_ceiling.go) so the same fact about the same number isn't hand-typed twice and drift apart.

Variables

This section is empty.

Functions

func AutonomyPostureOf added in v0.8.0

func AutonomyPostureOf(spec types.RunPolicySpec, enforced types.ConfinementClass) types.AutonomyPosture

AutonomyPostureOf grades a run's three-axis posture from its RESOLVED spec and the confinement class the run will actually enforce. It keys on the same inputs as Grade and RequiredConfinementFloor, so posture and risk grade never disagree about what "powerful" or "beyond baseline" means on the same Review screen. Purely a function of the spec, never of anything a model claimed.

func CapDiskMiB added in v0.7.2

func CapDiskMiB(disk, ceil int) int

CapDiskMiB bounds a non-zero ephemeral-disk size by one operator ceiling; 0 on either side means "no bound". Shared by Clamp (preview) and api.ephemeralDiskFor (dispatch) so both ceilings agree — previously each applied a different ceiling (profile vs org), so a 100000 MiB policy under a 4096 MiB org max previewed 100000 but ran on 4096; pinned by TestPreflightAndDispatchAgreeOnEphemeralDisk. A zero disk stays zero: a ceiling bounds a request, it never invents one.

func CeilingGrantsCovering added in v0.7.0

func CeilingGrantsCovering(g types.GrantSpec, ceiling []types.GrantSpec) []types.GrantSpec

CeilingGrantsCovering returns the ceiling grants whose identity covers g (same kind, and for a stored-secret kind the same host/secret/known_hosts pairing) — exported so api's write-time comparator selects from the same set the runtime clamp bounds against, one definition not two. Identity only, never bounds: an undecodable proposal scope is covered by nothing (fail closed).

func Clamp

func Clamp(proposed, ceiling types.RunPolicySpec, maxEphemeralDiskMiB int) (types.RunPolicySpec, []string)

Clamp tightens a proposed RunPolicySpec to the operator's policy ceiling so the composer can never propose something more permissive than the operator allows, returning the clamped spec and a warning for every tightening performed. Defense-in-depth alongside the deterministic risk grade: the grade informs the human, this enforces the operator's hard limits regardless of what an untrusted-input-driven analyzer or a member's own inline_policy proposed.

The returned spec owns its memory (see cloneProposal): it shares no backing array or pointee with either argument, so a later mutation of either side can never move an already-enforced ceiling.

maxEphemeralDiskMiB is the acting principal's GovernanceLimits.MaxEphemeralDiskMiB (0 = unlimited). It's applied via CapDiskMiB, shared with dispatch's own ephemeral-disk clamp so preview and the actual run agree, and only clamps a non-zero request since 0 means unbounded scratch.

func ClampRunConfinement

func ClampRunConfinement(runClass string, floor types.ConfinementClass) (string, string)

func EffectiveConfinementFloor

func EffectiveConfinementFloor(policyMin, floor, cap types.ConfinementClass) types.ConfinementClass

EffectiveConfinementFloor caps the per-run floor (the Getting Started default tier, sent raise-only) at the strongest class this host's runner can enforce, then returns max(policyMin, cappedFloor). The cap degrades only the per-run floor, never policyMin — an unenforceable policy minimum still fails closed at launch (invariant 5); degrading it here would make compose the one path that bypasses an operator security control. cap=="" means "do not cap". Feeding the result into Clamp's ceiling reuses its existing "confinement raised" warning.

func FoldAutonomy added in v0.8.0

func FoldAutonomy(rubric types.AutonomyRubric, posture types.AutonomyPosture) (types.AutonomyLevel, []string)

FoldAutonomy folds a rubric against a posture: the level is the MINIMUM over the three fields the posture selects, and boundBy names EVERY field tied at that minimum (its rubric wire name), not just the first — so an admin who raises one capping row can see the level not move because another field tied it. An unset field caps nothing and is skipped, so an all-unset rubric returns ("", nil), matching the "empty means unrestricted" rule every GovernanceLimits field follows. Order is applicableAutonomyCaps's fixed field order, so the audit row and the Review response agree byte for byte.

func GitHubScopeWithin added in v0.7.0

func GitHubScopeWithin(proposed, ceiling json.RawMessage) error

GitHubScopeWithin reports whether a proposed github_token scope stays inside a ceiling's, by the same rules clampGitHubScope enforces (ceiling repo list is an allowlist, empty = deny-all; an absent permission is ungrantable; a present one bounds the level by permRank) — one shared copy so accept-here can't drift from widen-there.

Differs in one way: an undecodable scope is an error here, not empty, since a comparator reading "no constraint" would fail open (the clamp instead intersects toward empty, fail-closed).

func GrantPairing added in v0.7.0

func GrantPairing(g types.GrantSpec) (host, secretRef, knownHostsRef string, covered, ok bool)

GrantPairing returns the pairing a grant names and whether its kind names a stored secret at all. covered=false is honest for github_token/cloud_sts, which name no stored secret. ok=false means the scope didn't decode into a usable pairing — deliberately not an error return, since fail-closed here means an unreadable scope never MATCHES anything. env_secret puts the env var NAME in the host slot.

func PairingInCeiling added in v0.7.0

func PairingInCeiling(g types.GrantSpec, ceiling []types.GrantSpec) bool

PairingInCeiling reports whether some ceiling grant of the SAME kind names the same stored-secret pairing — the identity axis of the one comparator (internal/api's storedSecretPairingInCeiling forwards to it). Takes the whole proposed grant, not a destructured pairing, so the pairing rule lives in exactly ONE decoder. Fail-closed: a grant whose kind names no stored secret, or whose scope doesn't decode, is in no pairing.

func RequiredConfinementFloor

func RequiredConfinementFloor(spec types.RunPolicySpec) types.ConfinementClass

RequiredConfinementFloor returns the deterministic minimum confinement class a run's blast radius requires, independent of model/operator choice: SECURITY: a run holding a write-capable grant or an api_key to a non-baseline host is a high-value target and must run in CC3 so an escape is contained. "" means no floor. Enforced both at composer proposal and (defense-in-depth) at run.create.

Types

type RiskItem

type RiskItem struct {
	Field        string    `json:"field"`
	Value        string    `json:"value"`
	Level        RiskLevel `json:"risk_level"`
	Rationale    string    `json:"rationale"`
	InvariantRef string    `json:"invariant_ref,omitempty"`
}

RiskItem is one graded config choice. Field/Value identify what was graded, Level is Wardyn's deterministic grade, Rationale explains it to the human, and InvariantRef (optional) cites the security invariant the choice bears on.

func Grade

func Grade(run RunInput, spec types.RunPolicySpec) []RiskItem

Grade computes the deterministic risk assessment of a proposed run setup purely from its fields. SECURITY: it never consults any LLM self-assessment — a prompt-injected attachment cannot lower the grade, since the grade is a function of the spec, not of anything the model claims about it. Emits one item per notable choice (including LOW ones), sorted riskiest-first.

type RiskLevel

type RiskLevel string

RiskLevel is Wardyn's deterministic grade for a single config choice.

const (
	RiskLow    RiskLevel = "low"
	RiskMedium RiskLevel = "medium"
	RiskHigh   RiskLevel = "high"
)

func OverallLevel

func OverallLevel(items []RiskItem) RiskLevel

OverallLevel returns the highest level among items (low if none).

type RunInput

type RunInput struct {
	Agent            string `json:"agent"`
	Repo             string `json:"repo"`
	Task             string `json:"task"`
	ConfinementClass string `json:"confinement_class,omitempty"`
	Interactive      bool   `json:"interactive,omitempty"`
	DevcontainerRepo string `json:"devcontainer_repo,omitempty"`
}

RunInput is the scalar create-run fields graded by Grade — the same fields the wizard's buildSpec puts on `run`. Mapped onto the create-run request by the API layer (this package must not import internal/api).

Jump to

Keyboard shortcuts

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