auditaction

package
v0.0.2 Latest Latest
Warning

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

Go to latest
Published: Sep 17, 2026 License: MIT Imports: 4 Imported by: 0

Documentation

Overview

Package auditaction is the registry of every action name the hub can write into the `event_type` column of `audit_events`.

Before this package, every one of those names was an inline string literal at its emission site, spread across pkg/statedb, pkg/secretbroker, pkg/gitproxy, pkg/kubeguard, pkg/claudeproxy, pkg/oidcauth, pkg/offboard and pkg/ui. Two things followed from that, and both of them were real:

  • A typo produced an action name that no consumer would ever match. There was nothing to compare a literal against, so `gitproxy.push_deneid` would have appended rows forever, passed chain verification, exported cleanly to a SIEM, and matched no detection rule. The failure is silent in the one direction that matters — a control that looks like it is working.

  • Nothing told a reader which names exist. An operator wiring the SIEM export into a detection rule had to read emission code in eight packages to learn what they could key on, and docs/security/model.md cited `sandbox.image_denied` and `gitproxy.push_denied` as evidence that a control works with nothing guaranteeing those strings were still in the code it described.

So the names live here, once, each with the trigger that fires it, the entity it is recorded against, the payload keys it carries, a stability marker, and the permission that gates reading it. docs/reference/audit-events.md is generated from this registry, and three gates keep the arrangement from rotting:

  • tests/arch/auditaction_test.go fails when an emission site names an action this registry does not know, and when a family's source enum grows a member with no registry entry.
  • tests/docs/audit_events_test.go fails when the generated page drifts from the registry, and when a prose page cites an action name that no longer exists.
  • The registry's own tests below fail on a duplicate, a malformed name, or an entry missing the fields the page renders.

What is not enforced

The registry does not filter. An emitter that somehow produces an unregistered name still writes its row: dropping an audit record to punish a bookkeeping mistake would turn a documentation defect into an evidence one. Enforcement happens at CI time, where a missing entry is a failed build rather than a missing row.

The reverse direction is deliberately not gated either. A registry entry whose emission site is unreachable on a given build — a family member that only fires on an offline-agent path, say — is not an error. Requiring every entry to be provably emitted would mean deleting the documentation for the rarest events, which are the ones most in need of it.

Index

Constants

View Source
const (
	// FamilyExecutor is the fleet-lifecycle family: enrol, revoke, cordon,
	// and the rest of the operations an operator performs on an executor.
	FamilyExecutor = "executor"
	// FamilyWorkspace is the source-provisioning family.
	FamilyWorkspace = "workspace"
	// FamilyGitProxy is the git interception proxy's family.
	FamilyGitProxy = "gitproxy"
	// FamilyKubeGuard is the Kubernetes interception proxy's family.
	FamilyKubeGuard = "kubeguard"
	// FamilyAuthz is the authorization-decision family.
	FamilyAuthz = "authz"
)

Variables

This section is empty.

Functions

func Families

func Families() []string

Families returns every family name that has at least one registered action, in the order the generated page presents them — which is the order the registry declares, not alphabetical, so related families stay adjacent.

func Markdown

func Markdown(intro string) string

Markdown renders the whole registry as docs/reference/audit-events.md.

The page is generated rather than written for the same reason docs/reference/http-api.md is: a hand-maintained list of 100-odd strings diverges from the code within one release, and the divergence is invisible — a stale page still reads as authoritative. tests/docs/audit_events_test.go compares this output against the checked-in file and fails when they differ.

intro is the hand-written lead. It is passed in rather than embedded here so the prose that explains the trail lives next to the test that owns the page, where a writer will find it, rather than inside a package whose job is the data.

func Registered

func Registered(a Action) bool

Registered reports whether a is a known action.

Types

type Action

type Action string

Action is one value of the `event_type` column in `audit_events`.

Values are stable wire strings. They appear in exported SIEM records, in customer detection rules, and in rows already sealed into a hash chain that cannot be rewritten. Never rename one: add a new constant, mark the old one StabilityDeprecated, and let both exist until no stored row carries the old name — which, for an append-only table with a retention policy, means until retention has passed over it.

const (

	// ActionTaskUpsert records a task whose audited fields changed.
	ActionTaskUpsert Action = "task.upsert"
	// ActionTaskDelete records a task leaving the plan.
	ActionTaskDelete Action = "task.delete"
	// ActionTaskStatus records a hand-made status change.
	ActionTaskStatus Action = "task.status"
	// ActionTaskDispatch records a task being handed to an executor.
	ActionTaskDispatch Action = "task.dispatch"
	// ActionTaskFinish records a dispatched task reaching a terminal outcome.
	ActionTaskFinish Action = "task.finish"

	// ActionRunCapPaused records a run parked by a Claude Code subscription
	// cap, together with when the window reopens.
	ActionRunCapPaused Action = "run.cap_paused"
	// ActionRunCapResumed records the hub restarting such a run once the
	// window rolled over, with no human involved.
	ActionRunCapResumed Action = "run.cap_resumed"

	// ActionStepAppend records one execution step's transcript.
	ActionStepAppend Action = "step.append"

	// ActionStateSave records a plan-level state write.
	ActionStateSave Action = "state.save"
	// ActionConfigSet records a configuration write.
	ActionConfigSet Action = "config.set"

	// ActionExecutorEnroll records an agent joining the fleet.
	ActionExecutorEnroll Action = "executor.enroll"
	// ActionExecutorRevoke records an agent's credential being revoked.
	ActionExecutorRevoke Action = "executor.revoke"
	// ActionExecutorCordon records an executor being closed to new work.
	ActionExecutorCordon Action = "executor.cordon"
	// ActionExecutorUncordon records a cordoned executor returning to service.
	ActionExecutorUncordon Action = "executor.uncordon"
	// ActionExecutorDrain records an executor being told to shed work.
	ActionExecutorDrain Action = "executor.drain"
	// ActionExecutorBind records a project being pinned to one executor.
	ActionExecutorBind Action = "executor.bind"
	// ActionExecutorUnbind records a project's executor pin being cleared.
	ActionExecutorUnbind Action = "executor.unbind"
	// ActionExecutorStateChange records a health-state transition nobody asked for.
	ActionExecutorStateChange Action = "executor.state_change"
	// ActionExecutorFailover records a session moving off a failed executor.
	ActionExecutorFailover Action = "executor.failover"

	// ActionWorkspaceProvisionStart records the beginning of source provisioning.
	ActionWorkspaceProvisionStart Action = "workspace.provision_start"
	// ActionWorkspaceProvisionEnd records provisioning finishing, with or without an error.
	ActionWorkspaceProvisionEnd Action = "workspace.provision_end"

	// ActionSandboxImageDenied records an image refused by trust policy.
	ActionSandboxImageDenied Action = "sandbox.image_denied"

	// ActionSandboxAttachOpen records a shell being opened inside a running sandbox.
	ActionSandboxAttachOpen Action = "sandbox.attach.open"
	// ActionSandboxAttachClose records an attached session ending.
	ActionSandboxAttachClose Action = "sandbox.attach.close"
	// ActionSandboxAttachDenied records an attach request being refused.
	ActionSandboxAttachDenied Action = "sandbox.attach.denied"

	// ActionSecretMint records a credential being sealed into a new secret.
	ActionSecretMint Action = "secret.mint"
	// ActionSecretDelete records a secret being destroyed.
	ActionSecretDelete Action = "secret.delete"
	// ActionSecretGrant records authority to lease a secret being written.
	ActionSecretGrant Action = "secret.grant"
	// ActionSecretRevoke records a grant being marked unusable.
	ActionSecretRevoke Action = "secret.revoke"
	// ActionSecretLease records a lease being issued or refused.
	ActionSecretLease Action = "secret.lease"
	// ActionSecretRenew records a live lease being re-issued.
	ActionSecretRenew Action = "secret.renew"
	// ActionSecretRelease records a lease ending in the ordinary way.
	ActionSecretRelease Action = "secret.release"
	// ActionSecretAccessCheck records an access decision against a grant's constraints.
	ActionSecretAccessCheck Action = "secret.access_check"
	// ActionSecretRequest records a self-service access request being filed.
	ActionSecretRequest Action = "secret.request"
	// ActionSecretRequestApprove records a request being approved.
	ActionSecretRequestApprove Action = "secret.request_approve"
	// ActionSecretRequestDeny records a request being refused.
	ActionSecretRequestDeny Action = "secret.request_deny"
	// ActionSecretRequestWithdraw records a requester withdrawing their request.
	ActionSecretRequestWithdraw Action = "secret.request_withdraw"
	// ActionSecretRequestExpire records a request lapsing undecided.
	ActionSecretRequestExpire Action = "secret.request_expire"
	// ActionSecretLeaseSweep records one run of the expired-lease sweeper.
	ActionSecretLeaseSweep Action = "secret.lease.sweep"

	// ActionLeaseRevokeSent records a revocation being queued for delivery.
	ActionLeaseRevokeSent Action = "lease.revoke_sent"
	// ActionLeaseRevokeAcked records an executor confirming it destroyed the material.
	ActionLeaseRevokeAcked Action = "lease.revoke_acked"
	// ActionLeaseRevokeFailed records a revocation that did not land.
	ActionLeaseRevokeFailed Action = "lease.revoke_failed"

	// ActionGitHubAppTokenDestroy records a GitHub App installation token deleted at GitHub.
	ActionGitHubAppTokenDestroy Action = "github_app.token_destroy"

	// ActionEgressGrant records authority to reach the network being written.
	ActionEgressGrant Action = "egress.grant"
	// ActionEgressRevoke records an egress authorisation being withdrawn.
	ActionEgressRevoke Action = "egress.revoke"
	// ActionEgressRedeem records a proxy session being minted against a grant.
	ActionEgressRedeem Action = "egress.redeem"
	// ActionEgressConnect records a connection attempt being evaluated.
	ActionEgressConnect Action = "egress.connect"
	// ActionEgressRequest records an HTTP request passing through the proxy.
	ActionEgressRequest Action = "egress.request"
	// ActionEgressClose records a proxy session closing with its byte counts.
	ActionEgressClose Action = "egress.close"

	// ActionGitProxySessionMinted records a git proxy session being created.
	ActionGitProxySessionMinted Action = "gitproxy.session_minted"
	// ActionGitProxySessionClosed records a git proxy session ending.
	ActionGitProxySessionClosed Action = "gitproxy.session_closed"
	// ActionGitProxyPushAllowed records a push admitted by branch policy.
	ActionGitProxyPushAllowed Action = "gitproxy.push_allowed"
	// ActionGitProxyPushDenied records a push refused by branch policy.
	ActionGitProxyPushDenied Action = "gitproxy.push_denied"
	// ActionGitProxyFetch records a read passing through the proxy.
	ActionGitProxyFetch Action = "gitproxy.fetch"
	// ActionGitProxyRejected records a request refused before policy evaluation.
	ActionGitProxyRejected Action = "gitproxy.rejected"

	// ActionKubeGuardSessionMinted records a Kubernetes proxy session being created.
	ActionKubeGuardSessionMinted Action = "kubeguard.session_minted"
	// ActionKubeGuardSessionClosed records a Kubernetes proxy session ending.
	ActionKubeGuardSessionClosed Action = "kubeguard.session_closed"
	// ActionKubeGuardRequestDenied records a Kubernetes request refused by policy.
	ActionKubeGuardRequestDenied Action = "kubeguard.request_denied"
	// ActionKubeGuardRequestAllowed records a Kubernetes request admitted by policy.
	ActionKubeGuardRequestAllowed Action = "kubeguard.request_allowed"
	// ActionKubeGuardRejected records a request refused before its session was identified.
	ActionKubeGuardRejected Action = "kubeguard.rejected"

	// ActionCIRejected records a relay request refused before a session existed.
	ActionCIRejected Action = "ci.rejected"
	// ActionCISessionMinted records a relay session being issued to a pipeline.
	ActionCISessionMinted Action = "ci.session.minted"
	// ActionCISessionClosed records a relay session ending.
	ActionCISessionClosed Action = "ci.session.closed"
	// ActionCISessionRevoked records an operator revoking a live relay session.
	ActionCISessionRevoked Action = "ci.session.revoked"
	// ActionCIExchangeAccepted records a pipeline's OIDC token being exchanged.
	ActionCIExchangeAccepted Action = "ci.exchange.accepted"
	// ActionCIExchangeRejected records a token exchange being refused.
	ActionCIExchangeRejected Action = "ci.exchange.rejected"
	// ActionCIRelayAllowed records a relayed API call being forwarded.
	ActionCIRelayAllowed Action = "ci.relay.allowed"
	// ActionCIRelayDenied records a relayed API call being refused.
	ActionCIRelayDenied Action = "ci.relay.denied"
	// ActionCIRuleCreated records an allowlist rule being added.
	ActionCIRuleCreated Action = "ci.rule.created"
	// ActionCIRuleUpdated records an allowlist rule being edited.
	ActionCIRuleUpdated Action = "ci.rule.updated"
	// ActionCIRuleDeleted records an allowlist rule being removed.
	ActionCIRuleDeleted Action = "ci.rule.deleted"
	// ActionCIConfigUpdated records the relay's own settings changing.
	ActionCIConfigUpdated Action = "ci.config.updated"

	// ActionAuthzGranted records a privileged permission being exercised.
	ActionAuthzGranted Action = "authz.granted"
	// ActionAuthzDenied records a permission check refusing a caller.
	ActionAuthzDenied Action = "authz.denied"

	// ActionAPITokenCreated records a token or glasses link being minted.
	ActionAPITokenCreated Action = "api_token.created"
	// ActionAPITokenRevoked records a token or glasses link being revoked.
	ActionAPITokenRevoked Action = "api_token.revoked"
	// ActionAPITokenAuthFailed records a presented token failing to authenticate.
	ActionAPITokenAuthFailed Action = "api_token.auth_failed"
	// ActionAPITokenCreateDenied records a mint refused by the anti-escalation check.
	ActionAPITokenCreateDenied Action = "api_token.create_denied"

	// ActionSessionCreated records a sign-in completing.
	ActionSessionCreated Action = "session.created"
	// ActionSessionExpired records the janitor removing a deadline-expired session.
	ActionSessionExpired Action = "session.expired"
	// ActionSessionRevoked records a logout or an operator termination.
	ActionSessionRevoked Action = "session.revoked"
	// ActionSessionIdPRevoked records the IdP reporting the authorisation is gone.
	ActionSessionIdPRevoked Action = "session.idp_revoked"
	// ActionSessionRoleNarrowed records a re-assertion demoting a live session.
	ActionSessionRoleNarrowed Action = "session.role_narrowed"
	// ActionSessionClaimsUnverified records the hub failing to reach the IdP.
	ActionSessionClaimsUnverified Action = "session.claims_unverified"
	// ActionSessionClaimsRejected records the IdP refusing a re-assertion.
	ActionSessionClaimsRejected Action = "session.claims_rejected"
	// ActionSessionClaimsStale records a privileged operation blocked on claim age.
	ActionSessionClaimsStale Action = "session.claims_stale"

	// ActionRoleBindingGranted records a runtime binding granting a role.
	ActionRoleBindingGranted Action = "role_binding.granted"
	// ActionRoleBindingDenied records a runtime binding taking a role away.
	ActionRoleBindingDenied Action = "role_binding.denied"
	// ActionRoleBindingDeleted records a runtime binding being removed.
	ActionRoleBindingDeleted Action = "role_binding.deleted"

	// ActionQuotaDenied records admission control refusing an operation.
	ActionQuotaDenied Action = "quota.denied"
	// ActionQuotaOverrideSet records a per-identity quota override being written.
	ActionQuotaOverrideSet Action = "quota.override_set"
	// ActionQuotaOverrideCleared records an override being removed.
	ActionQuotaOverrideCleared Action = "quota.override_cleared"
	// ActionQuotaSpendRefused records a run stopped for exceeding a spend limit.
	ActionQuotaSpendRefused Action = "quota.spend_refused"

	// ActionResourceCeilingSet records a per-project resource ceiling being
	// written (Task 20301).
	//
	// Beside the quota overrides above, and for the same reason they are on the
	// trail: the authority to edit one is the authority to decide how much of
	// the machine a tenant gets. The fleet ceiling has no action of its own
	// because it is not editable at runtime — it comes from config.yaml, which
	// is reviewed and deployed rather than written through an API.
	ActionResourceCeilingSet Action = "resource_ceiling.set"
	// ActionResourceCeilingCleared records a per-project ceiling being removed,
	// after which the project is bounded by the fleet ceiling alone.
	ActionResourceCeilingCleared Action = "resource_ceiling.cleared"

	// ActionSealingKeyRotated records the secret store's sealing key being rotated.
	ActionSealingKeyRotated Action = "sealing_key.rotated"
	// ActionSealingKeyRetired records a superseded sealing key being retired.
	ActionSealingKeyRetired Action = "sealing_key.retired"

	// ActionSTTCredentialSet records the speech-to-text key being configured.
	ActionSTTCredentialSet Action = "stt.credential.set"
	// ActionSTTCredentialCleared records the speech-to-text key being removed.
	ActionSTTCredentialCleared Action = "stt.credential.cleared"

	// ActionUserOffboard is the offboarding summary row.
	ActionUserOffboard Action = "user.offboard"
	// ActionUserOffboardSession records sessions revoked during offboarding.
	ActionUserOffboardSession Action = "user.offboard_session"
	// ActionUserOffboardToken records API tokens revoked during offboarding.
	ActionUserOffboardToken Action = "user.offboard_token"
	// ActionUserOffboardGlasses records glasses links revoked during offboarding.
	ActionUserOffboardGlasses Action = "user.offboard_glasses"
	// ActionUserOffboardDeny records deny bindings written during offboarding.
	ActionUserOffboardDeny Action = "user.offboard_deny"
	// ActionUserOffboardMembership records project memberships dropped during offboarding.
	ActionUserOffboardMembership Action = "user.offboard_membership"
	// ActionUserOffboardLease records secret leases released during offboarding.
	ActionUserOffboardLease Action = "user.offboard_lease"
	// ActionUserOffboardTask records tasks stopped during offboarding.
	ActionUserOffboardTask Action = "user.offboard_task"
	// ActionUserOffboardProject records projects reported as needing a new owner.
	ActionUserOffboardProject Action = "user.offboard_project"

	// ActionProjectMemberGrant records an identity joining a project's roster.
	ActionProjectMemberGrant Action = "project.member.grant"
	// ActionProjectMemberRevoke records a maintainer removing a member.
	ActionProjectMemberRevoke Action = "project.member.revoke"
	// ActionProjectMemberLeave records a member removing themselves.
	ActionProjectMemberLeave Action = "project.member.leave"
)

One constant per registered action.

These are what emission sites reference. Writing the literal again at an emission site is what tests/arch/auditaction_test.go exists to catch, so a new action means a new constant here and a new entry in registry.go — adding one without the other fails the build rather than shipping a name no consumer can match.

The constants are grouped and ordered to mirror registry.go. Keeping the two files in the same order is not cosmetic: it is how a reviewer reads a diff that adds an action and sees both halves of it at once.

func AuthzOutcome

func AuthzOutcome(outcome string) Action

AuthzOutcome returns the action for an authorization outcome.

func ExecutorLifecycle

func ExecutorLifecycle(verb string) Action

ExecutorLifecycle returns the action for an executor-fleet verb: ExecutorLifecycle("cordon") is ActionExecutorCordon.

func GitProxyEvent

func GitProxyEvent(kind string) Action

GitProxyEvent returns the action for a pkg/gitproxy EventKind.

func KubeGuardEvent

func KubeGuardEvent(kind string) Action

KubeGuardEvent returns the action for a pkg/kubeguard EventKind.

func WorkspacePhase

func WorkspacePhase(phase string) Action

WorkspacePhase returns the action for a workspace-provisioning phase.

func (Action) Family

func (a Action) Family() string

Family returns the dotted prefix an action belongs to: "task.upsert" is in the "task" family, "sandbox.attach.open" in "sandbox.attach".

The two-segment case is not a special rule bolted on for one family; it is what the names already say. `sandbox.image_denied` and `sandbox.attach.open` are not siblings — the first is a placement decision, the second is a human opening a shell — and a reader scanning the generated page for "everything about interactive access" is served by them grouping separately.

func (Action) String

func (a Action) String() string

String returns the action as it appears in the database column.

func (Action) Verb

func (a Action) Verb() string

Verb returns the action with its family prefix removed: "executor.cordon" yields "cordon".

This exists because several emitters put the bare verb in the payload as well as the qualified name in the column — `{"action":"cordon"}` alongside `event_type='executor.cordon'`. Those payloads are already in sealed rows, so converting an emission site to carry a fully-qualified Action must not change what lands in the payload. Verb is how a converted site keeps the stored bytes identical.

type Entry

type Entry struct {
	// Action is the exact string written to the event_type column.
	Action Action

	// Entity is the value of the entity_type column for rows of this action.
	// It is what the EntityID is an identifier *of*, and a reader filtering
	// the trail by subject needs it to know which id space they are in.
	Entity string

	// Home is which of the two `audit_events` chains this action is written
	// to: the hub's control plane, the project's own database, or — for
	// authorization decisions alone — whichever the decision was scoped to.
	//
	// Declared rather than inferred because there is nothing to infer it
	// from. The home is decided by which *statedb.DB handle an emission site
	// holds, which is a fact about a call stack and not about the row, so a
	// reader of the trail cannot recover it and a mis-routed row cannot be
	// distinguished from a correctly-routed one. See home.go.
	Home HomeDB

	// Trigger is one sentence, present tense, naming the moment the row is
	// written — not what the feature is for. "A push is refused by branch
	// policy", not "guards pushes".
	Trigger string

	// Payload lists the JSON keys the emitter can set, in the order the
	// emitter sets them. Keys are frequently conditional: an emitter omits
	// what it does not know. The list is what a consumer may *expect to see*,
	// not what every row carries.
	Payload []string

	// Stability marks how much a consumer may rely on this.
	Stability Stability

	// Read is the permission a caller must hold to read rows of this action
	// back through the hub's audit API.
	//
	// It is per-entry rather than a package constant because the trail is one
	// table serving several audiences, and the day a family needs narrower
	// reads than authz.PermAuditRead the registry must be able to say so
	// without a schema change. Today every entry names the same permission,
	// and the generated page says that plainly rather than implying a
	// distinction that does not exist.
	Read authz.Permission

	// Note is optional: a second sentence for an action whose name or payload
	// would otherwise mislead. Most entries do not need one, and an entry that
	// has one usually earned it by being confusable with a neighbour.
	Note string
}

Entry is one registered action: everything the generated reference page says about it, and everything the gates check.

func All

func All() []Entry

All returns every registered entry, sorted by action name. The slice is a fresh copy: callers may sort or filter it without disturbing the registry.

func InFamily

func InFamily(family string) []Entry

InFamily returns the registered actions of one family, sorted by name.

func InHome

func InHome(h HomeDB) []Entry

InHome returns every registered action whose home is h, sorted by name.

Used by the generated page and by the merged reader, which needs to know which actions it should expect to find in which chain in order to tell "this project has no executor events because none happened" apart from "because I was reading the wrong database".

func Lookup

func Lookup(a Action) (Entry, bool)

Lookup returns the entry for a, and whether it is registered.

type HomeDB

type HomeDB string

HomeDB names the chain an action is recorded in.

const (
	// HomeControlPlane: the hub's own state.db. Facts about the fleet and the
	// hub as a whole — which executors exist, who holds a credential, who
	// logged in, what an operator administered. These outlive any one project
	// and several of them belong to no project at all, so a project's chain is
	// the wrong place for them even when a project is what triggered them.
	HomeControlPlane HomeDB = "control-plane"

	// HomeProject: the project's own .cloop/state.db. The plan's life — tasks
	// created, dispatched and finished, steps appended, the project's config
	// written. These travel with the project directory, which is what makes a
	// project's trail readable after it has been moved off the hub that ran it.
	HomeProject HomeDB = "project"

	// HomeEither: genuinely both, depending on the scope of the thing being
	// recorded — not "we did not decide".
	//
	// One family needs this honestly. An authorization decision is recorded
	// against whatever it was scoped to: a permission check on a project lands
	// in that project's chain, and a fleet-wide one lands in the hub's. Forcing
	// either answer would make the declaration a lie, and a lie here is worse
	// than the ambiguity it papers over, because the runtime assertion would
	// then fire on correct code and the next person would delete the assertion
	// rather than the lie.
	//
	// The gate keeps this from becoming a dumping ground: an entry declaring
	// HomeEither must carry a Note explaining what varies, or tests/arch fails.
	// An escape hatch that costs a sentence stays rare.
	HomeEither HomeDB = "either"
)

func HomeOf

func HomeOf(a Action) (HomeDB, bool)

HomeOf returns where a registered action is recorded, and whether the action is registered at all. An unregistered action has no declared home — callers deciding whether to assert must not treat that as a mismatch, because an unknown name is tests/arch's problem, not the emit path's.

func (HomeDB) Describe

func (h HomeDB) Describe() string

Describe is the one-line gloss the generated page uses. Kept next to the constants so a reader changing what a home means changes its description in the same edit.

func (HomeDB) String

func (h HomeDB) String() string

String renders the home as it appears in the generated docs and in the --source column of a merged read.

func (HomeDB) Valid

func (h HomeDB) Valid() bool

Valid reports whether h is one of the declared homes. The zero value is not valid, which is the point: an entry that forgot to say fails the gate rather than defaulting into somebody's chain.

type Stability

type Stability string

Stability says how much a consumer may rely on an action's name and payload.

const (
	// StabilityStable: the name and the payload keys listed for it will not
	// change. Safe to key a detection rule on. New payload keys may still be
	// added — a consumer must tolerate that — but no listed key will be
	// removed or repurposed.
	StabilityStable Stability = "stable"

	// StabilityBeta: the action fires, and its rows are real, but its name or
	// payload may still change while the surface that emits it settles. Key a
	// dashboard on it; do not key a paging alert on it.
	StabilityBeta Stability = "beta"

	// StabilityDeprecated: still emitted for compatibility, replaced by
	// something else. The Note says by what. Kept in the registry rather than
	// deleted because stored rows still carry the name and a reader looking it
	// up deserves an answer better than silence.
	StabilityDeprecated Stability = "deprecated"
)

func (Stability) Valid

func (s Stability) Valid() bool

Valid reports whether s is a known stability marker.

Jump to

Keyboard shortcuts

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