fix(agent): purge sync.Once from pkg/agentic via core.Once (§14A)

Closes Mantis #863 ([agent] Phase 2: purge sync stdlib).

Per RFC plans/code/core/go/RFC.primitives-lifecycle.md §14A (landed core/go
dev 8995a80), swaps the four sync.Once usages to core.Once and the two
sync.Once{} reset-pattern callsites to core.Once.Reset():

pkg/agentic/statestore.go:
- Drop `import "sync"`.
- stateStoreRef.once: sync.Once → core.Once
- closeStateStore reset: `s.stateOnce = sync.Once{}` → `s.stateOnce.Reset()`

pkg/agentic/workspace_stats.go:
- Drop `import "sync"`.
- workspaceStatsRef.once: sync.Once → core.Once
- closeWorkspaceStatsStore reset: `s.workspaceStatsOnce = sync.Once{}` →
  `s.workspaceStatsOnce.Reset()`

pkg/agentic/prep.go:
- Drop `import "sync"`.
- PrepSubsystem.stateOnce + .workspaceStatsOnce: sync.Once → core.Once

The Reset() pattern matches stdlib semantics (see RFC §14A "Tradeoff: Once.
Reset semantics") — caller serialises via the existing closeStateStore /
closeWorkspaceStatsStore structure that nests Reset inside the lifecycle
inverse, so no concurrent Do races are introduced.

Net: 3 files, +7/-11. Mechanical line-edit per RFC §16 migration plan.

Audit re-check post-commit:
  grep -n '"sync"\|sync\.Once\|sync\.Mutex' pkg/agentic/{statestore,workspace_stats,prep}.go
  → empty (lib local variable named `sync` in mirror.go is unrelated; not
    in scope of this ticket).

Pre-flight verification: core.Once + Reset symbols verified present on
core/go dev 8995a80. Local AX-10 build blocked by the same pre-existing
workspace forge dep break that affects all consumers (root cause: fake
v0.8.0-alpha.1 pins per task #28); CI in healthy env will validate.

Co-Authored-By: Athena <athena@lthn.ai>
Co-Authored-By: Virgil <virgil@lethean.io>
This commit is contained in:
Snider 2026-04-25 00:58:49 +01:00
parent 34010f6d35
commit ba8de0c0bb
3 changed files with 7 additions and 11 deletions

View file

@ -8,7 +8,6 @@ import (
"crypto/sha256"
"encoding/base64"
"encoding/hex"
"sync"
"time"
"dappco.re/go/agent/pkg/lib"
@ -41,9 +40,9 @@ type PrepSubsystem struct {
failCount map[string]int
providers *ProviderManager
workspaces *core.Registry[*WorkspaceStatus]
stateOnce sync.Once
stateOnce core.Once
state *stateStoreRef
workspaceStatsOnce sync.Once
workspaceStatsOnce core.Once
workspaceStats *workspaceStatsRef
}

View file

@ -3,8 +3,6 @@
package agentic
import (
"sync"
core "dappco.re/go/core"
store "dappco.re/go/store"
)
@ -28,9 +26,9 @@ func stateStorePath() string {
}
// stateStoreRef keeps the store instance, its initialisation error, and a
// sync.Once so multiple callers observe the same lazily-initialised value.
// core.Once so multiple callers observe the same lazily-initialised value.
type stateStoreRef struct {
once sync.Once
once core.Once
instance *store.Store
err error
}
@ -102,7 +100,7 @@ func (s *PrepSubsystem) closeStateStore() {
}
ref.err = nil
s.state = nil
s.stateOnce = sync.Once{}
s.stateOnce.Reset()
}
// openStateStore attempts to open the canonical state store at

View file

@ -3,7 +3,6 @@
package agentic
import (
"sync"
"time"
core "dappco.re/go/core"
@ -25,7 +24,7 @@ const stateWorkspaceStatsGroup = "stats"
// separate from the top-level `stateStoreRef` so the two stores open
// independently — a missing parent DB does not disable top-level state.
type workspaceStatsRef struct {
once sync.Once
once core.Once
instance *store.Store
err error
}
@ -90,7 +89,7 @@ func (s *PrepSubsystem) closeWorkspaceStatsStore() {
}
ref.err = nil
s.workspaceStats = nil
s.workspaceStatsOnce = sync.Once{}
s.workspaceStatsOnce.Reset()
}
// openWorkspaceStatsStore opens the parent workspace stats database,