Documentation
¶
Index ¶
- Variables
- func CheckSchemaVersion(v Version) error
- func ParseReadinessBudget(desc AgentDescribe) (*time.Duration, error)
- func ValidateAgentDescribe(desc AgentDescribe) error
- func ValidateCPULimit(limit string) error
- func ValidateMemoryLimit(limit string) error
- func ValidateSchedule(schedule string) error
- type AgentDescribe
- type DescribeEnvelope
- type MalformedReadinessBudget
- type Version
Constants ¶
This section is empty.
Variables ¶
var CurrentVersion = Version{Major: 1, Minor: 0, Patch: 0}
Current schema version
var ValidAgentTypes = []string{"service", "timer", "socket", "pipe", "event", "init", "oneshot"}
ValidAgentTypes are the supported agent unit types
Functions ¶
func CheckSchemaVersion ¶
CheckSchemaVersion validates schema version compatibility
func ParseReadinessBudget ¶
func ParseReadinessBudget(desc AgentDescribe) (*time.Duration, error)
ParseReadinessBudget resolves a descriptor's declared readiness budget, refusing one the supervisor will not honour.
PARSED ONCE, AT THE BOUNDARY, per design/adk-architecture.md. This is the single spelling of the rule: ValidateAgentDescribe calls it to refuse, and discovery calls it to get the value. Two parsers would be two chances to disagree about what "30s" means, which is the class of drift GAPI-DIV-115 was filed for.
ABSENT IS NOT ZERO, so the result is a pointer. A descriptor with no readiness_budget field returns (nil, nil) and means "use the derived default for my language" - a distinction a bare time.Duration cannot carry, and the same reason AgentDescribe.Enabled is a *bool.
THE REFUSAL IS HERE, AT DECLARATION TIME, AND NOT AT START. The exit calls for "a declaration-time refusal of a budget above the ceiling", which is the difference between a config that cannot be valid failing to build and one failing at 3am.
func ValidateAgentDescribe ¶
func ValidateAgentDescribe(desc AgentDescribe) error
ValidateAgentDescribe validates agent metadata
func ValidateCPULimit ¶
ValidateCPULimit validates CPU limit format Accepts: "0.5", "500m", "1", "1.5"
It does not implement the format. It asks cgroups.ParseResourceSpec - the same function that converts the string for cgroups.Create at start - and accepts exactly what that function can represent as a POSITIVE quantity. Acceptance therefore means the limit will actually be applied, which is a property nothing enforced while the two sides were separate implementations (GAPI-DIV-049).
The cycle noted in ValidateSchedule below is schema -> agentmgr and does not apply here: core/cgroups imports only internal/safeio.
func ValidateMemoryLimit ¶
ValidateMemoryLimit validates memory limit format Accepts: "100MB", "1GB", "512M", "1G", "1024B"
Delegates to cgroups.ParseResourceSpec for the same reason ValidateCPULimit does: the accepted set and the representable set must be one set. The overflow rejection GAPI-DIV-042 added lives there now, next to the multiplication that overflows.
func ValidateSchedule ¶
ValidateSchedule validates systemd-style timer schedule or cron expression Accepts: "OnUnitActiveSec=5s", "OnBootSec=30s", "OnStartupSec=1m", "*/5 * * * *", "@hourly", etc.
Types ¶
type AgentDescribe ¶
type AgentDescribe struct {
SchemaVersion string `json:"schema_version"`
ID string `json:"id"`
Type string `json:"type"`
CPULimit string `json:"cpu_limit"`
MemoryLimit string `json:"memory_limit"`
Schedule string `json:"schedule"`
ListenStream string `json:"listen_stream"`
Requires []string `json:"requires"`
Wants []string `json:"wants"`
WantedBy []string `json:"wanted_by"`
RequiredBy []string `json:"required_by"`
Capabilities []string `json:"capabilities"`
// POINTER, so ABSENT is distinguishable from an explicit false. Go
// agents do not emit this field at all, and a plain bool would
// unmarshal their silence as disabled - turning every Go agent off
// the moment the field was honoured. Validation ignores it; only
// discovery resolves it.
Enabled *bool `json:"enabled"`
// ReadinessBudget is how long this agent may take to reach RUNNING
// after its first control frame (GAPI-DIV-107). OPTIONAL: decision
// 51 dropped the required form on this entry's own warning that a
// required field invites an author to copy a number from an example,
// and a cargo-culted value is worse than a default because it LOOKS
// declared.
//
// POINTER for the same reason as Enabled, and it matters more here:
// absent means "use the derived default for my language", which is
// a different instruction from any duration an author could write.
// A plain string would spell absence as "", which is a value.
//
// A STRING, holding a Go duration such as "30s", matching CPULimit
// and MemoryLimit rather than inventing a numeric unit convention
// for one field. Parsed and refused by ParseReadinessBudget.
ReadinessBudget *string `json:"readiness_budget"`
}
AgentDescribe is an agent's DECLARATION, and it is the one place this shape is spelled (GAPI-DIV-115).
It was spelled four times: twice in core/agentmgr/discovery.go - once as pyDescribe's inner struct and once as an inline anonymous parameter to processDiscovered, which had to match it structurally - and here, with a field-by-field copy between them. The copy is what drifted: GAPI-DIV-083 records Describe() spelling `mem_limit` where the wire spells `memory_limit`, and that is the class of defect a hand-written translation between two identical shapes produces.
THE JSON TAGS LIVE HERE because discovery now unmarshals STRAIGHT INTO this type. Parsing and validating the same struct means a field added to the schema cannot be silently dropped on the way to the validator - previously it had to be added in three places and forgetting the third was invisible.
Note the type serves BOTH languages despite the old name: Go agents and Python agents emit the same `describe` object, and binaryDescribe and pythonDescribe both decoded it.
type DescribeEnvelope ¶
type DescribeEnvelope struct {
Describe AgentDescribe `json:"describe"`
}
DescribeEnvelope is the object an agent actually prints: the declaration under a "describe" key. Named for what it is rather than for one of the two languages that emit it.
type MalformedReadinessBudget ¶
MalformedReadinessBudget is a declared budget that is not a duration, as data. It carries the text the author actually wrote, because "invalid duration" without the offending string sends an operator back to the descriptor to guess which field was meant.
func (*MalformedReadinessBudget) Error ¶
func (e *MalformedReadinessBudget) Error() string
func (*MalformedReadinessBudget) Unwrap ¶
func (e *MalformedReadinessBudget) Unwrap() error