kioku-core 0.8.0.2 → 0.9.0.0
raw patch · 16 files changed
+200/−43 lines, 16 filesdep ~keirodep ~keiro-coredep ~kioku-apiPVP ok
version bump matches the API change (PVP)
Dependency ranges changed: keiro, keiro-core, kioku-api, kioku-core, kioku-migrations, kiroku-store, shibuya-core, shibuya-kiroku-adapter
API changes (from Hackage documentation)
Files
- CHANGELOG.md +16/−2
- kioku-core.cabal +14/−14
- src/Kioku/Distill/Timer/Deferred.hs +1/−1
- src/Kioku/Distill/Timer/Worker.hs +1/−1
- src/Kioku/Memory/Embedding/Worker.hs +1/−1
- src/Kioku/Recall.hs +2/−1
- src/Kioku/Session/Domain.hs +3/−0
- src/Kioku/Worker/Failure.hs +1/−0
- test/Kioku/AIRuntimeSpec.hs +2/−0
- test/Kioku/CodecCompatSpec.hs +2/−1
- test/Kioku/EmbeddingWorkerSpec.hs +136/−2
- test/Kioku/IdempotencySpec.hs +2/−1
- test/Kioku/MemorySpaceSpec.hs +7/−7
- test/Kioku/ReadModelReconcileSpec.hs +2/−3
- test/Kioku/SessionLineageSpec.hs +8/−7
- test/Kioku/TimerWorkerSpec.hs +2/−2
CHANGELOG.md view
@@ -1,12 +1,26 @@ # Changelog +## [Unreleased]++## 0.9.0.0 — 2026-10-12++### Breaking Changes++- Require the Keiro 0.20 / Kiroku Store 0.11 cohort, Shibuya core 0.10.0.1,+ and Kiroku adapter 0.6.0.1, with internal packages at 0.9.0.0.++### Changed++- Classify `EventDecodeFailed` as permanent. Preserve subscription identity,+ authorization, retry policy, and timer transaction boundaries.+- Verify real adapter delivery, durable checkpoints, confirmed legacy adoption,+ conflicting-target refusal, and clean shutdown with a fake embedding provider.+ ## 0.8.0.2 — 2026-10-06 ### Fixed - Keep the shared Kioku release version and internal bounds aligned with the migration test-fixture cleanup fix.--## [Unreleased] ## 0.8.0.1 — 2026-10-05
kioku-core.cabal view
@@ -1,6 +1,6 @@ cabal-version: 3.0 name: kioku-core-version: 0.8.0.2+version: 0.9.0.0 synopsis: Reusable agent memory runtime description: Core runtime for kioku. M1 establishes the application effect stack; later@@ -132,14 +132,14 @@ hasql-transaction >=1.0 && <1.3, hs-opentelemetry-api >=1.0 && <1.1, keiki ^>=0.9.1.0,- keiro ^>=0.19.0.0,- keiro-core ^>=0.19.0.0,- kioku-api ^>=0.8.0.2,- kiroku-store ^>=0.9.0.1,+ keiro ^>=0.20.0.0,+ keiro-core ^>=0.20.0.0,+ kioku-api ^>=0.9.0.0,+ kiroku-store ^>=0.11.0.0, lens >=5.2 && <5.4, mmzk-typeid >=0.7 && <0.8,- shibuya-core ^>=0.10.0.0,- shibuya-kiroku-adapter ^>=0.5.1.5,+ shibuya-core ^>=0.10.0.1,+ shibuya-kiroku-adapter ^>=0.6.0.1, shikumi ^>=0.4.0.0, shikumi-trace ^>=0.3.0.0, text >=2.1 && <2.2,@@ -199,14 +199,14 @@ generic-lens >=2.2 && <2.4, hasql >=1.6, hasql-transaction >=1.0,- keiro ^>=0.19.0.0,- keiro-core ^>=0.19.0.0,- kioku-api ^>=0.8.0.2,- kioku-core ^>=0.8.0.2,- kioku-migrations:test-support ^>=0.8.0.2,- kiroku-store ^>=0.9.0.1,+ keiro ^>=0.20.0.0,+ keiro-core ^>=0.20.0.0,+ kioku-api ^>=0.9.0.0,+ kioku-core ^>=0.9.0.0,+ kioku-migrations:test-support ^>=0.9.0.0,+ kiroku-store ^>=0.11.0.0, lens >=5.2,- shibuya-core ^>=0.10.0.0,+ shibuya-core ^>=0.10.0.1, shikumi ^>=0.4.0.0, shikumi-trace ^>=0.3.0.0, tasty >=1.5,
src/Kioku/Distill/Timer/Deferred.hs view
@@ -29,7 +29,7 @@ import Kioku.Distill.Timer.Outcome (FireOutcome (..)) import Kioku.Distill.Timer.Worker (fireKiokuTimer) import Kioku.Id (SessionId, parseIdLenient)-import Kioku.Prelude+import Kioku.Prelude hiding (contexts) import Kiroku.Store.Effect (Store) import Kiroku.Store.Effect.Resource (KirokuStoreResource) import Kiroku.Store.Error (StoreError)
src/Kioku/Distill/Timer/Worker.hs view
@@ -46,7 +46,7 @@ ) import Kioku.Id (parseIdLenient) import Kioku.Partition (parseOptionalPartitionSpace)-import Kioku.Prelude+import Kioku.Prelude hiding (contexts) import Kiroku.Store.Effect (Store) import Kiroku.Store.Effect.Resource (KirokuStoreResource) import Kiroku.Store.Error (StoreError)
src/Kioku/Memory/Embedding/Worker.hs view
@@ -69,7 +69,7 @@ import Kioku.Memory.Embedding (EmbedError (..), embedWithRetry, embeddingModelCompatible, embeddingModelsCompatible, sha256Hex) import Kioku.Memory.EventStream (memoryCodec) import Kioku.Partition (memorySpaceColumn, memorySpaceParam)-import Kioku.Prelude+import Kioku.Prelude hiding (contexts) import Kioku.Recall.Capability (VectorCapability (..)) import Kioku.Worker.Failure (embeddingRetryDelay, isTransientStoreError) import Kiroku.Store.Connection (KirokuStore)
src/Kioku/Recall.hs view
@@ -119,6 +119,7 @@ recallTargetIsNamespaceWide, recallTargetNamespace, )+import Kioku.Api.Recall qualified as RecallApi import Kioku.Api.Scope (MemoryScope (..), Namespace (..), ScopeKind (..), scopeFromColumns, scopeKindText, scopeNamespaceText, scopeRefText) import Kioku.Api.Types (MemoryRecord (..), MemoryType, memoryTypeToText) import Kioku.Database.Schema (memoriesTable)@@ -364,7 +365,7 @@ Embedding -> pure (Left (RecallAIUnavailable err)) _ -> do when (request.strategy == Hybrid) (liftIO (System.IO.hPutStrLn System.IO.stderr "kioku recall: query embeddings disabled by AI policy; using keyword search"))- recallWithEmbeddingAdapter emptyEmbeddingModel VectorExtensionUnavailable context request {strategy = Keyword}+ recallWithEmbeddingAdapter emptyEmbeddingModel VectorExtensionUnavailable context request {RecallApi.strategy = Keyword} -- | Explicit host/test adapter. The supplied model is an independent API capability. recallWithEmbeddingAdapter ::
src/Kioku/Session/Domain.hs view
@@ -1,4 +1,7 @@ {-# LANGUAGE TemplateHaskell #-}+-- deriveAggregate also emits is*/inp* convenience helpers; this module uses+-- the inCtor* interface. Keep these generated helpers private, as in Memory.Domain.+{-# OPTIONS_GHC -Wno-unused-top-binds #-} module Kioku.Session.Domain ( SessionVertex (..),
src/Kioku/Worker/Failure.hs view
@@ -53,6 +53,7 @@ DuplicateEvent _ -> False EventAlreadyLinked _ _ -> False LinkSourceEventMissing _ -> False+ EventDecodeFailed _ -> False UnexpectedServerError _ _ -> False -- | Backoff for a redelivered @MemoryRecorded@ event, by zero-based delivery
test/Kioku/AIRuntimeSpec.hs view
@@ -174,10 +174,12 @@ interactiveConfig :: AIConfig interactiveConfig = disabledAIConfig {distillationDefault = InteractiveConfig I.InteractiveClaude ((I.interactiveLaunchRequest "") {I.modelId = Just "fixture"})} +interactive :: (AIFeature -> I.InteractiveLaunchRequest -> IO (Either AIExecutionError I.InteractiveLaunchResult)) -> IO AIRuntime interactive launch = expect =<< newAIRuntime noHostCapabilities {allowInteractive = True, launchInteractive = Just launch} interactiveConfig data Variant = Valid | WrongId | Missing | BadDomain | Nonzero | Symlink | Oversized | Cancelled deriving (Show) +fixture :: Variant -> AIFeature -> I.InteractiveLaunchRequest -> IO (Either AIExecutionError I.InteractiveLaunchResult) fixture Cancelled feature _ = pure (Left (AIInteractiveFailed feature "cancelled")) fixture variant feature req = do let raw = T.drop 1 (snd (T.breakOn "\n" req.userPrompt))
test/Kioku/CodecCompatSpec.hs view
@@ -43,6 +43,7 @@ MemoryTagsUpdatedData (..), ) import Kioku.Memory.Domain qualified as MemoryDomain+import Kioku.Memory.Domain qualified as Recorded (MemoryRecordedData (..)) import Kioku.Memory.EventStream (parseMemoryEvent) import Kioku.Prelude (toJSON) import Kioku.Session.Domain@@ -148,7 +149,7 @@ decoded @?= event, testCase "a legacy-marked actor survives encode and decode" do -- A stream rebuilt and re-encoded must not launder its legacy actor into a real one.- let event = MemoryRecorded partitionedRecord {actorPrincipal = LegacyPrincipal (legacyPrincipalRef "demo-agent")}+ let event = MemoryRecorded partitionedRecord {Recorded.actorPrincipal = LegacyPrincipal (legacyPrincipalRef "demo-agent")} decoded <- either (assertFailure . Text.unpack) pure (parseMemoryEvent (toJSON event)) decoded @?= event ]
test/Kioku/EmbeddingWorkerSpec.hs view
@@ -7,15 +7,20 @@ import Baikai.Embedding (EmbeddingModel) import Baikai.Embedding qualified as Embedding+import Control.Concurrent (threadDelay) import Data.Aeson qualified as Aeson import Data.Aeson.KeyMap qualified as KeyMap import Data.Functor.Contravariant ((>$<)) import Data.HashMap.Strict qualified as HashMap+import Data.IORef (modifyIORef', newIORef, readIORef, writeIORef)+import Data.Int (Int64) import Data.List (sort) import Data.Set qualified as Set+import Data.UUID qualified as UUID import Data.Vector qualified as Vector import Effectful (Eff, IOE, (:>)) import Effectful.Error.Static (Error)+import Effectful.Exception qualified as Exception import Hasql.Decoders qualified as D import Hasql.Encoders qualified as E import Hasql.Statement (Statement, preparable)@@ -43,6 +48,7 @@ EmbeddingWorkerEnv (..), backfillMissingEmbeddings, embeddingHandler,+ embeddingWorkerProcessor, selectEmbeddingCandidateIds, shouldSkipEmbedding, )@@ -54,15 +60,18 @@ import Kioku.Worker.Failure (embeddingRetryDelay, isTransientStoreError) import Kiroku.Store.Connection (defaultConnectionSettings) import Kiroku.Store.Effect (Store)-import Kiroku.Store.Effect.Resource (KirokuStoreResource)+import Kiroku.Store.Effect.Resource (KirokuStoreResource, getKirokuStore) import Kiroku.Store.Error (StoreError (..)) import Kiroku.Store.Read (readStreamForward)+import Kiroku.Store.Settings (DecodeFailure (..)) import Kiroku.Store.Transaction (runTransaction)-import Kiroku.Store.Types (ExpectedVersion (..), RecordedEvent (..), StreamName (..), StreamVersion (..))+import Kiroku.Store.Types (EventId (..), ExpectedVersion (..), RecordedEvent (..), StreamName (..), StreamVersion (..))+import Shibuya.App qualified as App import Shibuya.Core.Ack (AckDecision (..), DeadLetterReason (..), HaltReason (..), RetryDelay (..)) import Shibuya.Core.AckHandle (AckHandle (..)) import Shibuya.Core.Ingested (Ingested (..)) import Shibuya.Core.Types (Attempt (..), Envelope (..), MessageId (..))+import System.Timeout (timeout) import Test.Tasty (TestTree, testGroup) import Test.Tasty.HUnit (Assertion, assertBool, assertFailure, testCase, (@?=)) @@ -77,6 +86,9 @@ shouldSkipEmbedding True (Just "hash-b") "hash-a" @?= False, testCase "classifies only connection-shaped store errors as transient" testTransientClassification, testCase "backs off on the documented retry schedule" testRetrySchedule,+ testCase "real adapter delivers, checkpoints, and shuts down" (testAdapterLifecycle False),+ testCase "real adapter adopts a confirmed legacy checkpoint and resumes" (testAdapterLifecycle True),+ testCase "real adapter refuses a conflicting target without advancing" testAdapterWrongTarget, testCase "provider failure acks retry" testProviderFailureRetries, testCase "undecodable payload acks dead-letter" testUndecodablePayloadDeadLetters, testCase "successful embedding acks ok and stores the vector" testSuccessStoresEmbedding,@@ -93,6 +105,7 @@ -- kiroku constructor breaks this test's exhaustiveness at the source, not here. testTransientClassification :: Assertion testTransientClassification = do+ isTransientStoreError (EventDecodeFailed (DecodeFailure (EventId UUID.nil) "invalid stored payload")) @?= False isTransientStoreError PoolAcquisitionTimeout @?= True isTransientStoreError (ConnectionLost "reset by peer") @?= True isTransientStoreError (ConnectionError "pool closed") @?= True@@ -106,6 +119,127 @@ isTransientStoreError (StreamAlreadyExists (StreamName "s")) @?= False isTransientStoreError (EventAlreadyLinked (StreamName "s") Nothing) @?= False isTransientStoreError (LinkSourceEventMissing (StreamName "s")) @?= False++-- | Exercise the production adapter and its acknowledgement bridge, not just the+-- handler. A confirmed old checkpoint is represented by the unbound row that+-- migration 0014 preserves; the migration suite independently proves that evolution.+testAdapterLifecycle :: Bool -> Assertion+testAdapterLifecycle legacy = withEmbeddingEnv $ \appEnv -> do+ deliveries <- newIORef []+ bounded "adapter delivery and shutdown" $ runOrFail appEnv $ do+ capability <- detectVectorCapability embeddingDims+ liftIO (capability @?= VectorAvailable)+ when legacy $ do+ (_, prior) <- recordFixtureMemory testContext "already consumed before upgrade"+ position <- eventCheckpointPosition prior+ seedCheckpoint position "unbound" Nothing+ (memoryId, recorded) <- recordFixtureMemory testContext "delivered through the real adapter"+ expected <- eventCheckpointPosition recorded+ store <- getKirokuStore+ processor <-+ embeddingWorkerProcessor+ testContextProvider+ capability+ ( mkTestEnv+ ( \content -> do+ modifyIORef' deliveries (content :)+ content @?= "delivered through the real adapter"+ pure (Right (Vector.replicate embeddingDims 0.1))+ )+ )+ store+ app <- App.runApp App.defaultAppConfig [processor] >>= liftIO . expectRight "runApp"+ Exception.finally+ ( do+ awaitAdapter $ do+ embedded <- loadEmbeddingState (idText memoryId)+ checkpoint <- loadCheckpoint+ pure (embedded && checkpoint == [(expected, "category", Just "kioku_memory")])+ )+ ( do+ drained <- App.stopAppGracefully (App.ShutdownConfig 2 4) app+ liftIO (assertBool "acknowledgements drained without forced shutdown" drained)+ App.waitApp app+ )+ readIORef deliveries >>= (@?= ["delivered through the real adapter"])+ -- Reopening the runtime verifies the position and binding are durable.+ saved <- runOrFail appEnv loadCheckpoint+ case saved of+ [(position, "category", Just "kioku_memory")] -> assertBool "checkpoint advanced" (position > 0)+ other -> assertFailure ("unexpected durable checkpoint: " <> show other)++testAdapterWrongTarget :: Assertion+testAdapterWrongTarget = withEmbeddingEnv $ \appEnv -> do+ called <- newIORef False+ bounded "target refusal and shutdown" $ runOrFail appEnv $ do+ capability <- detectVectorCapability embeddingDims+ seedCheckpoint 0 "category" (Just "another_category")+ before <- loadCheckpoint+ (memoryId, _) <- recordFixtureMemory testContext "must not reach provider"+ store <- getKirokuStore+ processor <-+ embeddingWorkerProcessor+ testContextProvider+ capability+ (mkTestEnv (\_ -> writeIORef called True >> pure (Right (Vector.replicate embeddingDims 0.1))))+ store+ app <- App.runApp App.defaultAppConfig [processor] >>= liftIO . expectRight "runApp"+ Exception.finally+ ( do+ -- A valid subscription is infinite; a refused source terminates before+ -- delivering. Terminal processors leave the master's live metrics map.+ App.waitApp app+ after <- loadCheckpoint+ liftIO (after @?= before)+ embedded <- loadEmbeddingState (idText memoryId)+ liftIO (assertBool "refused subscription wrote no vector" (not embedded))+ )+ (App.stopApp app)+ readIORef called >>= (@?= False)++bounded :: String -> IO () -> IO ()+bounded label action =+ timeout 15_000_000 action >>= \case+ Just () -> pure ()+ Nothing -> assertFailure (label <> " exceeded 15 seconds")++awaitAdapter :: Eff AppEffects Bool -> Eff AppEffects ()+awaitAdapter check = do+ ready <- check+ unless ready (liftIO (threadDelay 10_000) >> awaitAdapter check)++seedCheckpoint :: Int64 -> Text -> Maybe Text -> Eff AppEffects ()+seedCheckpoint position kind category =+ runTransaction $+ Tx.statement (position, kind, category) $+ preparable+ "INSERT INTO kiroku.subscriptions (subscription_name, last_seen, target_kind, target_category) VALUES ('kioku-memory-embedding', $1, $2, $3)"+ ( ((\(p, _, _) -> p) >$< E.param (E.nonNullable E.int8))+ <> ((\(_, k, _) -> k) >$< E.param (E.nonNullable E.text))+ <> ((\(_, _, c) -> c) >$< E.param (E.nullable E.text))+ )+ D.noResult++-- Stream-local reads carry their own cursor. Subscription checkpoints use the+-- durable $all position of the same event instead.+eventCheckpointPosition :: RecordedEvent -> Eff AppEffects Int64+eventCheckpointPosition recorded =+ let EventId uuid = recorded.eventId+ in runTransaction $+ Tx.statement uuid $+ preparable+ "SELECT stream_version FROM kiroku.stream_events WHERE stream_id = 0 AND event_id = $1"+ (E.param (E.nonNullable E.uuid))+ (D.singleRow (D.column (D.nonNullable D.int8)))++loadCheckpoint :: Eff AppEffects [(Int64, Text, Maybe Text)]+loadCheckpoint =+ runTransaction $+ Tx.statement () $+ preparable+ "SELECT last_seen, target_kind, target_category FROM kiroku.subscriptions WHERE subscription_name = 'kioku-memory-embedding' ORDER BY consumer_group_member"+ E.noParams+ (D.rowList ((,,) <$> D.column (D.nonNullable D.int8) <*> D.column (D.nonNullable D.text) <*> D.column (D.nullable D.text))) testRetrySchedule :: Assertion testRetrySchedule = do
test/Kioku/IdempotencySpec.hs view
@@ -20,6 +20,7 @@ import Kioku.Id (MemoryId, SessionId, genMemoryId, genSessionId, idText) import Kioku.Memory qualified as Memory import Kioku.Memory.Domain (ArchiveMemoryData (..), RecordMemoryData (..), SupersedeMemoryData (..))+import Kioku.Memory.Domain qualified as Record (RecordMemoryData (..)) import Kioku.Memory.EventStream (memoryStream) import Kioku.Memory.ReadModel (MemoryRow (..)) import Kioku.Migrations.TestSupport (withKiokuMigratedDatabase)@@ -223,7 +224,7 @@ expectRightM "record with supersedes" =<< Memory.recordWithContext testContext- (recordData source now "record lineage source") {supersedes = Just target}+ (recordData source now "record lineage source") {Record.supersedes = Just target} row <- getMemoryRow source liftIO $ assertEqual "the record projection keeps its target" (Just (idText target)) row.supersedes assertMemoryEvents source 1
test/Kioku/MemorySpaceSpec.hs view
@@ -22,7 +22,6 @@ ( MemoryAccessContext, MemoryPermission (..), MemorySpaceId,- RecordedPrincipal, legacyMemorySpaceId, memoryContextRecordedActor, memoryContextSpace,@@ -32,10 +31,11 @@ import Kioku.Api.Types (Confidence (..), MemoryType (..)) import Kioku.App (AppEffects, runAppIO, withNoopAppEnv) import Kioku.Distill.L1 (L1Error (..), L1RunMode (..), distillSessionL1, scopedScanCandidates)-import Kioku.Distill.Runtime (DistillRuntime, TestRunners (..), testDistillRuntime, withDistillWorkspace, withTestRunners)+import Kioku.Distill.Runtime (TestRunners (..), testDistillRuntime, withTestRunners) import Kioku.Id (MemoryId, SessionId, genMemoryId, genSessionId, idText) import Kioku.Memory qualified as Memory import Kioku.Memory.Domain (ArchiveMemoryData (..), MemoryEvent (..), MemoryRecordedData (..), RecordMemoryData (..), SupersedeMemoryData (..))+import Kioku.Memory.Domain qualified as Record (RecordMemoryData (..)) import Kioku.Memory.EventStream (memoryStream, parseMemoryEvent) import Kioku.Memory.ReadModel (MemoryRow (..)) import Kioku.Migrations.TestSupport (withKiokuMigratedDatabase)@@ -198,7 +198,7 @@ result <- Memory.recordWithContext testContext- (recordData mid testContext now) {memorySpaceId = otherSpace}+ (recordData mid testContext now) {Record.memorySpaceId = otherSpace} liftIO case result of Left (Memory.MemorySpaceMismatch requested authorized) -> do assertEqual "names the requested space" otherSpace requested@@ -219,7 +219,7 @@ result <- Memory.recordWithContext testContext- (recordData mid testContext now) {actorPrincipal = otherActorPrincipal}+ (recordData mid testContext now) {Record.actorPrincipal = otherActorPrincipal} liftIO case result of Left (Memory.MemoryActorMismatch claimed authorized) -> do assertEqual "names the claimed actor" otherActorPrincipal claimed@@ -371,9 +371,9 @@ elsewhere <- recordFixture otherContext "record lineage target in another space" now <- liftIO getCurrentTime missingResult <-- Memory.recordWithContext testContext (recordData source testContext now) {supersedes = Just absent}+ Memory.recordWithContext testContext (recordData source testContext now) {Record.supersedes = Just absent} crossSpaceResult <-- Memory.recordWithContext testContext (recordData source testContext now) {supersedes = Just elsewhere}+ Memory.recordWithContext testContext (recordData source testContext now) {Record.supersedes = Just elsewhere} assertHiddenTarget "record" missingResult crossSpaceResult assertMemoryEventCount source 0 @@ -439,7 +439,7 @@ recordFixture context content = do mid <- liftIO genMemoryId now <- liftIO getCurrentTime- result <- Memory.recordWithContext context (recordData mid context now) {content}+ result <- Memory.recordWithContext context (recordData mid context now) {Record.content = content} case result of Left err -> liftIO (assertFailure ("Memory.recordWithContext: " <> show err)) Right written -> pure written
test/Kioku/ReadModelReconcileSpec.hs view
@@ -21,8 +21,7 @@ import Data.Text qualified as Text import Data.Text.Encoding (encodeUtf8)-import Data.Time (getCurrentTime)-import Effectful (Eff, IOE, liftIO, (:>))+import Effectful (Eff, IOE, (:>)) import Effectful.Error.Static (Error) import Hasql.Transaction qualified as Tx import Keiro.ReadModel@@ -38,7 +37,7 @@ import Kioku.Id (SessionId, genMemoryId, genSessionId, idText) import Kioku.Memory qualified as Memory import Kioku.Migrations.TestSupport (withKiokuMigratedDatabase)-import Kioku.Prelude+import Kioku.Prelude hiding (use) import Kioku.ReadModel ( ReadModelSchema (..), ReconcileOutcome (..),
test/Kioku/SessionLineageSpec.hs view
@@ -15,6 +15,7 @@ import Kioku.Migrations.TestSupport (withKiokuMigratedDatabase) import Kioku.Session qualified as Session import Kioku.Session.Domain (StartSessionData (..))+import Kioku.Session.Domain qualified as Start (StartSessionData (..)) import Kioku.Session.ReadModel (SessionRow (..)) import Kioku.SpaceFixtures (testActorPrincipal, testContext, testSpace) import Kiroku.Store.Connection (defaultConnectionSettings)@@ -99,12 +100,12 @@ } selfPrevious, selfParent, negativeDepth, depthPastCap, parentAtDepthZero, rootAtDepthOne :: LineageCase-selfPrevious sid o t = (baseStart sid o t) {previousSessionId = Just sid}-selfParent sid o t = (baseStart sid o t) {parentSessionId = Just sid, delegationDepth = 1}-negativeDepth sid o t = (baseStart sid o t) {delegationDepth = -1}-depthPastCap sid o t = (baseStart sid o t) {parentSessionId = Just o, delegationDepth = 65}-parentAtDepthZero sid o t = (baseStart sid o t) {parentSessionId = Just o, delegationDepth = 0}-rootAtDepthOne sid o t = (baseStart sid o t) {delegationDepth = 1}+selfPrevious sid o t = (baseStart sid o t) {Start.previousSessionId = Just sid}+selfParent sid o t = (baseStart sid o t) {Start.parentSessionId = Just sid, Start.delegationDepth = 1}+negativeDepth sid o t = (baseStart sid o t) {Start.delegationDepth = -1}+depthPastCap sid o t = (baseStart sid o t) {Start.parentSessionId = Just o, Start.delegationDepth = 65}+parentAtDepthZero sid o t = (baseStart sid o t) {Start.parentSessionId = Just o, Start.delegationDepth = 0}+rootAtDepthOne sid o t = (baseStart sid o t) {Start.delegationDepth = 1} assertInvalidLineage :: LineageCase -> IO () assertInvalidLineage mkCommand =@@ -172,7 +173,7 @@ (sort (rowSessionId <$> chain)) insertCyclicPair ::- (IOE :> es, Store :> es) =>+ (Store :> es) => SessionId -> SessionId -> Eff es ()
test/Kioku/TimerWorkerSpec.hs view
@@ -45,14 +45,14 @@ import Kioku.Distill.L1 (scopedScanCandidates) import Kioku.Distill.L2 (SceneTimerPayload (..), l2SceneProcessManagerName, l2SceneTimerId) import Kioku.Distill.L3 (partitionedCorrelationId)-import Kioku.Distill.Runtime (DistillRuntime, TestRunners (..), newDistillRuntime, testDistillRuntime, withDistillWorkspace, withTestRunners)+import Kioku.Distill.Runtime (DistillRuntime, TestRunners (..), newDistillRuntime, testDistillRuntime, withTestRunners) import Kioku.Distill.Timer (L1TimerPayload (..), l1ExtractProcessManagerName) import Kioku.Distill.Timer.Deferred import Kioku.Distill.Timer.Outcome (FireOutcome (..), timerMarkerEventId) import Kioku.Distill.Timer.Worker (drainKiokuTimers, runKiokuTimerWorkerOnce) import Kioku.Id (SessionId, genSessionId, idText) import Kioku.Migrations.TestSupport (withKiokuMigratedDatabase)-import Kioku.Prelude+import Kioku.Prelude hiding (failing) import Kioku.Session qualified as Session import Kioku.Session.Domain (StartSessionData (..)) import Kioku.SpaceFixtures (legacyContext, otherContext, otherSpace, testContext, testContextProvider, testSpace)