Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 9 additions & 9 deletions agentcore/artifact/artifact.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// Package artifact is the Artifact Core:
// Ref, Binding and the two-state RetentionLedger. The ledger
// persists itself; claims are activated before the owner fact is appended and
// orphans are released by the pre-collection reconciliation (ART-RET-3).
// orphans are released by the pre-collection reconciliation.
package artifact

import (
Expand Down Expand Up @@ -64,7 +64,7 @@ type Integrity struct {
Value string `json:"value"`
}

// Ref locates and verifies immutable content (ART-REF-1).
// Ref locates and verifies immutable content.
type Ref struct {
Scheme Scheme `json:"scheme"`
Authority Authority `json:"authority"`
Expand All @@ -76,7 +76,7 @@ type Ref struct {
ExpiresAtUnixMilli *int64 `json:"expiresAtUnixMilli,omitempty"`
}

// Validate applies ART-ID-1 and ART-REF-2.
// Validate checks locator components, durability, integrity and expiry.
//
//nolint:gocritic // Ref is intentionally passed by value as an immutable wire value.
func (r Ref) Validate() error {
Expand Down Expand Up @@ -109,7 +109,7 @@ func (r Ref) Identity() (string, error) {
return string(raw), nil
}

// Binding maps a stable BindingID to an immutable Ref (ART-BND-1).
// Binding maps a stable BindingID to an immutable Ref.
type Binding struct {
ID BindingID `json:"id"`
Ref Ref `json:"ref"`
Expand Down Expand Up @@ -179,7 +179,7 @@ const (
ClaimReleased ClaimState = "released"
)

// BindingSet is a canonical, resolved retention set (ART-RET-1).
// BindingSet is a canonical, resolved retention set.
type BindingSet struct {
BindingIDs []BindingID `json:"bindingIds"`
RefSetDigest RefSetDigest `json:"refSetDigest"`
Expand Down Expand Up @@ -243,7 +243,7 @@ func SortedUniqueBindingIDs(ids []BindingID) []BindingID {
return out[:n]
}

// ClaimOwnerQuery selects claims by owner (ART-RET-3). Identities nil selects
// ClaimOwnerQuery selects claims by owner. Identities nil selects
// every owner of the Kind under the Authority; an explicit list selects those
// owners only, and an empty identity in it matches nothing. Limit is the page
// size, 0 meaning DefaultClaimPageSize.
Expand Down Expand Up @@ -272,14 +272,14 @@ type ClaimPage struct {
// DefaultClaimPageSize is the ClaimsByOwner page size when the query gives none.
const DefaultClaimPageSize = 256

// RetentionLedger keeps Active/Released claims (ART-RET-2). It persists
// RetentionLedger keeps Active/Released claims. It persists
// itself; Activate returns only once the claim is durable.
type RetentionLedger interface {
Activate(context.Context, ClaimID, ClaimOwner, BindingSet) (RetentionClaim, error)
LookupClaim(context.Context, ClaimID) (RetentionClaim, bool, error)
ReleaseActive(context.Context, ClaimID) error
// ClaimsByOwner enumerates the matching claims of every state in stable
// ClaimID order under a watermark cursor (ART-RET-3).
// ClaimID order under a watermark cursor.
ClaimsByOwner(context.Context, ClaimOwnerQuery, ClaimCursor) (ClaimPage, error)
}

Expand Down Expand Up @@ -311,7 +311,7 @@ type OwnerVerifier interface {
}

// Reconcile releases Active claims in scope whose owner no longer exists
// (ART-RET-3). The caller guarantees no owner write in scope is in flight.
// The caller guarantees no owner write in scope is in flight.
func Reconcile(ctx context.Context, ledger RetentionLedger, scope ClaimOwnerScope, verifier OwnerVerifier) (int, error) {
claims, err := ActiveClaims(ctx, ledger, scope)
if err != nil {
Expand Down
22 changes: 11 additions & 11 deletions agentcore/artifact/artifacttest/conformance.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import (
)

// Fixture is one adapter under test. Ledger must verify sets through a
// BindingSetBuilder over Bindings (ART-RET-1). NewContent builds a cas
// BindingSetBuilder over Bindings. NewContent builds a cas
// ContentStore for one Authority; Advance moves the clock those stores judge
// expiry by, nil skips the expiry checks.
type Fixture struct {
Expand Down Expand Up @@ -80,7 +80,7 @@ func mustBinding(t *testing.T, ctx context.Context, store artifact.BindingStore,
return b
}

// ART-ID-1, ART-REF-1, ART-REF-2: validation, identity stability and the
// validation, identity stability and the
// identity-bound MediaType.
func testRef(t *testing.T) {
expires := int64(5)
Expand Down Expand Up @@ -129,7 +129,7 @@ func testRef(t *testing.T) {
}
}

// ART-BND-1: immutable bindings, exact-rebuild idempotency, conflict.
// immutable bindings, exact-rebuild idempotency, conflict.
func testBinding(t *testing.T, f Fixture) {
ctx := context.Background()
ref := sampleRef("k1", artifact.EventBound)
Expand Down Expand Up @@ -160,7 +160,7 @@ func testBinding(t *testing.T, f Fixture) {
}
}

// ART-RET-1, ART-RET-2 (builder half): sorted-unique ids, order-independent
// (builder half): sorted-unique ids, order-independent
// digest, ephemeral rejection.
func testSet(t *testing.T, f Fixture) {
ctx := context.Background()
Expand All @@ -187,7 +187,7 @@ func testSet(t *testing.T, f Fixture) {
}
}

// ART-RET-2: the state table, exact verification of incoming sets.
// the state table, exact verification of incoming sets.
func testLedger(t *testing.T, f Fixture) {
ctx := context.Background()
mustBinding(t, ctx, f.Bindings, "b1", sampleRef("k1", artifact.EventBound))
Expand Down Expand Up @@ -240,7 +240,7 @@ func (s ownerSet) OwnerExists(_ context.Context, o artifact.ClaimOwner) (bool, e
return s[o.Identity], nil
}

// ART-RET-3: reconciliation releases orphans and leaves owned claims alone.
// reconciliation releases orphans and leaves owned claims alone.
func testReconcile(t *testing.T, f Fixture) {
ctx := context.Background()
mustBinding(t, ctx, f.Bindings, "b1", sampleRef("k1", artifact.EventBound))
Expand All @@ -265,7 +265,7 @@ func testReconcile(t *testing.T, f Fixture) {
}
}

// ART-RET-3: watermark cursor pagination and owner filters.
// watermark cursor pagination and owner filters.
func testPaging(t *testing.T, f Fixture) {
ctx := context.Background()
mustBinding(t, ctx, f.Bindings, "b1", sampleRef("k1", artifact.EventBound))
Expand Down Expand Up @@ -389,7 +389,7 @@ func readAll(t *testing.T, r artifact.Resolver, ref artifact.Ref) string {
return string(data)
}

// ART-BND-2, ART-CAP-1, ART-CAP-2: cas keys, idempotent Put, verified reads
// cas keys, idempotent Put, verified reads
// and the error classification.
func testContent(t *testing.T, f Fixture) {
ctx := context.Background()
Expand Down Expand Up @@ -417,7 +417,7 @@ func testContent(t *testing.T, f Fixture) {
if info, err := store.Stat(ctx, ref); err != nil || info.MediaType != "text/plain" || *info.Integrity != *ref.Integrity {
t.Fatalf("stat = %+v %v", info, err)
}
// Classification (ART-CAP-1).
// Classification.
missing := ref
missing.Key = artifact.Key("sha256:" + strings.Repeat("0", 64))
missing.Integrity = &artifact.Integrity{Algorithm: "sha256", Value: strings.Repeat("0", 64)}
Expand Down Expand Up @@ -472,7 +472,7 @@ func testContent(t *testing.T, f Fixture) {
}
}

// ART-REF-2, ART-BND-2: promotion never lowers durability, clears expiry,
// promotion never lowers durability, clears expiry,
// yields a new Ref and a new Binding without touching the old one.
func testPromote(t *testing.T, f Fixture) {
ctx := context.Background()
Expand Down Expand Up @@ -522,7 +522,7 @@ func testPromote(t *testing.T, f Fixture) {
}
}

// ART-PRO-1: immutable registry, unique scheme and (scheme, authority),
// immutable registry, unique scheme and (scheme, authority),
// verification outcomes.
func testRegistry(t *testing.T) {
cas := artifact.CASScheme()
Expand Down
9 changes: 4 additions & 5 deletions agentcore/artifact/artifacttest/map.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import (
"github.com/felinics/twilight/agentcore/artifact"
)

// MapBindings is artifact.BindingStore over a Go map (ART-BND-1): the
// MapBindings is artifact.BindingStore over a Go map: the
// reference the suite is written against and the store the kernel's own
// tests bind through. The zero value is ready.
type MapBindings struct {
Expand Down Expand Up @@ -60,8 +60,7 @@ func (s *MapBindings) ResolveBinding(ctx context.Context, id artifact.BindingID)
return b, nil
}

// MapLedger is artifact.RetentionLedger over a Go map (ART-RET-2,
// ART-RET-3). Builder, when set, verifies every activated set against the
// MapLedger is artifact.RetentionLedger over a Go map. Builder, when set, verifies every activated set against the
// bindings it was built from.
type MapLedger struct {
Builder artifact.BindingSetBuilder
Expand Down Expand Up @@ -126,7 +125,7 @@ func (l *MapLedger) ReleaseActive(_ context.Context, id artifact.ClaimID) error
}

// ClaimsByOwner pages the owner's claims in ClaimID order under a watermark
// cursor (ART-RET-3): a first page fixes its watermark at the last matching
// cursor: a first page fixes its watermark at the last matching
// id, so claims activated while paging stay out of the enumeration.
func (l *MapLedger) ClaimsByOwner(_ context.Context, q artifact.ClaimOwnerQuery, cursor artifact.ClaimCursor) (artifact.ClaimPage, error) {
if q.Kind == "" || q.Authority == "" {
Expand Down Expand Up @@ -162,7 +161,7 @@ func (l *MapLedger) ClaimsByOwner(_ context.Context, q artifact.ClaimOwnerQuery,
return artifact.ClaimPage{Items: items}, nil
}

// matchesIdentity is ART-RET-3: nil selects every identity, an explicit
// matchesIdentity is nil selects every identity, an explicit
// list selects its members, and an empty identity never matches.
func matchesIdentity(q artifact.ClaimOwnerQuery, identity string) bool {
if identity == "" {
Expand Down
15 changes: 7 additions & 8 deletions agentcore/artifact/content.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,14 @@ import (
"io"
)

// SchemeCAS is the standard content-addressed scheme (ART-CAP-2): Key is the
// SchemeCAS is the standard content-addressed scheme: Key is the
// content digest in the form <algorithm>:<hex> and equals Integrity.
const SchemeCAS Scheme = "cas"

// IntegritySHA256 is the one integrity algorithm the reference store speaks.
const IntegritySHA256 = "sha256"

// Info is what a Resolver knows about a Ref's content (ART-BND-2).
// Info is what a Resolver knows about a Ref's content.
type Info struct {
MediaType string
SizeBytes *uint64
Expand All @@ -32,16 +32,16 @@ type PutRequest struct {
}

// PromoteRequest asks for a Ref of the same content at TargetScheme and
// TargetAuthority with at least the durability of the source (ART-REF-2).
// TargetAuthority with at least the durability of the source.
type PromoteRequest struct {
TargetScheme Scheme
TargetAuthority Authority
Durability Durability
}

// Resolver reads content behind a Ref and verifies it against the Ref's
// declared size and integrity (ART-BND-2). Failures are classified by
// ErrorCode (ART-CAP-1): ErrNotFound, ErrExpired, ErrUnauthorized (a key of
// declared size and integrity. Failures are classified by
// ErrorCode: ErrNotFound, ErrExpired, ErrUnauthorized (a key of
// another Authority), ErrCorrupt (stored bytes disagree with the Ref) and
// ErrUnsupported (a scheme this resolver does not speak).
type Resolver interface {
Expand All @@ -50,14 +50,13 @@ type Resolver interface {
}

// Store writes content and returns its Ref only once the write is durable.
// A repeated Put of identical bytes is idempotent (ART-BND-2).
// A repeated Put of identical bytes is idempotent.
type Store interface {
Put(context.Context, PutRequest) (Ref, error)
}

// Promoter produces a new Ref for existing content at the requested target
// and durability; it never lowers durability and never rewrites a Binding
// (ART-BND-2, ART-REF-2).
type Promoter interface {
Promote(context.Context, Ref, PromoteRequest) (Ref, error)
}
Expand All @@ -70,7 +69,7 @@ type ContentStore interface {
}

// DefaultMaxContentBytes bounds a Put when a store's options give no cap
// (ART-CAP-1, size amplification).
// (size amplification).
const DefaultMaxContentBytes int64 = 64 << 20

// CASKey is the cas Key and Integrity value of data.
Expand Down
8 changes: 4 additions & 4 deletions agentcore/artifact/registry.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ type (
ProviderInstanceID string
)

// SchemeDefinition is the resolution contract of one Scheme (ART-CAP-2).
// SchemeDefinition is the resolution contract of one Scheme.
type SchemeDefinition struct {
Scheme Scheme
SupportedDurabilities []Durability
Expand All @@ -35,7 +35,7 @@ type ProviderBinding struct {
}

// Registry is the immutable scheme and provider index of one deployment
// (ART-PRO-1): every Scheme has one definition, every (Scheme, Authority) one
// every Scheme has one definition, every (Scheme, Authority) one
// provider instance, and verified use requires both.
type Registry struct {
schemes map[Scheme]SchemeDefinition
Expand Down Expand Up @@ -99,7 +99,7 @@ func (r *Registry) Provider(scheme Scheme, authority Authority) (ProviderBinding
// Verify admits a Ref for verified use: a registered scheme that supports the
// Ref's durability, the scheme's own rules, and a bound provider for its
// Authority. An unknown scheme is ErrUnsupported so callers can keep such a
// Ref conservatively (ART-RET-2) rather than treat it as invalid.
// Ref conservatively rather than treat it as invalid.
//
//nolint:gocritic // Ref is intentionally passed by value as an immutable wire value.
func (r *Registry) Verify(ref Ref) error {
Expand Down Expand Up @@ -131,7 +131,7 @@ func (r *Registry) Verify(ref Ref) error {
}

// CASScheme is the standard cas definition: every durability, and a Key that
// equals the Ref's integrity in <algorithm>:<value> form (ART-CAP-2).
// equals the Ref's integrity in <algorithm>:<value> form.
func CASScheme() SchemeDefinition {
return SchemeDefinition{
Scheme: SchemeCAS,
Expand Down
Loading
Loading