Documentation
¶
Overview ¶
Package governance holds the framework's governance-audit payload types.
A governance verdict (deny/approve, ADR-039) is an *event*: N verdicts occur per rule over time. ADR-055 §3a retires the previous mechanism — a best-effort audit triple written onto a phantom rule-ID "entity" via the graph-ingest auto-vivify path that ADR-055 deletes — and replaces it with this registered verdict-event payload published to the append-only GOVERNANCE_VERDICT_AUDIT JetStream stream. The verdict thus carries its own producer contract (a semantic envelope, §2) and lands on an honest, queryable event log instead of a mutable, last-write-wins rule-ID record.
Index ¶
Constants ¶
const ( // Domain is the payload-registry domain for governance events. Domain = "governance" // CategoryVerdict is the payload-registry category for verdict events. CategoryVerdict = "verdict" // SchemaVersion is the current governance payload schema version. SchemaVersion = "v1" )
Payload type coordinates (the semantic envelope, ADR-055 §2).
const ( // DecisionDeny records an explicit tool-call/structural denial. DecisionDeny = "deny" // DecisionApprove records an explicit approval. DecisionApprove = "approve" )
Verdict decision values. These are the subject-safe tokens used in the verdict subject (`governance.verdict.{decision}.{rule_token}`).
const SubjectPrefix = "governance.verdict"
SubjectPrefix is the root of every verdict subject. The GOVERNANCE_VERDICT_AUDIT stream captures `governance.verdict.>`.
Variables ¶
This section is empty.
Functions ¶
func RegisterPayloads ¶
func RegisterPayloads(reg *payloadregistry.Registry) error
RegisterPayloads registers the governance verdict-event payload with the supplied registry. Called from payloadbuiltins.Register during bootstrap so any registry-based decoder (audit/ops dashboards replaying the stream) can read verdict events off the wire.
func RuleToken ¶
RuleToken returns a deterministic, subject-safe encoding of a rule ID for use as a NATS subject token. Rule IDs are free-form config strings that can contain `.` (the token separator), spaces, or `*`/`>` (wildcards) — any of which would break subject publishing AND filtering. The token is a 64-bit FNV-1a hash in hex (16 chars, always subject-safe). The canonical rule_id travels in the payload for display/query, so the hash being lossy is acceptable (ADR-055 §3a).
func VerdictSubject ¶
VerdictSubject builds the publish subject for a verdict event: `governance.verdict.{decision}.{rule_token}`. decision should be DecisionDeny or DecisionApprove (already subject-safe).
Types ¶
type VerdictEvent ¶
type VerdictEvent struct {
// Decision is DecisionDeny or DecisionApprove.
Decision string `json:"decision"`
// RuleID is the canonical (un-encoded) rule identifier. Free-form config
// string; carried here verbatim because the subject token is a lossy hash.
RuleID string `json:"rule_id"`
// Reason is the operator-facing verdict reason (substituted).
Reason string `json:"reason"`
// EntityID is the entity the verdict concerns (may be empty for some rule
// contexts).
EntityID string `json:"entity_id,omitempty"`
// Timestamp is when the verdict was issued.
Timestamp time.Time `json:"timestamp"`
// LoopID is the agentic-loop id, when the verdict fired on a tool-call.
LoopID string `json:"loop_id,omitempty"`
// CallID is the tool-call id, when the verdict fired on a tool-call.
CallID string `json:"call_id,omitempty"`
}
VerdictEvent is the registered audit payload for a governance verdict.
Always-present fields (RuleID, Reason, EntityID, Decision, Timestamp) come from the rule action's execution context. LoopID/CallID are OPTIONAL — they are echoed from the proposed-call message when the verdict fires on a tool-call (ADR-055 §3a) and are empty for entity-state-driven or cron-fired rules, which have no inbound call identity.
func (*VerdictEvent) MarshalJSON ¶
func (e *VerdictEvent) MarshalJSON() ([]byte, error)
MarshalJSON implements json.Marshaler. The Alias indirection avoids infinite recursion; the BaseMessage envelope is added by the publisher (message.NewBaseMessage), not here.
func (*VerdictEvent) Schema ¶
func (e *VerdictEvent) Schema() message.Type
Schema implements message.Payload.
func (*VerdictEvent) UnmarshalJSON ¶
func (e *VerdictEvent) UnmarshalJSON(data []byte) error
UnmarshalJSON implements json.Unmarshaler.
func (*VerdictEvent) Validate ¶
func (e *VerdictEvent) Validate() error
Validate implements message.Payload. It is deliberately lenient: the only hard requirements are a recognized decision and a non-empty rule ID. The audit emit is best-effort and must never block a structural verdict, so a permissive Validate keeps a sparse-but-real verdict event readable rather than rejecting it at decode.