cks-runtime 0.1.2__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,127 @@
1
+ """
2
+ In-memory Runtime Storage.
3
+
4
+ Reference implementation used by tests.
5
+ """
6
+
7
+ from __future__ import annotations
8
+
9
+ from copy import deepcopy
10
+
11
+ from cks_runtime.session.session import RuntimeSession
12
+ from cks_runtime.storage.exceptions import (
13
+ SessionNotFound,
14
+ VersionNotFound,
15
+ )
16
+ from cks_runtime.storage.storage import RuntimeStorage
17
+ from cks_runtime.versioning.version import RuntimeVersion
18
+
19
+
20
+ class InMemoryStorage(RuntimeStorage):
21
+ """
22
+ Reference Runtime Storage implementation.
23
+
24
+ Provides deterministic in-memory persistence for:
25
+
26
+ - Runtime Sessions;
27
+ - Runtime Versions.
28
+
29
+ Intended primarily for testing and as the
30
+ reference Runtime Storage implementation.
31
+ """
32
+
33
+ def __init__(self) -> None:
34
+ self._sessions: dict[str, RuntimeSession] = {}
35
+ self._versions: dict[str, RuntimeVersion] = {}
36
+
37
+ def save_session(
38
+ self,
39
+ session: RuntimeSession,
40
+ ) -> None:
41
+ """
42
+ Persist a Runtime Session.
43
+ """
44
+
45
+ self._sessions[
46
+ session.session_id
47
+ ] = deepcopy(session)
48
+
49
+ def load_session(
50
+ self,
51
+ session_id: str,
52
+ ) -> RuntimeSession:
53
+ """
54
+ Restore a Runtime Session.
55
+ """
56
+
57
+ try:
58
+ session = self._sessions[
59
+ session_id
60
+ ]
61
+ except KeyError as exc:
62
+ raise SessionNotFound(
63
+ session_id
64
+ ) from exc
65
+
66
+ return deepcopy(session)
67
+
68
+ def save_version(
69
+ self,
70
+ version: RuntimeVersion,
71
+ ) -> None:
72
+ """
73
+ Persist a Runtime Version.
74
+ """
75
+
76
+ self._versions[
77
+ version.version_id
78
+ ] = deepcopy(version)
79
+
80
+ def load_version(
81
+ self,
82
+ version_id: str,
83
+ ) -> RuntimeVersion:
84
+ """
85
+ Restore a Runtime Version.
86
+ """
87
+
88
+ try:
89
+ version = self._versions[
90
+ version_id
91
+ ]
92
+ except KeyError as exc:
93
+ raise VersionNotFound(
94
+ version_id
95
+ ) from exc
96
+
97
+ return deepcopy(version)
98
+
99
+ def has_session(
100
+ self,
101
+ session_id: str,
102
+ ) -> bool:
103
+ """
104
+ Determine whether a Runtime Session exists.
105
+ """
106
+
107
+ return session_id in self._sessions
108
+
109
+
110
+ def has_version(
111
+ self,
112
+ version_id: str,
113
+ ) -> bool:
114
+ """
115
+ Determine whether a Runtime Version exists.
116
+ """
117
+
118
+ return version_id in self._versions
119
+
120
+
121
+ def clear(self) -> None:
122
+ """
123
+ Remove every persisted Runtime object.
124
+ """
125
+
126
+ self._sessions.clear()
127
+ self._versions.clear()
@@ -0,0 +1,90 @@
1
+ """
2
+ Abstract Runtime Storage.
3
+
4
+ SPEC-006 Storage.
5
+ """
6
+
7
+ from __future__ import annotations
8
+
9
+ from abc import ABC
10
+ from abc import abstractmethod
11
+
12
+ from cks_runtime.session.session import RuntimeSession
13
+ from cks_runtime.versioning.version import RuntimeVersion
14
+
15
+
16
+ class RuntimeStorage(ABC):
17
+ """
18
+ Abstract Runtime Storage.
19
+
20
+ Storage persists Runtime operational state.
21
+
22
+ Storage never:
23
+
24
+ - owns Sessions;
25
+ - owns Transactions;
26
+ - interprets semantics.
27
+ """
28
+
29
+ @abstractmethod
30
+ def save_session(
31
+ self,
32
+ session: RuntimeSession,
33
+ ) -> None:
34
+ """
35
+ Persist a Runtime Session.
36
+ """
37
+
38
+ @abstractmethod
39
+ def load_session(
40
+ self,
41
+ session_id: str,
42
+ ) -> RuntimeSession:
43
+ """
44
+ Restore a Runtime Session.
45
+ """
46
+
47
+ @abstractmethod
48
+ def has_session(
49
+ self,
50
+ session_id: str,
51
+ ) -> bool:
52
+ """
53
+ Check whether a Runtime Session exists.
54
+ """
55
+
56
+ @abstractmethod
57
+ def save_version(
58
+ self,
59
+ version: RuntimeVersion,
60
+ ) -> None:
61
+ """
62
+ Persist a Runtime Version.
63
+ """
64
+
65
+ @abstractmethod
66
+ def load_version(
67
+ self,
68
+ version_id: str,
69
+ ) -> RuntimeVersion:
70
+ """
71
+ Restore a Runtime Version.
72
+ """
73
+
74
+ @abstractmethod
75
+ def has_version(
76
+ self,
77
+ version_id: str,
78
+ ) -> bool:
79
+ """
80
+ Check whether a Runtime Version exists.
81
+ """
82
+
83
+ @abstractmethod
84
+ def clear(self) -> None:
85
+ """
86
+ Remove every persisted object.
87
+
88
+ Intended primarily for testing and
89
+ deterministic reference implementations.
90
+ """
File without changes
@@ -0,0 +1,149 @@
1
+ """
2
+ Runtime Transaction model.
3
+
4
+ A Transaction is the exclusive mechanism through which
5
+ Runtime Session operational state may evolve.
6
+
7
+ Transactions coordinate execution.
8
+ They do not define semantic behaviour.
9
+ """
10
+
11
+ from dataclasses import dataclass, field
12
+ from enum import Enum
13
+ from typing import Any
14
+ from uuid import uuid4
15
+
16
+
17
+ class TransactionStatus(Enum):
18
+ """
19
+ Canonical Runtime Transaction states.
20
+ """
21
+
22
+ CREATED = "created"
23
+ EXECUTING = "executing"
24
+ VALIDATING = "validating"
25
+ COMMITTED = "committed"
26
+ ROLLED_BACK = "rolled_back"
27
+ ABORTED = "aborted"
28
+
29
+
30
+ @dataclass
31
+ class RuntimeTransaction:
32
+ """
33
+ Represents one Runtime Transaction.
34
+
35
+ Ownership:
36
+
37
+ - exactly one Runtime Session owns a Transaction;
38
+ - Transaction modifies operational state only;
39
+ - semantic validation belongs to CKS Core.
40
+ """
41
+
42
+ session: Any
43
+
44
+ transaction_id: str = field(
45
+ default_factory=lambda: str(uuid4())
46
+ )
47
+
48
+ operations: list[Any] = field(
49
+ default_factory=list
50
+ )
51
+
52
+ diagnostics: list[Any] = field(
53
+ default_factory=list
54
+ )
55
+
56
+ status: TransactionStatus = (
57
+ TransactionStatus.CREATED
58
+ )
59
+
60
+ def _ensure_not_completed(self) -> bool:
61
+ """
62
+ Return False when the Transaction has
63
+ already reached a terminal state.
64
+ """
65
+
66
+ return not self.completed
67
+
68
+ def add_operation(
69
+ self,
70
+ operation: Any,
71
+ ) -> None:
72
+ """
73
+ Register a Runtime operation.
74
+ """
75
+
76
+ self.operations.append(operation)
77
+
78
+ def add_diagnostic(
79
+ self,
80
+ diagnostic: Any,
81
+ ) -> None:
82
+ """
83
+ Register a Runtime or Core diagnostic.
84
+ """
85
+
86
+ self.diagnostics.append(diagnostic)
87
+
88
+ def mark_executing(self) -> None:
89
+ """
90
+ Mark Transaction as executing.
91
+ """
92
+
93
+ if not self._ensure_not_completed():
94
+ return
95
+
96
+ self.status = TransactionStatus.EXECUTING
97
+
98
+ def mark_validating(self) -> None:
99
+ """
100
+ Mark Transaction as validating.
101
+ """
102
+
103
+ if not self._ensure_not_completed():
104
+ return
105
+
106
+ self.status = TransactionStatus.VALIDATING
107
+
108
+ def commit(self) -> None:
109
+ """
110
+ Complete Transaction successfully.
111
+ """
112
+
113
+ if not self._ensure_not_completed():
114
+ return
115
+
116
+ self.status = TransactionStatus.COMMITTED
117
+
118
+ def rollback(self) -> None:
119
+ """
120
+ Roll back pending operational changes.
121
+ """
122
+
123
+ if not self._ensure_not_completed():
124
+ return
125
+
126
+ self.status = TransactionStatus.ROLLED_BACK
127
+
128
+ def abort(self) -> None:
129
+ """
130
+ Abort Transaction execution.
131
+ """
132
+
133
+ if not self._ensure_not_completed():
134
+ return
135
+
136
+ self.status = TransactionStatus.ABORTED
137
+
138
+ @property
139
+ def completed(self) -> bool:
140
+ """
141
+ Whether the Transaction has reached
142
+ a terminal state.
143
+ """
144
+
145
+ return self.status in {
146
+ TransactionStatus.COMMITTED,
147
+ TransactionStatus.ROLLED_BACK,
148
+ TransactionStatus.ABORTED,
149
+ }
@@ -0,0 +1,125 @@
1
+ """
2
+ Runtime Transaction Manager.
3
+
4
+ Owns Transaction lifecycle.
5
+
6
+ Responsibilities:
7
+
8
+ - begin Transactions;
9
+ - retrieve Transactions;
10
+ - coordinate completion;
11
+ - preserve Session ownership.
12
+
13
+ Does not:
14
+
15
+ - perform semantic validation;
16
+ - create Versions;
17
+ - persist Runtime state;
18
+ - modify CKS Core behaviour.
19
+ """
20
+
21
+ from typing import Any
22
+
23
+ from .transaction import RuntimeTransaction
24
+
25
+
26
+ class TransactionManager:
27
+ """
28
+ Coordinates Runtime Transactions.
29
+ """
30
+
31
+ def __init__(self) -> None:
32
+ self._transactions: dict[
33
+ str,
34
+ RuntimeTransaction
35
+ ] = {}
36
+
37
+ def begin(
38
+ self,
39
+ session: Any,
40
+ ) -> RuntimeTransaction:
41
+ """
42
+ Begin a Transaction for a Session.
43
+
44
+ Exactly one active Transaction may exist
45
+ per Session.
46
+ """
47
+
48
+ if session.active_transaction is not None:
49
+ raise RuntimeError(
50
+ "Session already has an active transaction."
51
+ )
52
+
53
+ transaction = RuntimeTransaction(
54
+ session=session
55
+ )
56
+
57
+ self._transactions[
58
+ transaction.transaction_id
59
+ ] = transaction
60
+
61
+ session.active_transaction = transaction
62
+
63
+ return transaction
64
+
65
+ def retrieve(
66
+ self,
67
+ transaction_id: str,
68
+ ) -> RuntimeTransaction | None:
69
+ """
70
+ Retrieve a Transaction by identity.
71
+ """
72
+
73
+ return self._transactions.get(
74
+ transaction_id
75
+ )
76
+
77
+ def commit(
78
+ self,
79
+ transaction: RuntimeTransaction,
80
+ ) -> None:
81
+ """
82
+ Commit a Transaction.
83
+ """
84
+
85
+ transaction.commit()
86
+
87
+ transaction.session.active_transaction = None
88
+
89
+ def rollback(
90
+ self,
91
+ transaction: RuntimeTransaction,
92
+ ) -> None:
93
+ """
94
+ Roll back a Transaction.
95
+ """
96
+
97
+ transaction.rollback()
98
+
99
+ transaction.session.active_transaction = None
100
+
101
+ def abort(
102
+ self,
103
+ transaction: RuntimeTransaction,
104
+ ) -> None:
105
+ """
106
+ Abort a Transaction.
107
+ """
108
+
109
+ transaction.abort()
110
+
111
+ transaction.session.active_transaction = None
112
+
113
+ def list_transactions(
114
+ self,
115
+ ) -> list[RuntimeTransaction]:
116
+ """
117
+ Return known Transactions.
118
+
119
+ Primarily intended for Runtime
120
+ management and testing.
121
+ """
122
+
123
+ return list(
124
+ self._transactions.values()
125
+ )
File without changes
@@ -0,0 +1,44 @@
1
+ """
2
+ Immutable Runtime Version.
3
+
4
+ A Runtime Version records the operational state of a
5
+ Runtime Session immediately following a committed Transaction.
6
+
7
+ Versions are immutable.
8
+ """
9
+
10
+ from __future__ import annotations
11
+
12
+ from dataclasses import dataclass, field
13
+ from datetime import datetime, UTC
14
+ from typing import Any
15
+ from uuid import uuid4
16
+
17
+
18
+ @dataclass(frozen=True, slots=True)
19
+ class RuntimeVersion:
20
+ """
21
+ Immutable Runtime Version.
22
+
23
+ Ownership:
24
+
25
+ - owned by exactly one Runtime Session;
26
+ - created from exactly one committed Transaction;
27
+ - records operational state only.
28
+ """
29
+
30
+ session_id: str
31
+
32
+ transaction_id: str
33
+
34
+ knowledge_structure: Any
35
+
36
+ metadata: dict[str, Any]
37
+
38
+ version_id: str = field(
39
+ default_factory=lambda: str(uuid4())
40
+ )
41
+
42
+ created_at: datetime = field(
43
+ default_factory=lambda: datetime.now(UTC)
44
+ )
@@ -0,0 +1,81 @@
1
+ """
2
+ Runtime Version Manager.
3
+
4
+ Creates immutable Runtime Versions from the
5
+ current Runtime Session state.
6
+ """
7
+
8
+ from __future__ import annotations
9
+
10
+ from cks_runtime.session.session import RuntimeSession
11
+ from cks_runtime.versioning.version import RuntimeVersion
12
+
13
+
14
+ class VersionManager:
15
+ """
16
+ Coordinates Runtime Version creation.
17
+ """
18
+
19
+ def create(
20
+ self,
21
+ session: RuntimeSession,
22
+ ) -> RuntimeVersion:
23
+ """
24
+ Create a new Runtime Version.
25
+
26
+ The Version is appended to the owning
27
+ Session Version History.
28
+ """
29
+
30
+ version = RuntimeVersion(
31
+ session_id=session.session_id,
32
+ transaction_id=(
33
+ session.active_transaction.transaction_id
34
+ if session.active_transaction is not None
35
+ else ""
36
+ ),
37
+ knowledge_structure=session.knowledge_structure,
38
+ metadata=dict(session.metadata),
39
+ )
40
+
41
+ session.version_history.append(version)
42
+
43
+ return version
44
+
45
+ def latest(
46
+ self,
47
+ session: RuntimeSession,
48
+ ) -> RuntimeVersion | None:
49
+ """
50
+ Return the latest Runtime Version.
51
+ """
52
+
53
+ if not session.version_history:
54
+ return None
55
+
56
+ return session.version_history[-1]
57
+
58
+ def retrieve(
59
+ self,
60
+ session: RuntimeSession,
61
+ version_id: str,
62
+ ) -> RuntimeVersion | None:
63
+ """
64
+ Retrieve a Runtime Version by identifier.
65
+ """
66
+
67
+ for version in session.version_history:
68
+ if version.version_id == version_id:
69
+ return version
70
+
71
+ return None
72
+
73
+ def list_versions(
74
+ self,
75
+ session: RuntimeSession,
76
+ ) -> tuple[RuntimeVersion, ...]:
77
+ """
78
+ Return immutable Runtime Version history.
79
+ """
80
+
81
+ return tuple(session.version_history)