From 07e4703173af64f2ea664120efbb4859522f9c6d Mon Sep 17 00:00:00 2001 From: Jared Jakacky Date: Mon, 8 Jun 2026 21:38:00 -0500 Subject: [PATCH] Clarify Opskit contract scope and readiness metadata --- component.go | 6 ++++++ doc.go | 5 +++++ docs/api.md | 5 +++-- docs/design.md | 6 ++++++ registry.go | 4 ++++ 5 files changed, 24 insertions(+), 2 deletions(-) diff --git a/component.go b/component.go index e02dd96..e41ee47 100644 --- a/component.go +++ b/component.go @@ -35,6 +35,12 @@ type ComponentInfo struct { // Workerkit loops, or application-owned execution paths. Admission control // should use ReadinessContributor when a component needs readiness semantics // that differ from Status.Ready. +// +// Component implementations must be safe for concurrent calls to ComponentInfo, +// Status, and any optional Opskit capability methods when shared across +// registries, probes, admin routes, CLIs, tests, or execution layers. Opskit +// protects registry state, but it does not serialize or synchronize component +// internals. type Component interface { ComponentInfo() ComponentInfo Status(context.Context) Status diff --git a/doc.go b/doc.go index 89303ad..332aab4 100644 --- a/doc.go +++ b/doc.go @@ -11,4 +11,9 @@ // component registry. It must not execute checks, dispatch commands, schedule // work, authorize operations, export telemetry, own lifecycle, or decide // application policy. +// +// Registry methods are safe for concurrent use, but component implementations +// may be called concurrently by different callers. Components that expose +// mutable state through Opskit interfaces are responsible for their own +// synchronization. package opskit diff --git a/docs/api.md b/docs/api.md index 8c0dc76..31a0d87 100644 --- a/docs/api.md +++ b/docs/api.md @@ -140,8 +140,9 @@ dashboards, and admin presentation. Labels must be safe to expose anywhere `ComponentInfo` appears. Do not use labels for secrets, user data, request IDs, dynamic health details, or high-cardinality values. -Use `Attribute` fields on status, inspection, checks, commands, and future event -records for runtime or result-specific metadata. +Use `Attribute` fields on status, inspection, checks, and commands for runtime +or result-specific metadata. If Opskit later defines a passive event envelope, +that event shape can use the same safe attribute model. ### `ComponentFunc` diff --git a/docs/design.md b/docs/design.md index 92f0705..88fd641 100644 --- a/docs/design.md +++ b/docs/design.md @@ -154,6 +154,12 @@ descriptive methods when asked, and exposes optional capabilities. It does not own the lifecycle of the components it stores. +The registry is safe for concurrent use, but it does not make component +internals safe. Servekit routes, readiness probes, CLIs, tests, and Workerkit +execution may call component methods at the same time. Component implementations +that expose mutable state through Opskit interfaces must provide their own +synchronization. + ## Core Contract Every registered component implements one required interface: diff --git a/registry.go b/registry.go index 1235167..f65601f 100644 --- a/registry.go +++ b/registry.go @@ -15,6 +15,10 @@ import ( // expose registry data through probes or admin endpoints should pass bounded // contexts. // +// Registry methods are safe for concurrent use. Component methods may also be +// called concurrently through registry read paths, so component implementations +// must protect their own mutable state. +// // The zero value is ready to use. type Registry struct { mu sync.RWMutex