tgi-foundation 0.2.0.dev0__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.
- tgi/__init__.py +7 -0
- tgi/__main__.py +194 -0
- tgi/acquisition_history.py +45 -0
- tgi/acquisition_history_check.py +51 -0
- tgi/acquisition_monitor.py +66 -0
- tgi/acquisition_monitor_check.py +78 -0
- tgi/acquisition_projection.py +70 -0
- tgi/acquisition_projection_check.py +93 -0
- tgi/acquisition_role_cells.py +53 -0
- tgi/acquisition_role_constraints.py +13 -0
- tgi/acquisition_role_constraints_check.py +66 -0
- tgi/acquisition_snapshot.py +35 -0
- tgi/acquisition_stream.py +21 -0
- tgi/acquisition_witness.py +117 -0
- tgi/actuation_goal_frontier.py +117 -0
- tgi/actuation_goal_frontier_check.py +147 -0
- tgi/actuation_goal_workflow.py +159 -0
- tgi/actuation_sequence_feedback.py +41 -0
- tgi/actuation_sequence_feedback_check.py +43 -0
- tgi/ask_certificate.py +74 -0
- tgi/bands.py +59 -0
- tgi/capacity_graph.py +70 -0
- tgi/closed_actuation_goal_frontier.py +13 -0
- tgi/closed_actuation_goal_frontier_check.py +19 -0
- tgi/closed_actuation_goal_workflow.py +159 -0
- tgi/closure.py +202 -0
- tgi/compact_acquisition_map.py +68 -0
- tgi/compact_acquisition_map_check.py +91 -0
- tgi/compact_complete_role_core.py +36 -0
- tgi/compact_complete_role_core_check.py +62 -0
- tgi/compact_measured_path.py +84 -0
- tgi/compact_role_observation.py +13 -0
- tgi/compact_role_observation_check.py +66 -0
- tgi/compatible_joins.py +33 -0
- tgi/complete_role_core.py +53 -0
- tgi/complete_role_core_check.py +54 -0
- tgi/context_family_selection.py +45 -0
- tgi/context_family_selection_check.py +32 -0
- tgi/context_family_separation.py +43 -0
- tgi/context_family_separation_check.py +47 -0
- tgi/contextual_isometry.py +62 -0
- tgi/contextual_isometry_check.py +54 -0
- tgi/continuation_checkpoint.py +75 -0
- tgi/continuation_cycle.py +102 -0
- tgi/continuation_goal_frontier.py +13 -0
- tgi/continuation_goal_frontier_check.py +19 -0
- tgi/continuation_goal_workflow.py +159 -0
- tgi/continuation_learning.py +36 -0
- tgi/continuation_learning_check.py +53 -0
- tgi/correspondence.py +76 -0
- tgi/cross_action_correspondence.py +182 -0
- tgi/cross_action_correspondence_check.py +92 -0
- tgi/cross_view_identity_map.py +41 -0
- tgi/cross_view_identity_map_check.py +48 -0
- tgi/derivation.py +74 -0
- tgi/empirical_transport.py +74 -0
- tgi/empirical_transport_check.py +78 -0
- tgi/events.py +36 -0
- tgi/evidence_response.py +24 -0
- tgi/evidence_response_check.py +33 -0
- tgi/exact_field.py +101 -0
- tgi/experience.py +68 -0
- tgi/experience_cli.py +44 -0
- tgi/feedback_update.py +32 -0
- tgi/feedback_update_check.py +38 -0
- tgi/formation.py +74 -0
- tgi/frame_cli.py +26 -0
- tgi/frame_engine.py +214 -0
- tgi/functional_capacity.py +74 -0
- tgi/functional_capacity_check.py +110 -0
- tgi/functional_transition.py +40 -0
- tgi/functional_transition_check.py +58 -0
- tgi/geometry.py +143 -0
- tgi/grounding.py +285 -0
- tgi/guarded_word_closure.py +148 -0
- tgi/guarded_word_closure_check.py +171 -0
- tgi/guarded_word_goal_frontier.py +13 -0
- tgi/guarded_word_goal_frontier_check.py +19 -0
- tgi/guarded_word_goal_workflow.py +160 -0
- tgi/identity.py +32 -0
- tgi/incidence.py +155 -0
- tgi/incremental.py +134 -0
- tgi/intervention_composition.py +63 -0
- tgi/intervention_composition_check.py +84 -0
- tgi/intervention_continuity.py +43 -0
- tgi/intervention_continuity_check.py +56 -0
- tgi/intervention_correspondence.py +156 -0
- tgi/intervention_correspondence_check.py +80 -0
- tgi/intervention_edit_contrast.py +27 -0
- tgi/intervention_edit_contrast_check.py +41 -0
- tgi/intervention_experiment.py +62 -0
- tgi/intervention_experiment_check.py +78 -0
- tgi/intervention_resolution.py +45 -0
- tgi/intervention_resolution_check.py +70 -0
- tgi/intervention_roles.py +83 -0
- tgi/intervention_roles_check.py +91 -0
- tgi/intervention_scope.py +34 -0
- tgi/intervention_sequence_experiment.py +71 -0
- tgi/intervention_sequence_experiment_check.py +97 -0
- tgi/interventions.py +240 -0
- tgi/joint_correspondence.py +73 -0
- tgi/joint_frontier_acquisition.py +114 -0
- tgi/joint_frontier_acquisition_check.py +116 -0
- tgi/joint_goal_observation.py +49 -0
- tgi/joint_goal_observation_check.py +55 -0
- tgi/joint_goal_traversal.py +101 -0
- tgi/joint_goal_traversal_check.py +114 -0
- tgi/joint_observed_laws.py +40 -0
- tgi/joint_observed_laws_check.py +63 -0
- tgi/joint_temporal_candidates.py +40 -0
- tgi/joint_temporal_candidates_check.py +68 -0
- tgi/lineage_knowledge.py +29 -0
- tgi/lineage_knowledge_check.py +41 -0
- tgi/lineage_state.py +39 -0
- tgi/lineage_state_check.py +47 -0
- tgi/local_acquisition_ownership.py +65 -0
- tgi/local_acquisition_runtime.py +119 -0
- tgi/local_acquisition_selection.py +41 -0
- tgi/local_acquisition_transition.py +50 -0
- tgi/local_acquisition_transition_check.py +80 -0
- tgi/local_edit_transport_classes.py +220 -0
- tgi/local_edit_transport_classes_check.py +128 -0
- tgi/local_evidence_persistence.py +67 -0
- tgi/measured_actuation_transition.py +56 -0
- tgi/measured_actuation_transition_check.py +81 -0
- tgi/measured_capacity.py +61 -0
- tgi/measured_context.py +52 -0
- tgi/measured_context_check.py +65 -0
- tgi/measured_context_laws.py +75 -0
- tgi/measured_context_laws_check.py +91 -0
- tgi/measured_context_layout.py +49 -0
- tgi/measured_occurrence_path.py +70 -0
- tgi/momentum.py +43 -0
- tgi/observation_context_laws.py +32 -0
- tgi/observation_context_laws_check.py +40 -0
- tgi/observation_epochs.py +35 -0
- tgi/observation_epochs_check.py +51 -0
- tgi/observation_point.py +92 -0
- tgi/observation_projection.py +45 -0
- tgi/observation_projection_check.py +48 -0
- tgi/observed_actuation_cycle.py +114 -0
- tgi/observed_actuation_discovery.py +41 -0
- tgi/observed_actuation_discovery_check.py +54 -0
- tgi/observed_actuation_learning.py +71 -0
- tgi/observed_actuation_learning_check.py +73 -0
- tgi/observed_actuation_runtime.py +114 -0
- tgi/observed_context_actions.py +66 -0
- tgi/observed_context_actions_check.py +81 -0
- tgi/observed_joint_state.py +52 -0
- tgi/observed_joint_state_check.py +55 -0
- tgi/observed_refinement.py +43 -0
- tgi/observed_response.py +20 -0
- tgi/observed_response_check.py +27 -0
- tgi/observed_role_core.py +41 -0
- tgi/observed_role_core_check.py +54 -0
- tgi/occurrence_route.py +56 -0
- tgi/operator_windows.py +84 -0
- tgi/operator_windows_check.py +111 -0
- tgi/organization.py +484 -0
- tgi/organization_check.py +143 -0
- tgi/organization_cli.py +77 -0
- tgi/organization_inventory_check.py +82 -0
- tgi/organization_snapshot.py +50 -0
- tgi/path_isometry.py +82 -0
- tgi/path_temporal_feasibility.py +69 -0
- tgi/phase_evidence.py +100 -0
- tgi/port_distinction_exploration.py +37 -0
- tgi/port_distinction_exploration_check.py +40 -0
- tgi/proofcheck.py +117 -0
- tgi/provenance.py +19 -0
- tgi/recent_observation.py +145 -0
- tgi/relational.py +222 -0
- tgi/resonance.py +114 -0
- tgi/response_eligibility.py +46 -0
- tgi/response_eligibility_check.py +55 -0
- tgi/response_interval_order.py +59 -0
- tgi/response_interval_order_check.py +92 -0
- tgi/response_readout.py +53 -0
- tgi/response_readout_check.py +73 -0
- tgi/role_bundle.py +31 -0
- tgi/role_bundle_check.py +20 -0
- tgi/role_candidates.py +47 -0
- tgi/role_candidates_check.py +57 -0
- tgi/role_eligibility.py +34 -0
- tgi/role_eligibility_check.py +46 -0
- tgi/role_feedback.py +15 -0
- tgi/role_feedback_check.py +23 -0
- tgi/role_history.py +37 -0
- tgi/role_history_check.py +51 -0
- tgi/role_projection.py +16 -0
- tgi/role_projection_check.py +85 -0
- tgi/role_proposal.py +39 -0
- tgi/role_proposal_check.py +51 -0
- tgi/role_readout.py +31 -0
- tgi/role_readout_check.py +51 -0
- tgi/role_response.py +34 -0
- tgi/role_response_check.py +40 -0
- tgi/role_work.py +54 -0
- tgi/scoped_sequence_experiment.py +20 -0
- tgi/scoped_sequence_experiment_check.py +33 -0
- tgi/separation.py +74 -0
- tgi/separation_check.py +87 -0
- tgi/sequence_prefix_feedback.py +57 -0
- tgi/sequence_prefix_feedback_check.py +79 -0
- tgi/source_intervals.py +85 -0
- tgi/source_intervals_check.py +97 -0
- tgi/spatial.py +109 -0
- tgi/spatial_action_observation.py +88 -0
- tgi/spatial_action_relation.py +53 -0
- tgi/spatial_action_relation_check.py +45 -0
- tgi/spatial_action_relation_cycle.py +84 -0
- tgi/spatial_action_relation_migration.py +41 -0
- tgi/spatial_action_relation_migration_bundle.py +60 -0
- tgi/spatial_contextual_action_cycle.py +130 -0
- tgi/spatial_contextual_action_local.py +79 -0
- tgi/spatial_contextual_action_phase.py +81 -0
- tgi/spatial_contextual_action_phase_check.py +81 -0
- tgi/spatial_direct_action_cycle.py +98 -0
- tgi/spatial_direct_action_relation.py +60 -0
- tgi/spatial_direct_action_relation_check.py +67 -0
- tgi/spatial_local_action_cycle.py +62 -0
- tgi/spatial_local_action_relation.py +66 -0
- tgi/spatial_temporal_action_cycle.py +116 -0
- tgi/spatial_temporal_action_local.py +77 -0
- tgi/spatial_temporal_action_phase.py +89 -0
- tgi/spatial_temporal_action_phase_check.py +94 -0
- tgi/structural_append_closure.py +99 -0
- tgi/structural_append_closure_check.py +106 -0
- tgi/structural_continuation_closure.py +93 -0
- tgi/structural_continuation_closure_check.py +108 -0
- tgi/temporal_candidate_spectrum.py +57 -0
- tgi/temporal_candidate_spectrum_check.py +94 -0
- tgi/temporal_correspondence.py +41 -0
- tgi/temporal_correspondence_check.py +56 -0
- tgi/temporal_projection.py +41 -0
- tgi/temporal_projection_check.py +56 -0
- tgi/transport.py +294 -0
- tgi/transport_cli.py +27 -0
- tgi/unlabeled_port_classes.py +199 -0
- tgi/unlabeled_port_classes_check.py +113 -0
- tgi/unobserved_action_selection.py +47 -0
- tgi/unobserved_action_selection_check.py +40 -0
- tgi/verification.py +98 -0
- tgi/witness_function.py +62 -0
- tgi/witness_probe.py +50 -0
- tgi/witness_probe_feedback.py +106 -0
- tgi/witness_response.py +67 -0
- tgi_foundation-0.2.0.dev0.dist-info/METADATA +30 -0
- tgi_foundation-0.2.0.dev0.dist-info/RECORD +252 -0
- tgi_foundation-0.2.0.dev0.dist-info/WHEEL +5 -0
- tgi_foundation-0.2.0.dev0.dist-info/licenses/LICENSE +3 -0
- tgi_foundation-0.2.0.dev0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
"""Owned append with independent one-pass complete replay."""
|
|
2
|
+
import copy
|
|
3
|
+
import hashlib
|
|
4
|
+
import json
|
|
5
|
+
import os
|
|
6
|
+
import re
|
|
7
|
+
import tempfile
|
|
8
|
+
from pathlib import Path
|
|
9
|
+
|
|
10
|
+
from tgi.frame_engine import canonical, unique_object
|
|
11
|
+
from tgi.identity import REGISTRY_ID, encode
|
|
12
|
+
from tgi.organization import OMEGA_CRIT
|
|
13
|
+
from tgi.intervention_edit_contrast import contrast
|
|
14
|
+
|
|
15
|
+
REVISION = 'TGI-M1-CROSS-ACTION-PROFILE-RESEARCH-V3'
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
def _sha(data):
|
|
19
|
+
return hashlib.sha256(data).hexdigest()
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def _contrast(before, after):
|
|
23
|
+
return contrast(before, after)
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
def _event(source, action, target_before, target_after, views):
|
|
27
|
+
if type(source) is not str or not source or type(action) is not str or not action:
|
|
28
|
+
raise ValueError('Original source and action required')
|
|
29
|
+
if type(views) is not dict or len(views) < 2:
|
|
30
|
+
raise ValueError('At least two original view streams required')
|
|
31
|
+
target = _contrast(target_before, target_after)
|
|
32
|
+
measured = {}
|
|
33
|
+
for name, frames in sorted(views.items()):
|
|
34
|
+
if type(name) is not str or not name or type(frames) not in (tuple, list) or len(frames) != 2:
|
|
35
|
+
raise ValueError('Original view address and before/after frames required')
|
|
36
|
+
measured[name] = _contrast(*frames)
|
|
37
|
+
return {'source': source, 'action_nmu': list(encode(action)),
|
|
38
|
+
'target': target, 'views': measured}
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
def form(events):
|
|
42
|
+
"""Accumulate original events once while retaining every V3 phase field."""
|
|
43
|
+
if type(events) is not list:
|
|
44
|
+
raise ValueError('Original chronological event list required')
|
|
45
|
+
if not events:
|
|
46
|
+
return {'revision': REVISION, 'registry': REGISTRY_ID, 'events': [],
|
|
47
|
+
'phases': [], 'result': {'status': 'NO_PATH', 'view': None}}
|
|
48
|
+
names = list(events[0]['views'])
|
|
49
|
+
if len(names) < 2:
|
|
50
|
+
raise ValueError('At least two view streams required')
|
|
51
|
+
sources = set()
|
|
52
|
+
prior_crystal = None
|
|
53
|
+
phases = []
|
|
54
|
+
actions = set()
|
|
55
|
+
comparator = set()
|
|
56
|
+
support = {name: {} for name in names}
|
|
57
|
+
controls = {name: {} for name in names}
|
|
58
|
+
opposing = {name: [] for name in names}
|
|
59
|
+
for index, event in enumerate(events):
|
|
60
|
+
if (type(event) is not dict or set(event) != {'source', 'action_nmu',
|
|
61
|
+
'target', 'views'} or event['source'] in sources or
|
|
62
|
+
list(event['views']) != names):
|
|
63
|
+
raise ValueError('Unique raw event and fixed view inventory required')
|
|
64
|
+
sources.add(event['source'])
|
|
65
|
+
action = tuple(event['action_nmu'])
|
|
66
|
+
actions.add(action)
|
|
67
|
+
if not event['target']['changed'] and any(
|
|
68
|
+
view['changed'] for view in event['views'].values()):
|
|
69
|
+
comparator.add(action)
|
|
70
|
+
cells = []
|
|
71
|
+
eligible = []
|
|
72
|
+
for name in names:
|
|
73
|
+
owned_support = support[name]
|
|
74
|
+
owned_controls = controls[name]
|
|
75
|
+
owned_support.setdefault(action, set())
|
|
76
|
+
owned_controls.setdefault(action, 0)
|
|
77
|
+
if event['target']['changed'] and event['views'][name]['changed']:
|
|
78
|
+
owned_support[action].add(tuple(event['target']['before_nmu']))
|
|
79
|
+
elif not event['target']['changed'] and not event['views'][name]['changed']:
|
|
80
|
+
owned_controls[action] += 1
|
|
81
|
+
else:
|
|
82
|
+
opposing[name].append(event['source'])
|
|
83
|
+
positives = [candidate for candidate in sorted(actions)
|
|
84
|
+
if len(owned_support.get(candidate, ())) >= OMEGA_CRIT and
|
|
85
|
+
owned_controls.get(candidate, 0) > 0]
|
|
86
|
+
if not opposing[name] and any(other != candidate for candidate in positives
|
|
87
|
+
for other in comparator):
|
|
88
|
+
eligible.append(name)
|
|
89
|
+
cells.append({'view': name,
|
|
90
|
+
'omega_by_action': [{'action_nmu': list(candidate),
|
|
91
|
+
'omega': len(owned_support.get(candidate, ())),
|
|
92
|
+
'controls': owned_controls.get(candidate, 0)}
|
|
93
|
+
for candidate in sorted(actions)],
|
|
94
|
+
'contradicting_sources': list(opposing[name]),
|
|
95
|
+
'xi': 0})
|
|
96
|
+
result = ({'status': 'CRYSTAL', 'view': eligible[0]}
|
|
97
|
+
if len(eligible) == 1 else
|
|
98
|
+
{'status': 'REVOKED', 'view': None}
|
|
99
|
+
if prior_crystal is not None and prior_crystal not in eligible else
|
|
100
|
+
{'status': 'NO_PATH', 'view': None})
|
|
101
|
+
if result['status'] == 'CRYSTAL':
|
|
102
|
+
prior_crystal = result['view']
|
|
103
|
+
for cell in cells:
|
|
104
|
+
cell['xi'] = int(cell['view'] == result['view'])
|
|
105
|
+
phases.append({'event_index': index, 'source': event['source'],
|
|
106
|
+
'comparator_actions': [list(candidate) for candidate in sorted(comparator)],
|
|
107
|
+
'cells': cells, 'result': result})
|
|
108
|
+
return {'revision': REVISION, 'registry': REGISTRY_ID,
|
|
109
|
+
'events': list(events), 'phases': phases,
|
|
110
|
+
'result': copy.deepcopy(phases[-1]['result'])}
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
class OwnedInterventionCorrespondence:
|
|
114
|
+
def __init__(self, events=None):
|
|
115
|
+
from tgi.cross_action_correspondence_check import verify
|
|
116
|
+
self._events = copy.deepcopy([] if events is None else events)
|
|
117
|
+
self._certificate = form(self._events)
|
|
118
|
+
if not verify(self._events, self._certificate):
|
|
119
|
+
raise ValueError('Invalid original raw correspondence history')
|
|
120
|
+
|
|
121
|
+
@property
|
|
122
|
+
def certificate(self):
|
|
123
|
+
return copy.deepcopy(self._certificate)
|
|
124
|
+
|
|
125
|
+
def observe(self, source, action, target_before, target_after, views):
|
|
126
|
+
event = _event(source, action, target_before, target_after, views)
|
|
127
|
+
if any(row['source'] == source for row in self._events):
|
|
128
|
+
raise ValueError('Duplicate original source')
|
|
129
|
+
from tgi.cross_action_correspondence_check import verify
|
|
130
|
+
child = type(self).__new__(type(self))
|
|
131
|
+
child._events = self._events + [event]
|
|
132
|
+
child._certificate = form(child._events)
|
|
133
|
+
if not verify(child._events, child._certificate):
|
|
134
|
+
raise ValueError('Invalid original raw correspondence history')
|
|
135
|
+
return child
|
|
136
|
+
|
|
137
|
+
def resolve(self):
|
|
138
|
+
return copy.deepcopy(self._certificate['result'])
|
|
139
|
+
|
|
140
|
+
def commit(self, path):
|
|
141
|
+
from tgi.cross_action_correspondence_check import verify
|
|
142
|
+
if not verify(self._events, self._certificate):
|
|
143
|
+
raise ValueError('Independent raw correspondence replay failed')
|
|
144
|
+
payload = {'revision': REVISION, 'registry': REGISTRY_ID,
|
|
145
|
+
'events': self._events, 'certificate': self._certificate}
|
|
146
|
+
envelope = {'payload': payload, 'sha256': _sha(canonical(payload).encode('utf8'))}
|
|
147
|
+
data = canonical(envelope).encode('utf8')
|
|
148
|
+
destination = Path(path)
|
|
149
|
+
temporary = None
|
|
150
|
+
try:
|
|
151
|
+
with tempfile.NamedTemporaryFile(mode='wb', dir=destination.parent,
|
|
152
|
+
delete=False) as stream:
|
|
153
|
+
temporary = Path(stream.name)
|
|
154
|
+
stream.write(data)
|
|
155
|
+
stream.flush()
|
|
156
|
+
os.fsync(stream.fileno())
|
|
157
|
+
os.replace(temporary, destination)
|
|
158
|
+
temporary = None
|
|
159
|
+
finally:
|
|
160
|
+
if temporary is not None and temporary.exists():
|
|
161
|
+
temporary.unlink()
|
|
162
|
+
return {'path': str(destination), 'sha256': _sha(data), 'bytes': len(data)}
|
|
163
|
+
|
|
164
|
+
@classmethod
|
|
165
|
+
def recover(cls, path, expected_sha256):
|
|
166
|
+
from tgi.cross_action_correspondence_check import verify
|
|
167
|
+
if type(expected_sha256) is not str or re.fullmatch(r'[0-9a-f]{64}', expected_sha256) is None:
|
|
168
|
+
raise ValueError('External checkpoint digest required')
|
|
169
|
+
data = Path(path).read_bytes()
|
|
170
|
+
if _sha(data) != expected_sha256:
|
|
171
|
+
raise ValueError('Checkpoint digest mismatch')
|
|
172
|
+
envelope = json.loads(data.decode('utf8'), object_pairs_hook=unique_object)
|
|
173
|
+
if type(envelope) is not dict or set(envelope) != {'payload', 'sha256'}:
|
|
174
|
+
raise ValueError('Invalid checkpoint envelope')
|
|
175
|
+
payload = envelope['payload']
|
|
176
|
+
if (type(payload) is not dict or set(payload) != {'revision', 'registry',
|
|
177
|
+
'events', 'certificate'} or payload['revision'] != REVISION or
|
|
178
|
+
payload['registry'] != REGISTRY_ID or
|
|
179
|
+
_sha(canonical(payload).encode('utf8')) != envelope['sha256'] or
|
|
180
|
+
not verify(payload['events'], payload['certificate'])):
|
|
181
|
+
raise ValueError('Invalid raw correspondence checkpoint')
|
|
182
|
+
return cls(payload['events'])
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
"""Independent one-pass replay of every original cross-action event and phase."""
|
|
2
|
+
from tgi.frame_engine import canonical
|
|
3
|
+
from tgi.identity import REGISTRY_ID, decode
|
|
4
|
+
from tgi.organization import OMEGA_CRIT
|
|
5
|
+
from tgi.intervention_edit_contrast_check import verify as verify_contrast
|
|
6
|
+
|
|
7
|
+
REVISION = 'TGI-M1-CROSS-ACTION-PROFILE-RESEARCH-V3'
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def verify(events, certificate):
|
|
11
|
+
try:
|
|
12
|
+
if (type(events) is not list or type(certificate) is not dict or
|
|
13
|
+
set(certificate) != {'revision', 'registry', 'events', 'phases', 'result'} or
|
|
14
|
+
certificate['revision'] != REVISION or certificate['registry'] != REGISTRY_ID or
|
|
15
|
+
canonical(certificate['events']) != canonical(events) or
|
|
16
|
+
type(certificate['phases']) is not list or len(certificate['phases']) != len(events)):
|
|
17
|
+
return False
|
|
18
|
+
if not events:
|
|
19
|
+
return canonical(certificate['result']) == canonical({'status': 'NO_PATH', 'view': None})
|
|
20
|
+
names = None
|
|
21
|
+
sources = set()
|
|
22
|
+
actions = set()
|
|
23
|
+
comparator = set()
|
|
24
|
+
support = {}
|
|
25
|
+
controls = {}
|
|
26
|
+
contradictions = {}
|
|
27
|
+
prior_crystal = None
|
|
28
|
+
final_result = {'status': 'NO_PATH', 'view': None}
|
|
29
|
+
for index, event in enumerate(events):
|
|
30
|
+
if (type(event) is not dict or set(event) != {'source', 'action_nmu', 'target', 'views'} or
|
|
31
|
+
type(event['source']) is not str or not event['source'] or event['source'] in sources or
|
|
32
|
+
type(event['action_nmu']) is not list or not event['action_nmu'] or
|
|
33
|
+
type(event['views']) is not dict or not verify_contrast(event['target'])):
|
|
34
|
+
return False
|
|
35
|
+
sources.add(event['source'])
|
|
36
|
+
decode(event['action_nmu'])
|
|
37
|
+
current_names = list(event['views'])
|
|
38
|
+
if (len(current_names) < 2 or current_names != sorted(current_names) or
|
|
39
|
+
any(type(name) is not str or not name for name in current_names)):
|
|
40
|
+
return False
|
|
41
|
+
if names is None:
|
|
42
|
+
names = current_names
|
|
43
|
+
support = {name: {} for name in names}
|
|
44
|
+
controls = {name: {} for name in names}
|
|
45
|
+
contradictions = {name: [] for name in names}
|
|
46
|
+
elif current_names != names:
|
|
47
|
+
return False
|
|
48
|
+
action = tuple(event['action_nmu'])
|
|
49
|
+
actions.add(action)
|
|
50
|
+
target_changed = event['target']['kind'] != 'STABLE'
|
|
51
|
+
if not target_changed and any(view['kind'] != 'STABLE' for view in event['views'].values()):
|
|
52
|
+
comparator.add(action)
|
|
53
|
+
cells = []
|
|
54
|
+
eligible = []
|
|
55
|
+
for name in names:
|
|
56
|
+
view = event['views'][name]
|
|
57
|
+
if not verify_contrast(view):
|
|
58
|
+
return False
|
|
59
|
+
view_changed = view['kind'] != 'STABLE'
|
|
60
|
+
if target_changed and view_changed:
|
|
61
|
+
support[name].setdefault(action, set()).add(tuple(event['target']['before_nmu']))
|
|
62
|
+
elif not target_changed and not view_changed:
|
|
63
|
+
controls[name][action] = controls[name].get(action, 0) + 1
|
|
64
|
+
if event['target']['changed'] != view['changed']:
|
|
65
|
+
contradictions[name].append(event['source'])
|
|
66
|
+
counts = [{'action_nmu': list(candidate),
|
|
67
|
+
'omega': len(support[name].get(candidate, ())),
|
|
68
|
+
'controls': controls[name].get(candidate, 0)}
|
|
69
|
+
for candidate in sorted(actions)]
|
|
70
|
+
positives = [tuple(row['action_nmu']) for row in counts
|
|
71
|
+
if row['omega'] >= OMEGA_CRIT and row['controls']]
|
|
72
|
+
if not contradictions[name] and any(a != b for a in positives for b in comparator):
|
|
73
|
+
eligible.append(name)
|
|
74
|
+
cells.append({'view': name, 'omega_by_action': counts, 'xi': 0,
|
|
75
|
+
'contradicting_sources': list(contradictions[name])})
|
|
76
|
+
if len(eligible) == 1:
|
|
77
|
+
final_result = {'status': 'CRYSTAL', 'view': eligible[0]}
|
|
78
|
+
prior_crystal = eligible[0]
|
|
79
|
+
for cell in cells:
|
|
80
|
+
cell['xi'] = int(cell['view'] == prior_crystal)
|
|
81
|
+
elif prior_crystal is not None and prior_crystal not in eligible:
|
|
82
|
+
final_result = {'status': 'REVOKED', 'view': None}
|
|
83
|
+
else:
|
|
84
|
+
final_result = {'status': 'NO_PATH', 'view': None}
|
|
85
|
+
expected = {'event_index': index, 'source': event['source'],
|
|
86
|
+
'comparator_actions': [list(a) for a in sorted(comparator)],
|
|
87
|
+
'cells': cells, 'result': final_result}
|
|
88
|
+
if canonical(certificate['phases'][index]) != canonical(expected):
|
|
89
|
+
return False
|
|
90
|
+
return canonical(certificate['result']) == canonical(final_result)
|
|
91
|
+
except (ValueError, TypeError, KeyError, IndexError, AttributeError):
|
|
92
|
+
return False
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
from tgi.identity import encode,decode
|
|
2
|
+
from tgi.incidence import _endpoint
|
|
3
|
+
from tgi.organization import OMEGA_CRIT
|
|
4
|
+
|
|
5
|
+
def _produce(m,query,budget):
|
|
6
|
+
q=encode(query)
|
|
7
|
+
if not q or m._dirty:raise ValueError('Invalid original scope')
|
|
8
|
+
sources=[];distinct=set()
|
|
9
|
+
for s,(frames,_) in sorted(m.episodes.items()):
|
|
10
|
+
budget.consume()
|
|
11
|
+
if not m._alive(s):raise ValueError('Broken original evidence')
|
|
12
|
+
if len(frames)!=2:raise ValueError('Paired views required')
|
|
13
|
+
distinct.add(frames[0]);sources.append(dict(source=s,occurrences=[_endpoint(m,s,(fi,0,len(f))) for fi,f in enumerate(frames)]))
|
|
14
|
+
alternatives=[]
|
|
15
|
+
for direction in (-1,1):
|
|
16
|
+
mapping={};inverse={};witnesses={};valid=True
|
|
17
|
+
for s,(frames,_) in sorted(m.episodes.items()):
|
|
18
|
+
budget.consume()
|
|
19
|
+
a,b=frames
|
|
20
|
+
if len(a)!=len(b):valid=False;break
|
|
21
|
+
for i,x in enumerate(a):
|
|
22
|
+
budget.consume()
|
|
23
|
+
j=i if direction==1 else len(a)-1-i;y=b[j]
|
|
24
|
+
if (x in mapping and mapping[x]!=y) or (y in inverse and inverse[y]!=x):valid=False;break
|
|
25
|
+
mapping[x]=y;inverse[y]=x;witnesses.setdefault((x,y),[]).append(dict(source=s,input_index=i,output_index=j))
|
|
26
|
+
if not valid:break
|
|
27
|
+
if valid:
|
|
28
|
+
for _ in q:budget.consume()
|
|
29
|
+
missing=sorted(set(q)-set(mapping));order=q if direction==1 else q[::-1]
|
|
30
|
+
alternatives.append(dict(direction=direction,mapping=[dict(input=x,output=y,witnesses=witnesses[x,y]) for x,y in sorted(mapping.items())],missing=missing,output=None if missing else decode(tuple(mapping[x] for x in order))))
|
|
31
|
+
outputs=sorted({c['output'] for c in alternatives if c['output'] is not None})
|
|
32
|
+
status='CONFLICT' if not alternatives else 'INCOMPLETE' if len(distinct)<OMEGA_CRIT else 'UNKNOWN_ID' if any(c['missing'] for c in alternatives) else 'AMBIGUOUS_OUTPUT' if len(outputs)!=1 else 'CONDITIONAL_OUTPUT'
|
|
33
|
+
return dict(query=query,sources=sources,diversity=len(distinct),alternatives=alternatives,outputs=outputs,status=status,output=outputs[0] if status=='CONDITIONAL_OUTPUT' else None)
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
def certify_cross_view_identity_map(model,query,*,max_search_steps=None):
|
|
37
|
+
from .organization_snapshot import snapshot
|
|
38
|
+
from .role_work import RoleSearchBudget
|
|
39
|
+
budget=RoleSearchBudget(max_search_steps)
|
|
40
|
+
with budget.scope():
|
|
41
|
+
return dict(policy='cross_view_identity_correspondence_v1',threshold=OMEGA_CRIT,**_produce(snapshot(model),query,budget))
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
"""Independent full relation-set verifier for witnessed cross-view NMU maps."""
|
|
2
|
+
from .identity import encode,decode
|
|
3
|
+
from .organization import OMEGA_CRIT
|
|
4
|
+
from .organization_snapshot import snapshot
|
|
5
|
+
from .role_work import RoleSearchBudget
|
|
6
|
+
from .frame_engine import canonical
|
|
7
|
+
|
|
8
|
+
def _expected(m,query,budget):
|
|
9
|
+
q=encode(query)
|
|
10
|
+
if not q:raise ValueError('Nonempty query required')
|
|
11
|
+
sources=[];distinct=set()
|
|
12
|
+
for s,(frames,receipts) in sorted(m.episodes.items()):
|
|
13
|
+
budget.consume()
|
|
14
|
+
if len(frames)!=2 or not m._alive(s):raise ValueError('Invalid source')
|
|
15
|
+
distinct.add(frames[0]);points=[]
|
|
16
|
+
for fi,f in enumerate(frames):
|
|
17
|
+
origin=receipts[fi].origin;offset=sum(map(len,frames[:fi]))
|
|
18
|
+
points.append(dict(frame=fi,start=0,stop=len(f),event_span=[offset,offset+len(f)],identities=list(f),coordinates=[[origin[0]+i,*origin[1:]] for i in range(len(f))]))
|
|
19
|
+
sources.append(dict(source=s,occurrences=points))
|
|
20
|
+
alternatives=[]
|
|
21
|
+
for sign in (-1,1):
|
|
22
|
+
edges={};left={};right={};equal=True
|
|
23
|
+
for s,(frames,_) in sorted(m.episodes.items()):
|
|
24
|
+
budget.consume();a,b=frames
|
|
25
|
+
if len(a)!=len(b):equal=False;continue
|
|
26
|
+
for j,y in enumerate(b):
|
|
27
|
+
budget.consume();i=j if sign==1 else len(a)-1-j;x=a[i]
|
|
28
|
+
left.setdefault(x,set()).add(y);right.setdefault(y,set()).add(x)
|
|
29
|
+
edges.setdefault((x,y),[]).append(dict(source=s,input_index=i,output_index=j))
|
|
30
|
+
if not equal or any(len(v)!=1 for v in left.values()) or any(len(v)!=1 for v in right.values()):continue
|
|
31
|
+
mapping={x:next(iter(values)) for x,values in left.items()};missing=set();output=[]
|
|
32
|
+
for k in range(len(q)):
|
|
33
|
+
budget.consume();x=q[k if sign==1 else len(q)-1-k]
|
|
34
|
+
if x not in mapping:missing.add(x)
|
|
35
|
+
else:output.append(mapping[x])
|
|
36
|
+
alternatives.append(dict(direction=sign,mapping=[dict(input=x,output=y,witnesses=sorted(edges[x,y],key=lambda w:(w['source'],w['input_index']))) for x,y in sorted(mapping.items())],missing=sorted(missing),output=None if missing else decode(tuple(output))))
|
|
37
|
+
outputs=sorted({c['output'] for c in alternatives if c['output'] is not None})
|
|
38
|
+
status='CONFLICT' if not alternatives else 'INCOMPLETE' if len(distinct)<OMEGA_CRIT else 'UNKNOWN_ID' if any(c['missing'] for c in alternatives) else 'AMBIGUOUS_OUTPUT' if len(outputs)!=1 else 'CONDITIONAL_OUTPUT'
|
|
39
|
+
return dict(query=query,sources=sources,diversity=len(distinct),alternatives=alternatives,outputs=outputs,status=status,output=outputs[0] if status=='CONDITIONAL_OUTPUT' else None)
|
|
40
|
+
|
|
41
|
+
def verify_cross_view_identity_map(model,query,certificate,*,max_search_steps=None):
|
|
42
|
+
budget=RoleSearchBudget(max_search_steps)
|
|
43
|
+
with budget.scope():
|
|
44
|
+
try:
|
|
45
|
+
if not isinstance(certificate,dict) or type(certificate.get('threshold')) is not int:return False
|
|
46
|
+
expected=dict(policy='cross_view_identity_correspondence_v1',threshold=OMEGA_CRIT,**_expected(snapshot(model),query,budget))
|
|
47
|
+
return canonical(certificate)==canonical(expected)
|
|
48
|
+
except (ValueError,TypeError,KeyError,IndexError,AttributeError):return False
|
tgi/derivation.py
ADDED
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
"""Interface for independently implemented TGI descendants.
|
|
2
|
+
|
|
3
|
+
A contract declaration is not a mechanism audit or admission certificate.
|
|
4
|
+
"""
|
|
5
|
+
from abc import ABC, abstractmethod
|
|
6
|
+
from dataclasses import dataclass
|
|
7
|
+
from enum import Enum
|
|
8
|
+
from .events import Event
|
|
9
|
+
from .identity import decode
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
@dataclass(frozen=True)
|
|
13
|
+
class DerivationContract:
|
|
14
|
+
name: str
|
|
15
|
+
revision: str
|
|
16
|
+
purpose: str
|
|
17
|
+
inherited_principles: str
|
|
18
|
+
formation_law: str
|
|
19
|
+
geometry_and_bonding_law: str
|
|
20
|
+
resolution_law: str
|
|
21
|
+
falsifiers: tuple[str, ...]
|
|
22
|
+
|
|
23
|
+
def __post_init__(self):
|
|
24
|
+
for field in (self.name, self.revision, self.purpose, self.inherited_principles,
|
|
25
|
+
self.formation_law, self.geometry_and_bonding_law, self.resolution_law):
|
|
26
|
+
if not isinstance(field, str) or not field.strip():
|
|
27
|
+
raise ValueError("A derivation must state its complete working contract")
|
|
28
|
+
if not isinstance(self.falsifiers, tuple) or not self.falsifiers or any(
|
|
29
|
+
not isinstance(f, str) or not f.strip() for f in self.falsifiers):
|
|
30
|
+
raise ValueError("Explicit falsifiers are required")
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
class ResolutionStatus(str, Enum):
|
|
34
|
+
RESOLVED = "resolved"
|
|
35
|
+
NO_PATH = "no_path"
|
|
36
|
+
AMBIGUOUS = "ambiguous"
|
|
37
|
+
CONFLICT = "conflict"
|
|
38
|
+
INCOMPLETE = "incomplete"
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
@dataclass(frozen=True)
|
|
42
|
+
class Resolution:
|
|
43
|
+
status: ResolutionStatus
|
|
44
|
+
output: tuple[int, ...] = ()
|
|
45
|
+
evidence: tuple[str, ...] = ()
|
|
46
|
+
|
|
47
|
+
def __post_init__(self):
|
|
48
|
+
if not isinstance(self.status, ResolutionStatus):
|
|
49
|
+
raise TypeError("Unknown resolution status")
|
|
50
|
+
if not isinstance(self.output, tuple) or not isinstance(self.evidence, tuple):
|
|
51
|
+
raise TypeError("Output and evidence must be immutable tuples")
|
|
52
|
+
decode(self.output)
|
|
53
|
+
if any(not isinstance(e, str) or not e.strip() for e in self.evidence):
|
|
54
|
+
raise ValueError("Evidence references must be nonempty strings")
|
|
55
|
+
if self.status is ResolutionStatus.RESOLVED:
|
|
56
|
+
if not self.evidence:
|
|
57
|
+
raise ValueError("Resolved output requires trace references")
|
|
58
|
+
elif self.output:
|
|
59
|
+
raise ValueError("An unresolved result cannot contain a final answer")
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
class Derivation(ABC):
|
|
63
|
+
@property
|
|
64
|
+
@abstractmethod
|
|
65
|
+
def contract(self) -> DerivationContract:
|
|
66
|
+
"""Return the independently specified mechanism contract."""
|
|
67
|
+
|
|
68
|
+
@abstractmethod
|
|
69
|
+
def observe(self, events: tuple[Event, ...]) -> None:
|
|
70
|
+
"""Form organization through the descendant's derived native mechanism."""
|
|
71
|
+
|
|
72
|
+
@abstractmethod
|
|
73
|
+
def resolve(self, query: tuple[Event, ...]) -> Resolution:
|
|
74
|
+
"""Resolve using the descendant's own geometric and crystallization laws."""
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
"""Set-valued raw-context transport from complete phase-valid organization."""
|
|
2
|
+
from .identity import encode, decode
|
|
3
|
+
from .organization import _match
|
|
4
|
+
from .organization_snapshot import snapshot
|
|
5
|
+
from .organization_inventory_check import verify_organization_inventory
|
|
6
|
+
from .role_work import RoleSearchBudget
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
def _query(domain, actions):
|
|
10
|
+
if not isinstance(domain, (list, tuple)) or not domain:
|
|
11
|
+
raise ValueError('Nonempty ordered context domain required')
|
|
12
|
+
contexts = []
|
|
13
|
+
for context in domain:
|
|
14
|
+
if not isinstance(context, (list, tuple)) or not context:
|
|
15
|
+
raise ValueError('Nonempty raw context frames required')
|
|
16
|
+
frames = tuple(encode(f) for f in context)
|
|
17
|
+
if any(not f for f in frames) or frames in contexts:
|
|
18
|
+
raise ValueError('Empty frame or duplicate context')
|
|
19
|
+
contexts.append(frames)
|
|
20
|
+
if not isinstance(actions, (list, tuple)) or not actions:
|
|
21
|
+
raise ValueError('Nonempty raw action inventory required')
|
|
22
|
+
raw_actions = tuple(encode(a) for a in actions)
|
|
23
|
+
if any(not a for a in raw_actions) or len(set(raw_actions)) != len(raw_actions):
|
|
24
|
+
raise ValueError('Empty or duplicate action')
|
|
25
|
+
return tuple(contexts), raw_actions
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
def certify_empirical_transport(model, domain, actions, *, max_search_steps=None):
|
|
29
|
+
budget = RoleSearchBudget(max_search_steps)
|
|
30
|
+
with budget.scope():
|
|
31
|
+
contexts, raw_actions = _query(domain, actions)
|
|
32
|
+
view = snapshot(model)
|
|
33
|
+
if not verify_organization_inventory(view):
|
|
34
|
+
raise ValueError('Incomplete or broken operator-experience inventory')
|
|
35
|
+
rows = []
|
|
36
|
+
for action in raw_actions:
|
|
37
|
+
for index, context in enumerate(contexts):
|
|
38
|
+
prefix = context + (action,)
|
|
39
|
+
outcomes = {}; unbound = set(); revoked = []
|
|
40
|
+
for anchor, h in sorted(view.organizations.items()):
|
|
41
|
+
budget.consume()
|
|
42
|
+
if len(prefix) >= len(h.pattern):
|
|
43
|
+
continue
|
|
44
|
+
for bindings, _ in _match(h.pattern, prefix):
|
|
45
|
+
if not view._phase_valid(h):
|
|
46
|
+
raise ValueError('Broken operator phase')
|
|
47
|
+
if set(bindings) != set(range(len(h.diversity))):
|
|
48
|
+
unbound.add(anchor); continue
|
|
49
|
+
output = tuple(tuple(i for k, v in parts for i in
|
|
50
|
+
(v if k == 'lit' else bindings[v]))
|
|
51
|
+
for parts in h.pattern[len(prefix):])
|
|
52
|
+
outcomes.setdefault(output, set()).add(anchor)
|
|
53
|
+
for anchor, (h, _) in sorted(view.rejected_organizations.items()):
|
|
54
|
+
budget.consume()
|
|
55
|
+
if len(prefix) < len(h.pattern) and _match(h.pattern, prefix):
|
|
56
|
+
revoked.append(anchor)
|
|
57
|
+
is_open = not outcomes or bool(unbound or revoked)
|
|
58
|
+
outputs = [{'frames': list(map(decode, out)),
|
|
59
|
+
'witnesses': [{'anchor': a, 'sources': list(view.organizations[a].supports)}
|
|
60
|
+
for a in sorted(anchors)]}
|
|
61
|
+
for out, anchors in sorted(outcomes.items())]
|
|
62
|
+
edges = [j for j, destination in enumerate(contexts) if destination in outcomes]
|
|
63
|
+
outside = [list(map(decode, out)) for out in sorted(outcomes) if out not in contexts]
|
|
64
|
+
rows.append({'action': decode(action), 'from_context': index, 'outputs': outputs,
|
|
65
|
+
'supported_edges': edges, 'outside_domain': outside,
|
|
66
|
+
'unbound': sorted(unbound), 'revoked': revoked, 'open': is_open,
|
|
67
|
+
'possible_edges': list(range(len(contexts))) if is_open else edges,
|
|
68
|
+
'unknown_outside_domain': is_open})
|
|
69
|
+
return {'policy': 'empirical_context_transport_v1',
|
|
70
|
+
'domain': [list(map(decode, c)) for c in contexts],
|
|
71
|
+
'actions': list(map(decode, raw_actions)),
|
|
72
|
+
'sources': [{'source': s, 'frames': list(map(decode, frames))}
|
|
73
|
+
for s, (frames, _) in sorted(view.episodes.items())],
|
|
74
|
+
'rows': rows}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
"""Independent full-inventory checker; no transport producer or resolver calls."""
|
|
2
|
+
from .identity import encode, decode
|
|
3
|
+
from .organization import _match
|
|
4
|
+
from .organization_snapshot import snapshot
|
|
5
|
+
from .organization_inventory_check import verify_organization_inventory
|
|
6
|
+
from .frame_engine import canonical
|
|
7
|
+
from .role_work import RoleSearchBudget
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def verify_empirical_transport(model, certificate, *, max_search_steps=None):
|
|
11
|
+
budget = RoleSearchBudget(max_search_steps)
|
|
12
|
+
with budget.scope():
|
|
13
|
+
try:
|
|
14
|
+
if set(certificate) != {'policy', 'domain', 'actions', 'sources', 'rows'}:
|
|
15
|
+
return False
|
|
16
|
+
if certificate['policy'] != 'empirical_context_transport_v1': return False
|
|
17
|
+
domain = certificate['domain']; actions = certificate['actions']
|
|
18
|
+
if not isinstance(domain, list) or not domain or not isinstance(actions, list) or not actions:
|
|
19
|
+
return False
|
|
20
|
+
raw_domain = []
|
|
21
|
+
for context in domain:
|
|
22
|
+
if not isinstance(context, list) or not context: return False
|
|
23
|
+
item = tuple(encode(f) for f in context)
|
|
24
|
+
if any(not f for f in item) or item in raw_domain: return False
|
|
25
|
+
raw_domain.append(item)
|
|
26
|
+
raw_actions = [encode(a) for a in actions]
|
|
27
|
+
if any(not a for a in raw_actions) or len(set(raw_actions)) != len(raw_actions): return False
|
|
28
|
+
view = snapshot(model)
|
|
29
|
+
if not verify_organization_inventory(view): return False
|
|
30
|
+
sources = [{'source': s, 'frames': [decode(f) for f in frames]}
|
|
31
|
+
for s, (frames, _) in sorted(view.episodes.items())]
|
|
32
|
+
if canonical(sources) != canonical(certificate['sources']): return False
|
|
33
|
+
expected = []
|
|
34
|
+
for action in raw_actions:
|
|
35
|
+
for origin in range(len(raw_domain)):
|
|
36
|
+
trigger = raw_domain[origin] + (action,)
|
|
37
|
+
supported = {}; partial = []; rejected = []
|
|
38
|
+
for anchor in sorted(view.organizations):
|
|
39
|
+
budget.consume(); org = view.organizations[anchor]
|
|
40
|
+
if len(org.pattern) <= len(trigger): continue
|
|
41
|
+
bindings = _match(org.pattern, trigger)
|
|
42
|
+
if bindings and not view._phase_valid(org): return False
|
|
43
|
+
incomplete = False
|
|
44
|
+
for assignment, _ in bindings:
|
|
45
|
+
if sorted(assignment) != list(range(len(org.diversity))):
|
|
46
|
+
incomplete = True; continue
|
|
47
|
+
result = []
|
|
48
|
+
for frame in org.pattern[len(trigger):]:
|
|
49
|
+
chars = []
|
|
50
|
+
for kind, value in frame:
|
|
51
|
+
if kind == 'lit': chars.extend(value)
|
|
52
|
+
else: chars.extend(assignment[value])
|
|
53
|
+
result.append(tuple(chars))
|
|
54
|
+
supported.setdefault(tuple(result), set()).add(anchor)
|
|
55
|
+
if incomplete: partial.append(anchor)
|
|
56
|
+
for anchor in sorted(view.rejected_organizations):
|
|
57
|
+
budget.consume(); org = view.rejected_organizations[anchor][0]
|
|
58
|
+
if len(org.pattern) > len(trigger) and _match(org.pattern, trigger): rejected.append(anchor)
|
|
59
|
+
outputs = []
|
|
60
|
+
for frames in sorted(supported):
|
|
61
|
+
witnesses = []
|
|
62
|
+
for anchor in sorted(supported[frames]):
|
|
63
|
+
witnesses.append({'anchor': anchor, 'sources': list(view.organizations[anchor].supports)})
|
|
64
|
+
outputs.append({'frames': [decode(f) for f in frames], 'witnesses': witnesses})
|
|
65
|
+
edges = []; outside = []
|
|
66
|
+
for frames in sorted(supported):
|
|
67
|
+
if frames in raw_domain: edges.append(raw_domain.index(frames))
|
|
68
|
+
else: outside.append([decode(f) for f in frames])
|
|
69
|
+
edges.sort()
|
|
70
|
+
open_row = len(outputs) == 0 or len(partial) > 0 or len(rejected) > 0
|
|
71
|
+
expected.append({'action': decode(action), 'from_context': origin, 'outputs': outputs,
|
|
72
|
+
'supported_edges': edges, 'outside_domain': outside,
|
|
73
|
+
'unbound': partial, 'revoked': rejected, 'open': open_row,
|
|
74
|
+
'possible_edges': list(range(len(raw_domain))) if open_row else edges,
|
|
75
|
+
'unknown_outside_domain': open_row})
|
|
76
|
+
return canonical(expected) == canonical(certificate['rows'])
|
|
77
|
+
except (ValueError, TypeError, KeyError, IndexError, AttributeError):
|
|
78
|
+
return False
|
tgi/events.py
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
"""Occurrences retain a static identity and an independent causal position."""
|
|
2
|
+
from dataclasses import dataclass
|
|
3
|
+
from .identity import encode, validate_identity
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
@dataclass(frozen=True, slots=True)
|
|
7
|
+
class Event:
|
|
8
|
+
stream_id: str
|
|
9
|
+
position: int
|
|
10
|
+
identity: int
|
|
11
|
+
|
|
12
|
+
def __post_init__(self):
|
|
13
|
+
if not isinstance(self.stream_id, str) or not self.stream_id:
|
|
14
|
+
raise ValueError("A stream requires a nonempty provenance identifier")
|
|
15
|
+
if type(self.position) is not int or self.position < 0:
|
|
16
|
+
raise ValueError("Position must be a nonnegative integer")
|
|
17
|
+
validate_identity(self.identity)
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
class EventStream:
|
|
21
|
+
def __init__(self, stream_id: str):
|
|
22
|
+
if not isinstance(stream_id, str) or not stream_id:
|
|
23
|
+
raise ValueError("A stream requires a nonempty provenance identifier")
|
|
24
|
+
self._stream_id = stream_id
|
|
25
|
+
self._position = 0
|
|
26
|
+
|
|
27
|
+
@property
|
|
28
|
+
def position(self) -> int:
|
|
29
|
+
return self._position
|
|
30
|
+
|
|
31
|
+
def feed(self, text: str) -> tuple[Event, ...]:
|
|
32
|
+
identities = encode(text) # Validate the complete chunk before advancing state.
|
|
33
|
+
events = tuple(Event(self._stream_id, self._position + i, identity)
|
|
34
|
+
for i, identity in enumerate(identities))
|
|
35
|
+
self._position += len(events)
|
|
36
|
+
return events
|
tgi/evidence_response.py
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
"""Combine certified observations and inference at the already selected state."""
|
|
2
|
+
from .role_response_check import verify_role_response
|
|
3
|
+
from .observed_response import certify_observed_response
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
def certify_evidence_response(model,role,history,inference):
|
|
7
|
+
if not verify_role_response(model,role,history,inference):raise ValueError('Invalid temporal inference')
|
|
8
|
+
temporal=inference['temporal'];rows=[];values=[]
|
|
9
|
+
for response in inference['responses']:
|
|
10
|
+
index=response['window'];window=temporal['windows'][index]
|
|
11
|
+
prefix=temporal['readouts'][window['readout']]['prefix']+[temporal['query']]
|
|
12
|
+
observed=certify_observed_response(model,prefix);actual=observed['result'];predicted=response['resolution']
|
|
13
|
+
value=[];basis='unresolved'
|
|
14
|
+
if actual['status']=='OBSERVED_CONFLICT':basis='observed_conflict'
|
|
15
|
+
elif actual['status']=='OBSERVED_AGREEMENT':
|
|
16
|
+
if predicted['status']=='RESOLVED' and predicted['output']!=actual['output']:basis='evidence_conflict'
|
|
17
|
+
else:value=actual['output'];basis='observed'
|
|
18
|
+
elif predicted['status']=='RESOLVED':value=predicted['output'];basis='inferred'
|
|
19
|
+
rows.append({'window':index,'observed':observed,'basis':basis,'output':value})
|
|
20
|
+
values.append(value)
|
|
21
|
+
available=bool(values) and all(values) and all(value==values[0] for value in values) and not inference['result']['blockers']
|
|
22
|
+
return {'inference':inference,'contexts':rows,'result':{
|
|
23
|
+
'status':'CONDITIONAL_RESPONSE' if available else 'UNRESOLVED','output':values[0] if available else [],
|
|
24
|
+
'conditions':list(inference['result']['conditions'])}}
|