openworkproof 1.0.0__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.
- openworkproof/__init__.py +1 -0
- openworkproof/acceptance.py +3006 -0
- openworkproof/cli.py +164 -0
- openworkproof/composition.py +832 -0
- openworkproof/evidence.py +8281 -0
- openworkproof/execution_adapter.py +256 -0
- openworkproof/external_acceptor.py +211 -0
- openworkproof/mcp_server.py +2939 -0
- openworkproof/mcp_transport.py +72 -0
- openworkproof/models.py +3380 -0
- openworkproof/policy.py +2494 -0
- openworkproof/predicates.py +333 -0
- openworkproof/repo_pipeline/__init__.py +74 -0
- openworkproof/repo_pipeline/analysis.py +152 -0
- openworkproof/repo_pipeline/errors.py +64 -0
- openworkproof/repo_pipeline/models.py +80 -0
- openworkproof/repo_pipeline/output.py +68 -0
- openworkproof/repo_pipeline/reader.py +47 -0
- openworkproof/repo_pipeline/sources.py +120 -0
- openworkproof/repo_pipeline/traversal.py +253 -0
- openworkproof/repo_tools.py +8382 -0
- openworkproof/runtime_context.py +189 -0
- openworkproof/schema_registry.py +623 -0
- openworkproof/schemas/v0.1/acceptance-receipt.schema.json +1 -0
- openworkproof/schemas/v0.1/acceptance-rejection-receipt.schema.json +1 -0
- openworkproof/schemas/v0.1/action-receipt.schema.json +1 -0
- openworkproof/schemas/v0.1/capability-grant.schema.json +1 -0
- openworkproof/schemas/v0.1/schema-registry.json +1 -0
- openworkproof/schemas/v0.1/work-order.schema.json +1 -0
- openworkproof/signing.py +421 -0
- openworkproof/state.py +765 -0
- openworkproof/team_network_client.py +419 -0
- openworkproof/trusted_helper.py +269 -0
- openworkproof-1.0.0.dist-info/METADATA +578 -0
- openworkproof-1.0.0.dist-info/RECORD +39 -0
- openworkproof-1.0.0.dist-info/WHEEL +5 -0
- openworkproof-1.0.0.dist-info/entry_points.txt +2 -0
- openworkproof-1.0.0.dist-info/licenses/LICENSE +202 -0
- openworkproof-1.0.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
"""Current ledger, evidence, and replay-checkpoint revalidation.
|
|
2
|
+
|
|
3
|
+
Package-internal module shared by trusted handlers and acceptance
|
|
4
|
+
transactions. It extracts the "is this AuthorizationContext still the
|
|
5
|
+
current authority" check from mcp_server.py without changing behavior.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from __future__ import annotations
|
|
9
|
+
|
|
10
|
+
import os
|
|
11
|
+
from pathlib import Path
|
|
12
|
+
import stat
|
|
13
|
+
from datetime import datetime
|
|
14
|
+
|
|
15
|
+
import openworkproof.evidence as evidence
|
|
16
|
+
from openworkproof.policy import (
|
|
17
|
+
AuthorizationContext,
|
|
18
|
+
AuthorizationLedgerPrefix,
|
|
19
|
+
derive_authorization_context,
|
|
20
|
+
)
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
class RuntimeContextError(RuntimeError):
|
|
24
|
+
"""The supplied authorization context is not the current authority."""
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
def committed_evidence_matches_context(
|
|
28
|
+
root: Path,
|
|
29
|
+
context: AuthorizationContext,
|
|
30
|
+
) -> None:
|
|
31
|
+
expected = {
|
|
32
|
+
item.reference.path: item
|
|
33
|
+
for item in context.committed_evidence
|
|
34
|
+
}
|
|
35
|
+
actual_paths = {
|
|
36
|
+
reference.path
|
|
37
|
+
for receipt in context.ledger_prefix.receipts
|
|
38
|
+
for reference in receipt.evidence_refs
|
|
39
|
+
}
|
|
40
|
+
if set(expected) != actual_paths:
|
|
41
|
+
raise RuntimeContextError(
|
|
42
|
+
"authorization evidence coverage is stale"
|
|
43
|
+
)
|
|
44
|
+
root_metadata = os.stat(root, follow_symlinks=False)
|
|
45
|
+
if not stat.S_ISDIR(root_metadata.st_mode):
|
|
46
|
+
raise RuntimeContextError(
|
|
47
|
+
"authorization evidence root is unavailable"
|
|
48
|
+
)
|
|
49
|
+
for path, item in expected.items():
|
|
50
|
+
relative = path.removeprefix("evidence/")
|
|
51
|
+
parts = Path(relative).parts
|
|
52
|
+
if (
|
|
53
|
+
relative == path
|
|
54
|
+
or not parts
|
|
55
|
+
or Path(relative).is_absolute()
|
|
56
|
+
or any(part in {"", ".", ".."} for part in parts)
|
|
57
|
+
):
|
|
58
|
+
raise RuntimeContextError(
|
|
59
|
+
"authorization evidence path is outside the root"
|
|
60
|
+
)
|
|
61
|
+
descriptors: list[int] = []
|
|
62
|
+
recheck_descriptors: list[int] = []
|
|
63
|
+
try:
|
|
64
|
+
descriptors, identities = evidence._open_evidence_chain(
|
|
65
|
+
root,
|
|
66
|
+
parts,
|
|
67
|
+
expected_size=item.reference.size_bytes,
|
|
68
|
+
)
|
|
69
|
+
payload, metadata = evidence._read_exact_descriptor(
|
|
70
|
+
descriptors[-1],
|
|
71
|
+
digest=item.reference.sha256,
|
|
72
|
+
size_bytes=item.reference.size_bytes,
|
|
73
|
+
allowed_links=(1,),
|
|
74
|
+
)
|
|
75
|
+
metadata_identity = (
|
|
76
|
+
metadata.st_dev,
|
|
77
|
+
metadata.st_ino,
|
|
78
|
+
metadata.st_mode,
|
|
79
|
+
metadata.st_nlink,
|
|
80
|
+
metadata.st_size,
|
|
81
|
+
)
|
|
82
|
+
recheck_descriptors, recheck_identities = (
|
|
83
|
+
evidence._open_evidence_chain(
|
|
84
|
+
root,
|
|
85
|
+
parts,
|
|
86
|
+
expected_size=item.reference.size_bytes,
|
|
87
|
+
)
|
|
88
|
+
)
|
|
89
|
+
if (
|
|
90
|
+
payload != item.payload
|
|
91
|
+
or metadata_identity != identities[-1]
|
|
92
|
+
or recheck_identities != identities
|
|
93
|
+
):
|
|
94
|
+
raise OSError("authorization evidence changed")
|
|
95
|
+
except OSError as error:
|
|
96
|
+
raise RuntimeContextError(
|
|
97
|
+
"authorization evidence bytes are stale"
|
|
98
|
+
) from error
|
|
99
|
+
finally:
|
|
100
|
+
evidence._close_evidence_descriptors(recheck_descriptors)
|
|
101
|
+
evidence._close_evidence_descriptors(descriptors)
|
|
102
|
+
root_after = os.stat(root, follow_symlinks=False)
|
|
103
|
+
if (root_metadata.st_dev, root_metadata.st_ino) != (
|
|
104
|
+
root_after.st_dev,
|
|
105
|
+
root_after.st_ino,
|
|
106
|
+
):
|
|
107
|
+
raise RuntimeContextError(
|
|
108
|
+
"authorization evidence root changed during validation"
|
|
109
|
+
)
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
def require_current_context(
|
|
113
|
+
ledger_path: Path,
|
|
114
|
+
evidence_root: Path,
|
|
115
|
+
context: AuthorizationContext,
|
|
116
|
+
now: datetime,
|
|
117
|
+
lock_descriptor: int,
|
|
118
|
+
) -> None:
|
|
119
|
+
evidence.require_all_publications_committed(
|
|
120
|
+
ledger_path,
|
|
121
|
+
evidence_root=evidence_root,
|
|
122
|
+
_borrowed_lock_descriptor=lock_descriptor,
|
|
123
|
+
)
|
|
124
|
+
connection = evidence.connect_ledger(ledger_path)
|
|
125
|
+
try:
|
|
126
|
+
work_order, receipts, grants, groups = (
|
|
127
|
+
evidence._replay_receipt_publication_ledger(connection)
|
|
128
|
+
)
|
|
129
|
+
attempts = evidence._validated_grant_attempts(
|
|
130
|
+
connection,
|
|
131
|
+
work_order,
|
|
132
|
+
receipts,
|
|
133
|
+
)
|
|
134
|
+
acceptances = evidence._validated_acceptance_receipts(
|
|
135
|
+
connection,
|
|
136
|
+
work_order,
|
|
137
|
+
)
|
|
138
|
+
rejections = evidence._validated_acceptance_rejections(
|
|
139
|
+
connection,
|
|
140
|
+
work_order,
|
|
141
|
+
)
|
|
142
|
+
state_row = connection.execute(
|
|
143
|
+
"""
|
|
144
|
+
SELECT current_state, version
|
|
145
|
+
FROM work_order_state
|
|
146
|
+
WHERE singleton = 1
|
|
147
|
+
"""
|
|
148
|
+
).fetchone()
|
|
149
|
+
finally:
|
|
150
|
+
connection.close()
|
|
151
|
+
current_prefix = AuthorizationLedgerPrefix(
|
|
152
|
+
effective_grants=tuple(
|
|
153
|
+
sorted(grants.values(), key=lambda item: item.grant_id)
|
|
154
|
+
),
|
|
155
|
+
grant_attempts=tuple(
|
|
156
|
+
sorted(attempts.values(), key=lambda item: item.digest)
|
|
157
|
+
),
|
|
158
|
+
receipts=receipts,
|
|
159
|
+
)
|
|
160
|
+
if (
|
|
161
|
+
work_order != context.work_order
|
|
162
|
+
or current_prefix != context.ledger_prefix
|
|
163
|
+
or context.transaction_time != now
|
|
164
|
+
or state_row
|
|
165
|
+
!= (
|
|
166
|
+
context.current_state,
|
|
167
|
+
evidence._derive_protocol_transaction_version(
|
|
168
|
+
action_receipts=receipts,
|
|
169
|
+
acceptance_receipts=acceptances,
|
|
170
|
+
acceptance_rejections=rejections,
|
|
171
|
+
),
|
|
172
|
+
)
|
|
173
|
+
or any(state_value != "COMMITTED" for _, state_value in groups)
|
|
174
|
+
):
|
|
175
|
+
raise RuntimeContextError(
|
|
176
|
+
"authorization context is not the current ledger snapshot"
|
|
177
|
+
)
|
|
178
|
+
committed_evidence_matches_context(evidence_root, context)
|
|
179
|
+
rebuilt = derive_authorization_context(
|
|
180
|
+
work_order,
|
|
181
|
+
current_prefix,
|
|
182
|
+
context.committed_evidence,
|
|
183
|
+
context.replay_checkpoint,
|
|
184
|
+
now,
|
|
185
|
+
)
|
|
186
|
+
if rebuilt != context:
|
|
187
|
+
raise RuntimeContextError(
|
|
188
|
+
"authorization context does not reproduce exactly"
|
|
189
|
+
)
|