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.
Files changed (39) hide show
  1. openworkproof/__init__.py +1 -0
  2. openworkproof/acceptance.py +3006 -0
  3. openworkproof/cli.py +164 -0
  4. openworkproof/composition.py +832 -0
  5. openworkproof/evidence.py +8281 -0
  6. openworkproof/execution_adapter.py +256 -0
  7. openworkproof/external_acceptor.py +211 -0
  8. openworkproof/mcp_server.py +2939 -0
  9. openworkproof/mcp_transport.py +72 -0
  10. openworkproof/models.py +3380 -0
  11. openworkproof/policy.py +2494 -0
  12. openworkproof/predicates.py +333 -0
  13. openworkproof/repo_pipeline/__init__.py +74 -0
  14. openworkproof/repo_pipeline/analysis.py +152 -0
  15. openworkproof/repo_pipeline/errors.py +64 -0
  16. openworkproof/repo_pipeline/models.py +80 -0
  17. openworkproof/repo_pipeline/output.py +68 -0
  18. openworkproof/repo_pipeline/reader.py +47 -0
  19. openworkproof/repo_pipeline/sources.py +120 -0
  20. openworkproof/repo_pipeline/traversal.py +253 -0
  21. openworkproof/repo_tools.py +8382 -0
  22. openworkproof/runtime_context.py +189 -0
  23. openworkproof/schema_registry.py +623 -0
  24. openworkproof/schemas/v0.1/acceptance-receipt.schema.json +1 -0
  25. openworkproof/schemas/v0.1/acceptance-rejection-receipt.schema.json +1 -0
  26. openworkproof/schemas/v0.1/action-receipt.schema.json +1 -0
  27. openworkproof/schemas/v0.1/capability-grant.schema.json +1 -0
  28. openworkproof/schemas/v0.1/schema-registry.json +1 -0
  29. openworkproof/schemas/v0.1/work-order.schema.json +1 -0
  30. openworkproof/signing.py +421 -0
  31. openworkproof/state.py +765 -0
  32. openworkproof/team_network_client.py +419 -0
  33. openworkproof/trusted_helper.py +269 -0
  34. openworkproof-1.0.0.dist-info/METADATA +578 -0
  35. openworkproof-1.0.0.dist-info/RECORD +39 -0
  36. openworkproof-1.0.0.dist-info/WHEEL +5 -0
  37. openworkproof-1.0.0.dist-info/entry_points.txt +2 -0
  38. openworkproof-1.0.0.dist-info/licenses/LICENSE +202 -0
  39. 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
+ )