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.
Files changed (252) hide show
  1. tgi/__init__.py +7 -0
  2. tgi/__main__.py +194 -0
  3. tgi/acquisition_history.py +45 -0
  4. tgi/acquisition_history_check.py +51 -0
  5. tgi/acquisition_monitor.py +66 -0
  6. tgi/acquisition_monitor_check.py +78 -0
  7. tgi/acquisition_projection.py +70 -0
  8. tgi/acquisition_projection_check.py +93 -0
  9. tgi/acquisition_role_cells.py +53 -0
  10. tgi/acquisition_role_constraints.py +13 -0
  11. tgi/acquisition_role_constraints_check.py +66 -0
  12. tgi/acquisition_snapshot.py +35 -0
  13. tgi/acquisition_stream.py +21 -0
  14. tgi/acquisition_witness.py +117 -0
  15. tgi/actuation_goal_frontier.py +117 -0
  16. tgi/actuation_goal_frontier_check.py +147 -0
  17. tgi/actuation_goal_workflow.py +159 -0
  18. tgi/actuation_sequence_feedback.py +41 -0
  19. tgi/actuation_sequence_feedback_check.py +43 -0
  20. tgi/ask_certificate.py +74 -0
  21. tgi/bands.py +59 -0
  22. tgi/capacity_graph.py +70 -0
  23. tgi/closed_actuation_goal_frontier.py +13 -0
  24. tgi/closed_actuation_goal_frontier_check.py +19 -0
  25. tgi/closed_actuation_goal_workflow.py +159 -0
  26. tgi/closure.py +202 -0
  27. tgi/compact_acquisition_map.py +68 -0
  28. tgi/compact_acquisition_map_check.py +91 -0
  29. tgi/compact_complete_role_core.py +36 -0
  30. tgi/compact_complete_role_core_check.py +62 -0
  31. tgi/compact_measured_path.py +84 -0
  32. tgi/compact_role_observation.py +13 -0
  33. tgi/compact_role_observation_check.py +66 -0
  34. tgi/compatible_joins.py +33 -0
  35. tgi/complete_role_core.py +53 -0
  36. tgi/complete_role_core_check.py +54 -0
  37. tgi/context_family_selection.py +45 -0
  38. tgi/context_family_selection_check.py +32 -0
  39. tgi/context_family_separation.py +43 -0
  40. tgi/context_family_separation_check.py +47 -0
  41. tgi/contextual_isometry.py +62 -0
  42. tgi/contextual_isometry_check.py +54 -0
  43. tgi/continuation_checkpoint.py +75 -0
  44. tgi/continuation_cycle.py +102 -0
  45. tgi/continuation_goal_frontier.py +13 -0
  46. tgi/continuation_goal_frontier_check.py +19 -0
  47. tgi/continuation_goal_workflow.py +159 -0
  48. tgi/continuation_learning.py +36 -0
  49. tgi/continuation_learning_check.py +53 -0
  50. tgi/correspondence.py +76 -0
  51. tgi/cross_action_correspondence.py +182 -0
  52. tgi/cross_action_correspondence_check.py +92 -0
  53. tgi/cross_view_identity_map.py +41 -0
  54. tgi/cross_view_identity_map_check.py +48 -0
  55. tgi/derivation.py +74 -0
  56. tgi/empirical_transport.py +74 -0
  57. tgi/empirical_transport_check.py +78 -0
  58. tgi/events.py +36 -0
  59. tgi/evidence_response.py +24 -0
  60. tgi/evidence_response_check.py +33 -0
  61. tgi/exact_field.py +101 -0
  62. tgi/experience.py +68 -0
  63. tgi/experience_cli.py +44 -0
  64. tgi/feedback_update.py +32 -0
  65. tgi/feedback_update_check.py +38 -0
  66. tgi/formation.py +74 -0
  67. tgi/frame_cli.py +26 -0
  68. tgi/frame_engine.py +214 -0
  69. tgi/functional_capacity.py +74 -0
  70. tgi/functional_capacity_check.py +110 -0
  71. tgi/functional_transition.py +40 -0
  72. tgi/functional_transition_check.py +58 -0
  73. tgi/geometry.py +143 -0
  74. tgi/grounding.py +285 -0
  75. tgi/guarded_word_closure.py +148 -0
  76. tgi/guarded_word_closure_check.py +171 -0
  77. tgi/guarded_word_goal_frontier.py +13 -0
  78. tgi/guarded_word_goal_frontier_check.py +19 -0
  79. tgi/guarded_word_goal_workflow.py +160 -0
  80. tgi/identity.py +32 -0
  81. tgi/incidence.py +155 -0
  82. tgi/incremental.py +134 -0
  83. tgi/intervention_composition.py +63 -0
  84. tgi/intervention_composition_check.py +84 -0
  85. tgi/intervention_continuity.py +43 -0
  86. tgi/intervention_continuity_check.py +56 -0
  87. tgi/intervention_correspondence.py +156 -0
  88. tgi/intervention_correspondence_check.py +80 -0
  89. tgi/intervention_edit_contrast.py +27 -0
  90. tgi/intervention_edit_contrast_check.py +41 -0
  91. tgi/intervention_experiment.py +62 -0
  92. tgi/intervention_experiment_check.py +78 -0
  93. tgi/intervention_resolution.py +45 -0
  94. tgi/intervention_resolution_check.py +70 -0
  95. tgi/intervention_roles.py +83 -0
  96. tgi/intervention_roles_check.py +91 -0
  97. tgi/intervention_scope.py +34 -0
  98. tgi/intervention_sequence_experiment.py +71 -0
  99. tgi/intervention_sequence_experiment_check.py +97 -0
  100. tgi/interventions.py +240 -0
  101. tgi/joint_correspondence.py +73 -0
  102. tgi/joint_frontier_acquisition.py +114 -0
  103. tgi/joint_frontier_acquisition_check.py +116 -0
  104. tgi/joint_goal_observation.py +49 -0
  105. tgi/joint_goal_observation_check.py +55 -0
  106. tgi/joint_goal_traversal.py +101 -0
  107. tgi/joint_goal_traversal_check.py +114 -0
  108. tgi/joint_observed_laws.py +40 -0
  109. tgi/joint_observed_laws_check.py +63 -0
  110. tgi/joint_temporal_candidates.py +40 -0
  111. tgi/joint_temporal_candidates_check.py +68 -0
  112. tgi/lineage_knowledge.py +29 -0
  113. tgi/lineage_knowledge_check.py +41 -0
  114. tgi/lineage_state.py +39 -0
  115. tgi/lineage_state_check.py +47 -0
  116. tgi/local_acquisition_ownership.py +65 -0
  117. tgi/local_acquisition_runtime.py +119 -0
  118. tgi/local_acquisition_selection.py +41 -0
  119. tgi/local_acquisition_transition.py +50 -0
  120. tgi/local_acquisition_transition_check.py +80 -0
  121. tgi/local_edit_transport_classes.py +220 -0
  122. tgi/local_edit_transport_classes_check.py +128 -0
  123. tgi/local_evidence_persistence.py +67 -0
  124. tgi/measured_actuation_transition.py +56 -0
  125. tgi/measured_actuation_transition_check.py +81 -0
  126. tgi/measured_capacity.py +61 -0
  127. tgi/measured_context.py +52 -0
  128. tgi/measured_context_check.py +65 -0
  129. tgi/measured_context_laws.py +75 -0
  130. tgi/measured_context_laws_check.py +91 -0
  131. tgi/measured_context_layout.py +49 -0
  132. tgi/measured_occurrence_path.py +70 -0
  133. tgi/momentum.py +43 -0
  134. tgi/observation_context_laws.py +32 -0
  135. tgi/observation_context_laws_check.py +40 -0
  136. tgi/observation_epochs.py +35 -0
  137. tgi/observation_epochs_check.py +51 -0
  138. tgi/observation_point.py +92 -0
  139. tgi/observation_projection.py +45 -0
  140. tgi/observation_projection_check.py +48 -0
  141. tgi/observed_actuation_cycle.py +114 -0
  142. tgi/observed_actuation_discovery.py +41 -0
  143. tgi/observed_actuation_discovery_check.py +54 -0
  144. tgi/observed_actuation_learning.py +71 -0
  145. tgi/observed_actuation_learning_check.py +73 -0
  146. tgi/observed_actuation_runtime.py +114 -0
  147. tgi/observed_context_actions.py +66 -0
  148. tgi/observed_context_actions_check.py +81 -0
  149. tgi/observed_joint_state.py +52 -0
  150. tgi/observed_joint_state_check.py +55 -0
  151. tgi/observed_refinement.py +43 -0
  152. tgi/observed_response.py +20 -0
  153. tgi/observed_response_check.py +27 -0
  154. tgi/observed_role_core.py +41 -0
  155. tgi/observed_role_core_check.py +54 -0
  156. tgi/occurrence_route.py +56 -0
  157. tgi/operator_windows.py +84 -0
  158. tgi/operator_windows_check.py +111 -0
  159. tgi/organization.py +484 -0
  160. tgi/organization_check.py +143 -0
  161. tgi/organization_cli.py +77 -0
  162. tgi/organization_inventory_check.py +82 -0
  163. tgi/organization_snapshot.py +50 -0
  164. tgi/path_isometry.py +82 -0
  165. tgi/path_temporal_feasibility.py +69 -0
  166. tgi/phase_evidence.py +100 -0
  167. tgi/port_distinction_exploration.py +37 -0
  168. tgi/port_distinction_exploration_check.py +40 -0
  169. tgi/proofcheck.py +117 -0
  170. tgi/provenance.py +19 -0
  171. tgi/recent_observation.py +145 -0
  172. tgi/relational.py +222 -0
  173. tgi/resonance.py +114 -0
  174. tgi/response_eligibility.py +46 -0
  175. tgi/response_eligibility_check.py +55 -0
  176. tgi/response_interval_order.py +59 -0
  177. tgi/response_interval_order_check.py +92 -0
  178. tgi/response_readout.py +53 -0
  179. tgi/response_readout_check.py +73 -0
  180. tgi/role_bundle.py +31 -0
  181. tgi/role_bundle_check.py +20 -0
  182. tgi/role_candidates.py +47 -0
  183. tgi/role_candidates_check.py +57 -0
  184. tgi/role_eligibility.py +34 -0
  185. tgi/role_eligibility_check.py +46 -0
  186. tgi/role_feedback.py +15 -0
  187. tgi/role_feedback_check.py +23 -0
  188. tgi/role_history.py +37 -0
  189. tgi/role_history_check.py +51 -0
  190. tgi/role_projection.py +16 -0
  191. tgi/role_projection_check.py +85 -0
  192. tgi/role_proposal.py +39 -0
  193. tgi/role_proposal_check.py +51 -0
  194. tgi/role_readout.py +31 -0
  195. tgi/role_readout_check.py +51 -0
  196. tgi/role_response.py +34 -0
  197. tgi/role_response_check.py +40 -0
  198. tgi/role_work.py +54 -0
  199. tgi/scoped_sequence_experiment.py +20 -0
  200. tgi/scoped_sequence_experiment_check.py +33 -0
  201. tgi/separation.py +74 -0
  202. tgi/separation_check.py +87 -0
  203. tgi/sequence_prefix_feedback.py +57 -0
  204. tgi/sequence_prefix_feedback_check.py +79 -0
  205. tgi/source_intervals.py +85 -0
  206. tgi/source_intervals_check.py +97 -0
  207. tgi/spatial.py +109 -0
  208. tgi/spatial_action_observation.py +88 -0
  209. tgi/spatial_action_relation.py +53 -0
  210. tgi/spatial_action_relation_check.py +45 -0
  211. tgi/spatial_action_relation_cycle.py +84 -0
  212. tgi/spatial_action_relation_migration.py +41 -0
  213. tgi/spatial_action_relation_migration_bundle.py +60 -0
  214. tgi/spatial_contextual_action_cycle.py +130 -0
  215. tgi/spatial_contextual_action_local.py +79 -0
  216. tgi/spatial_contextual_action_phase.py +81 -0
  217. tgi/spatial_contextual_action_phase_check.py +81 -0
  218. tgi/spatial_direct_action_cycle.py +98 -0
  219. tgi/spatial_direct_action_relation.py +60 -0
  220. tgi/spatial_direct_action_relation_check.py +67 -0
  221. tgi/spatial_local_action_cycle.py +62 -0
  222. tgi/spatial_local_action_relation.py +66 -0
  223. tgi/spatial_temporal_action_cycle.py +116 -0
  224. tgi/spatial_temporal_action_local.py +77 -0
  225. tgi/spatial_temporal_action_phase.py +89 -0
  226. tgi/spatial_temporal_action_phase_check.py +94 -0
  227. tgi/structural_append_closure.py +99 -0
  228. tgi/structural_append_closure_check.py +106 -0
  229. tgi/structural_continuation_closure.py +93 -0
  230. tgi/structural_continuation_closure_check.py +108 -0
  231. tgi/temporal_candidate_spectrum.py +57 -0
  232. tgi/temporal_candidate_spectrum_check.py +94 -0
  233. tgi/temporal_correspondence.py +41 -0
  234. tgi/temporal_correspondence_check.py +56 -0
  235. tgi/temporal_projection.py +41 -0
  236. tgi/temporal_projection_check.py +56 -0
  237. tgi/transport.py +294 -0
  238. tgi/transport_cli.py +27 -0
  239. tgi/unlabeled_port_classes.py +199 -0
  240. tgi/unlabeled_port_classes_check.py +113 -0
  241. tgi/unobserved_action_selection.py +47 -0
  242. tgi/unobserved_action_selection_check.py +40 -0
  243. tgi/verification.py +98 -0
  244. tgi/witness_function.py +62 -0
  245. tgi/witness_probe.py +50 -0
  246. tgi/witness_probe_feedback.py +106 -0
  247. tgi/witness_response.py +67 -0
  248. tgi_foundation-0.2.0.dev0.dist-info/METADATA +30 -0
  249. tgi_foundation-0.2.0.dev0.dist-info/RECORD +252 -0
  250. tgi_foundation-0.2.0.dev0.dist-info/WHEEL +5 -0
  251. tgi_foundation-0.2.0.dev0.dist-info/licenses/LICENSE +3 -0
  252. tgi_foundation-0.2.0.dev0.dist-info/top_level.txt +1 -0
tgi/__init__.py ADDED
@@ -0,0 +1,7 @@
1
+ """TGI foundation. No crystallization or capability claim is made by this package."""
2
+ from .identity import REGISTRY_ID, encode, decode
3
+ from .events import Event, EventStream
4
+ from .derivation import Derivation, DerivationContract, Resolution, ResolutionStatus
5
+
6
+ __all__ = ["REGISTRY_ID", "encode", "decode", "Event", "EventStream",
7
+ "Derivation", "DerivationContract", "Resolution", "ResolutionStatus"]
tgi/__main__.py ADDED
@@ -0,0 +1,194 @@
1
+ import argparse
2
+ import json
3
+ from pathlib import Path
4
+ from .identity import REGISTRY_ID, encode
5
+ from .provenance import verify_sources
6
+
7
+
8
+ def main():
9
+ parser = argparse.ArgumentParser(description="TGI foundation inspection")
10
+ subs = parser.add_subparsers(dest="command", required=True)
11
+ enc = subs.add_parser("encode", help="Inspect static NMU identities")
12
+ enc.add_argument("text")
13
+ check = subs.add_parser("verify-sources", help="Check source integrity")
14
+ check.add_argument("--root", type=Path, default=Path.cwd())
15
+ form = subs.add_parser("inspect-formation", help="Inspect experimental causal chart; not semantic resolution")
16
+ form.add_argument("text")
17
+ learn = subs.add_parser("relation-learn", help="Experimental affine lattice candidate, not free-language learning")
18
+ learn.add_argument("--input", type=Path, required=True)
19
+ learn.add_argument("--state", type=Path, required=True)
20
+ query = subs.add_parser("relation-query", help="Certified consequence within the affine measurement contract")
21
+ query.add_argument("--state", type=Path, required=True)
22
+ query.add_argument("--context", required=True)
23
+ query.add_argument("--point", nargs=5, type=int, required=True)
24
+ inspect = subs.add_parser("relation-inspect", help="Inspect experimental C/L, Omega, xi, and relation anchor")
25
+ inspect.add_argument("--state", type=Path, required=True)
26
+ inspect.add_argument("--context", required=True)
27
+ ingest = subs.add_parser("ingest", help="Crystallize framed character experiences under the user acceptance contract")
28
+ ingest.add_argument("--input",type=Path,required=True)
29
+ ingest.add_argument("--state",type=Path,required=True)
30
+ fq = subs.add_parser("query", help="Traverse committed crystal atoms with trigger and anchor")
31
+ fq.add_argument("--state",type=Path,required=True)
32
+ fq.add_argument("--trigger",required=True)
33
+ fq.add_argument("--anchor",type=int,required=True)
34
+ fq.add_argument("--max-new",type=int)
35
+ fi = subs.add_parser("inspect", help="Inspect committed frame crystal state and C/L evidence")
36
+ fi.add_argument("--state",type=Path,required=True)
37
+ fi.add_argument("--anchor",type=int)
38
+ tl = subs.add_parser("transport-learn", help="Experimental paired-path learning; explicit operator family")
39
+ tl.add_argument("--input", type=Path, required=True)
40
+ tl.add_argument("--state", type=Path, required=True)
41
+ tq = subs.add_parser("transport-query", help="Resolve a source-absent path with character provenance")
42
+ tq.add_argument("--state", type=Path, required=True)
43
+ tq.add_argument("--context", required=True)
44
+ tq.add_argument("--text", required=True)
45
+ ti = subs.add_parser("transport-inspect", help="Inspect transport hypotheses and evidence")
46
+ ti.add_argument("--state", type=Path, required=True)
47
+ ti.add_argument("--context", required=True)
48
+ tc = subs.add_parser("transport-compose", help="Compose an explicit sequence of learned relations")
49
+ tc.add_argument("--state", type=Path, required=True)
50
+ tc.add_argument("--contexts", nargs="+", required=True)
51
+ tc.add_argument("--text", required=True)
52
+ el = subs.add_parser("experience-learn", help="Ingest grounding, facts, and controlled intervention events")
53
+ el.add_argument("--input", type=Path, required=True)
54
+ el.add_argument("--state", type=Path, required=True)
55
+ eq = subs.add_parser("experience-ask", help="Resolve a raw question through grounded crystal relations")
56
+ eq.add_argument("--state", type=Path, required=True)
57
+ eq.add_argument("--text", required=True)
58
+ eq.add_argument("--world", default="default")
59
+ ei = subs.add_parser("experience-inspect", help="Inspect grounded schemas and intervention models")
60
+ ei.add_argument("--state", type=Path, required=True)
61
+ ep = subs.add_parser("experience-predict", help="Predict a measured action under its stated condition")
62
+ ep.add_argument("--state", type=Path, required=True)
63
+ ep.add_argument("--action", required=True)
64
+ ep.add_argument("--before", required=True, help="JSON sensor state")
65
+ ep.add_argument("--condition", default="default")
66
+ ep.add_argument("--world", default="default")
67
+ eg = subs.add_parser("experience-plan", help="Find an action path to a goal without a supplied action sequence")
68
+ eg.add_argument("--state", type=Path, required=True)
69
+ eg.add_argument("--before", required=True, help="JSON sensor state")
70
+ eg.add_argument("--goal", required=True, help="JSON goal sensor subset")
71
+ eg.add_argument("--condition", default="default")
72
+ eg.add_argument("--world", default="default")
73
+ eg.add_argument("--max-depth", type=int, default=16)
74
+ eg.add_argument("--max-states", type=int, default=10000)
75
+ ex = subs.add_parser("experience-propose", help="Propose unmeasured intervention contrasts without supplying outcomes")
76
+ ex.add_argument("--state", type=Path, required=True)
77
+ ex.add_argument("--action", required=True)
78
+ ex.add_argument("--domains", required=True, help="JSON mapping sensor names to available values")
79
+ ex.add_argument("--condition", default="default")
80
+ ex.add_argument("--world", default="default")
81
+ ex.add_argument("--limit", type=int, default=16)
82
+ eu = subs.add_parser("experience-upgrade", help="Replay a V1 journal with corrected guard derivation into a new checkpoint")
83
+ eu.add_argument("--input", type=Path, required=True)
84
+ eu.add_argument("--state", type=Path, required=True)
85
+ rl = subs.add_parser("raw-learn", help="Form organizations from ordered raw character episodes")
86
+ rl.add_argument("--input", type=Path, required=True)
87
+ rl.add_argument("--state", type=Path, required=True)
88
+ rq = subs.add_parser("raw-ask", help="Resolve a raw question against observed episode prefixes")
89
+ rq.add_argument("--state", type=Path, required=True)
90
+ rq.add_argument("--text", required=True)
91
+ rr = subs.add_parser("raw-resolve", help="Continue an ordered raw episode prefix")
92
+ rr.add_argument("--state", type=Path, required=True)
93
+ rr.add_argument("--frames", required=True, help="JSON array of raw frames")
94
+ rr.add_argument("--max-verification-match-steps", type=int, default=None, help="Optional ceiling on verifier matcher states; not query generation")
95
+ ri = subs.add_parser("raw-inspect", help="Inspect raw organization anchors and source support")
96
+ ri.add_argument("--state", type=Path, required=True)
97
+ rc = subs.add_parser("raw-reason", help="Resolve certified closure across raw episode organizations")
98
+ rc.add_argument("--state", type=Path, required=True)
99
+ rc.add_argument("--text", required=True)
100
+ rc.add_argument("--max-nodes", type=int, default=1024)
101
+ rc.add_argument("--max-work", type=int, default=1000000)
102
+ ru = subs.add_parser("raw-upgrade", help="Explicitly replay V1 raw evidence under phase V2 into a new checkpoint")
103
+ ru.add_argument("--input", type=Path, required=True)
104
+ ru.add_argument("--state", type=Path, required=True)
105
+ rx = subs.add_parser("raw-incidence", help="Trace phase-bound links between observed axis occurrences")
106
+ rx.add_argument("--state", type=Path, required=True)
107
+ rx.add_argument("--source", required=True)
108
+ rx.add_argument("--frame", type=int, required=True)
109
+ rx.add_argument("--start", type=int, required=True)
110
+ rx.add_argument("--stop", type=int, required=True)
111
+ rx.add_argument("--direction", choices=("all","forward","backward"), default="all")
112
+ ry = subs.add_parser("raw-correspondence", help="Trace witnessed axis correspondence between organizations")
113
+ ry.add_argument("--state", type=Path, required=True)
114
+ ry.add_argument("--left", required=True)
115
+ ry.add_argument("--axis", type=int, required=True)
116
+ ry.add_argument("--right", required=True)
117
+ for raw_parser in (rl, rq, rr, ri, rc, ru, rx, ry):
118
+ raw_parser.add_argument("--max-formation-steps", type=int, default=None,
119
+ help="Ceiling on formation candidate enumeration; not a wall-clock timeout")
120
+ args = parser.parse_args()
121
+ if args.command.startswith("raw-"):
122
+ from .organization_cli import run
123
+ try:
124
+ print(json.dumps(run(args), ensure_ascii=True))
125
+ except (ValueError, TypeError, OSError, KeyError) as error:
126
+ parser.error(str(error))
127
+ return 0
128
+ if args.command.startswith("experience-"):
129
+ from .experience_cli import run
130
+ try:
131
+ print(json.dumps(run(args), ensure_ascii=True))
132
+ except (ValueError, TypeError, OSError) as error:
133
+ parser.error(str(error))
134
+ return 0
135
+ if args.command.startswith("transport-"):
136
+ from .transport_cli import run
137
+ try:
138
+ print(json.dumps(run(args), ensure_ascii=True))
139
+ except (ValueError, TypeError, OSError) as error:
140
+ parser.error(str(error))
141
+ return 0
142
+ if args.command in ("ingest","query","inspect"):
143
+ from .frame_cli import run
144
+ try:
145
+ print(json.dumps(run(args),ensure_ascii=True))
146
+ except (ValueError,TypeError,OSError) as error:
147
+ parser.error(str(error))
148
+ return 0
149
+ if args.command.startswith("relation-"):
150
+ from .relational import RelationalEngine,unique_object
151
+ if args.command == "relation-learn":
152
+ engine = RelationalEngine.load(args.state) if args.state.exists() else RelationalEngine()
153
+ for line in args.input.read_text(encoding="utf8").splitlines():
154
+ if not line.strip():
155
+ continue
156
+ entry = json.loads(line,object_pairs_hook=unique_object)
157
+ if not isinstance(entry,dict) or set(entry)!={"source_id","raw"}:
158
+ raise ValueError("Each JSONL entry must contain exactly source_id and raw")
159
+ engine.observe(entry["raw"],entry["source_id"])
160
+ engine.save(args.state)
161
+ contexts = sorted({m.context for m in engine.measurements()})
162
+ print(json.dumps({"scope":"experimental_affine_lattice", "sources":len(engine.measurements()),
163
+ "contexts":{c:engine.inspect(c) for c in contexts}},ensure_ascii=True))
164
+ return 0
165
+ engine = RelationalEngine.load(args.state)
166
+ if args.command == "relation-inspect":
167
+ print(json.dumps(engine.inspect(args.context),ensure_ascii=True))
168
+ return 0
169
+ print(json.dumps(engine.resolve(args.context,args.point).as_dict(),ensure_ascii=True))
170
+ return 0
171
+ if args.command == "encode":
172
+ print(json.dumps({"registry": REGISTRY_ID, "identities": encode(args.text)}, ensure_ascii=True))
173
+ return 0
174
+ if args.command == "inspect-formation":
175
+ from dataclasses import asdict
176
+ from .events import EventStream
177
+ from .formation import CausalFormation
178
+ model = CausalFormation()
179
+ records = model.observe(EventStream("cli").feed(args.text))
180
+ print(json.dumps({"candidate": "TGI-CAUSAL-RECURRENCE-5D-V1",
181
+ "scope": "causal_chart_only", "semantic_admission": False,
182
+ "records": [asdict(r) for r in records],
183
+ "bond_count": len(model.geometry_snapshot()[0]),
184
+ "closure_count": len(model.geometry_snapshot()[1])}, ensure_ascii=True))
185
+ return 0
186
+ manifest = json.loads((args.root / "contracts/source_manifest.json").read_text(encoding="utf8"))
187
+ failures = verify_sources(args.root, manifest)
188
+ print(json.dumps({"source_count": len(manifest["sources"]), "mismatches": failures,
189
+ "scope": "source_integrity_only"}, ensure_ascii=True))
190
+ return int(bool(failures))
191
+
192
+
193
+ if __name__ == "__main__":
194
+ raise SystemExit(main())
@@ -0,0 +1,45 @@
1
+ """Complete conditional histories over recorded discrete occurrences."""
2
+ from .identity import decode
3
+ from .incidence import _endpoint
4
+ from .organization_snapshot import snapshot
5
+ from .separation_check import verify_separating_requests
6
+
7
+
8
+ def _choices(plan,live):
9
+ choices={}
10
+ for row in plan['requests']:
11
+ groups={tuple(g['value']):set(g['contexts'])&live for g in row['responses']}
12
+ groups={value:ids for value,ids in groups.items() if ids}
13
+ covered=set().union(*groups.values()) if groups else set()
14
+ if len(live)>1 and covered==live and all(len(ids)<len(live) for ids in groups.values()):
15
+ choices[row['query']]=groups
16
+ return choices
17
+
18
+
19
+ def certify_acquisition_history(model,plan,acquisition,source,boundaries):
20
+ if not verify_separating_requests(model,plan):raise ValueError('Invalid model plan')
21
+ view=snapshot(acquisition)
22
+ if not isinstance(source,str) or not source:raise ValueError('Source required')
23
+ frames=view.episodes[source][0]
24
+ if (not isinstance(boundaries,(list,tuple)) or len(boundaries)<2 or
25
+ any(type(x) is not int for x in boundaries) or boundaries[0]!=0 or
26
+ boundaries[-1]!=len(frames) or any(b-a<2 for a,b in zip(boundaries,boundaries[1:]))):
27
+ raise ValueError('Intervals must cover the entire source in order')
28
+ if not view._alive(source):raise ValueError('Broken acquisition evidence')
29
+ live=set(range(len(plan['contexts'])));events=[];status='OBSERVED'
30
+ for step,(start,stop) in enumerate(zip(boundaries,boundaries[1:])):
31
+ request=decode(frames[start]);observed=[decode(f) for f in frames[start+1:stop]]
32
+ before=sorted(live);choices=_choices(plan,live)
33
+ if step==0:
34
+ if request!=plan['request'] or observed!=plan['observed']:raise ValueError('Initial observation differs from plan')
35
+ else:
36
+ if request not in choices:raise ValueError('Request does not separate current contexts')
37
+ live=choices[request].get(tuple(observed),set())
38
+ status='REFINED' if live else 'UNMODELED_RESPONSE'
39
+ if not live and step!=len(boundaries)-2:raise ValueError('History continues beyond unmodeled feedback')
40
+ events.append({'request':request,'observed':observed,'before':before,'after':sorted(live),
41
+ 'admissible':sorted(choices),
42
+ 'occurrences':[_endpoint(view,source,(i,0,len(frames[i]))) for i in range(start,stop)]})
43
+ return {'plan':plan,'source':source,'boundaries':list(boundaries),'events':events,
44
+ 'result':{'status':status,'context_indexes':sorted(live),
45
+ 'contexts':[plan['contexts'][i] for i in sorted(live)],'next_requests':sorted(_choices(plan,live))}}
@@ -0,0 +1,51 @@
1
+ """Independent history coverage and conditional intersection verification."""
2
+ from .identity import decode
3
+ from .organization_snapshot import snapshot
4
+ from .separation_check import verify_separating_requests
5
+ from .frame_engine import canonical
6
+
7
+
8
+ def verify_acquisition_history(model,acquisition,certificate):
9
+ try:
10
+ if set(certificate)!={'plan','source','boundaries','events','result'}:return False
11
+ plan=certificate['plan']
12
+ if not verify_separating_requests(model,plan):return False
13
+ view=snapshot(acquisition);source=certificate['source']
14
+ if not isinstance(source,str) or not source or not view._alive(source):return False
15
+ frames,receipts=view.episodes[source];bounds=certificate['boundaries']
16
+ if (not isinstance(bounds,list) or len(bounds)<2 or any(type(x) is not int for x in bounds)
17
+ or bounds[0]!=0 or bounds[-1]!=len(frames) or any(b-a<2 for a,b in zip(bounds,bounds[1:]))):return False
18
+ if len(certificate['events'])!=len(bounds)-1:return False
19
+ live=list(range(len(plan['contexts'])));status='OBSERVED'
20
+
21
+ def choices(indexes):
22
+ admitted={}
23
+ if len(indexes)<2:return admitted
24
+ for row in plan['requests']:
25
+ alternatives={};covered=set()
26
+ for g in row['responses']:
27
+ retained=[i for i in indexes if i in g['contexts']]
28
+ if retained:alternatives[tuple(g['value'])]=retained;covered.update(retained)
29
+ if covered==set(indexes) and all(len(ids)<len(indexes) for ids in alternatives.values()):admitted[row['query']]=alternatives
30
+ return admitted
31
+
32
+ for step,row in enumerate(certificate['events']):
33
+ start,stop=bounds[step:step+2];request=decode(frames[start]);observed=[decode(f) for f in frames[start+1:stop]]
34
+ before=list(live);allowed=choices(live)
35
+ if step==0:
36
+ if request!=plan['request'] or observed!=plan['observed']:return False
37
+ else:
38
+ if request not in allowed:return False
39
+ live=allowed[request].get(tuple(observed),[])
40
+ status='REFINED' if live else 'UNMODELED_RESPONSE'
41
+ if not live and step!=len(bounds)-2:return False
42
+ occurrences=[]
43
+ for i in range(start,stop):
44
+ offset=sum(map(len,frames[:i]));size=len(frames[i]);origin=receipts[i].origin
45
+ occurrences.append({'frame':i,'start':0,'stop':size,'event_span':[offset,offset+size],
46
+ 'identities':list(frames[i]),'coordinates':[[origin[0]+j,*origin[1:]] for j in range(size)]})
47
+ expected={'request':request,'observed':observed,'before':before,'after':live,'admissible':sorted(allowed),'occurrences':occurrences}
48
+ if canonical(row)!=canonical(expected):return False
49
+ expected={'status':status,'context_indexes':live,'contexts':[plan['contexts'][i] for i in live],'next_requests':sorted(choices(live))}
50
+ return canonical(certificate['result'])==canonical(expected)
51
+ except (KeyError,IndexError,TypeError,ValueError,AttributeError):return False
@@ -0,0 +1,66 @@
1
+ """Stationary candidate monitoring over complete recorded acquisition histories."""
2
+ from copy import deepcopy
3
+ from tgi.identity import decode
4
+ from tgi.organization_snapshot import snapshot
5
+ from tgi.separation_check import verify_separating_requests
6
+
7
+ def _monitor(model, plan, acquisition, source, boundaries, budget):
8
+ model = snapshot(model)
9
+ plan = deepcopy(plan)
10
+ if not verify_separating_requests(model, plan):
11
+ raise ValueError('Invalid external plan')
12
+ view = snapshot(acquisition)
13
+ if not isinstance(source, str) or not source or source not in view.episodes:
14
+ raise ValueError('Missing acquisition source')
15
+ scope = []
16
+ for sid, (raw, _) in sorted(view.episodes.items()):
17
+ budget.consume()
18
+ if not view._alive(sid):
19
+ raise ValueError('Broken acquisition evidence')
20
+ scope.append(dict(source=sid, frames=list(map(decode, raw))))
21
+ frames, receipts = view.episodes[source]
22
+ if not isinstance(boundaries, (list, tuple)) or len(boundaries) < 2 or any((type(x) is not int for x in boundaries)) or (boundaries[0] != 0) or (boundaries[-1] != len(frames)) or any((b - a < 2 for a, b in zip(boundaries, boundaries[1:]))):
23
+ raise ValueError('Boundaries must cover every source frame')
24
+ offsets = [0]
25
+ for frame in frames:
26
+ budget.consume()
27
+ offsets.append(offsets[-1] + len(frame))
28
+ universe = set(range(len(plan['contexts'])))
29
+ possible, definite = (set(universe), set(universe))
30
+ events = []
31
+ for step, (start, stop) in enumerate(zip(boundaries, boundaries[1:])):
32
+ budget.consume()
33
+ request = decode(frames[start])
34
+ observed = list(map(decode, frames[start + 1:stop]))
35
+ if step == 0:
36
+ if request != plan['request'] or observed != plan['observed']:
37
+ raise ValueError('Initial observation differs from external plan')
38
+ supported, unknown = (set(universe), set())
39
+ else:
40
+ row = next((r for r in plan['requests'] if r['query'] == request), None)
41
+ groups = row['responses'] if row else []
42
+ covered = set().union(*(set(g['contexts']) for g in groups))
43
+ supported = set().union(*(set(g['contexts']) for g in groups if g['value'] == observed))
44
+ unknown = universe - covered
45
+ possible &= supported | unknown
46
+ definite &= supported
47
+ points = []
48
+ for i in range(start, stop):
49
+ budget.consume()
50
+ origin = receipts[i].origin
51
+ n = len(frames[i])
52
+ points.append(dict(frame=i, start=0, stop=n,
53
+ event_span=[offsets[i], offsets[i+1]],
54
+ identities=list(frames[i]),
55
+ coordinates=[[origin[0]+j, *origin[1:]] for j in range(n)]))
56
+ events.append(dict(request=request, observed=observed, supported=sorted(supported), unknown=sorted(unknown), possible=sorted(possible), definite=sorted(definite), occurrences=points))
57
+ status = 'CONTRADICTED' if not possible else 'INCOMPLETE' if possible != definite else 'CONSISTENT'
58
+ return dict(policy='stationary_acquisition_monitor_v1', plan=plan, source=source, scope=scope, boundaries=list(boundaries), events=events, result=dict(status=status, possible=sorted(possible), definite=sorted(definite)))
59
+
60
+ from tgi.role_work import RoleSearchBudget
61
+
62
+ def certify_acquisition_monitor(model, plan, acquisition, source, boundaries, *, max_search_steps=None):
63
+ budget = RoleSearchBudget(max_search_steps)
64
+ with budget.scope():
65
+ budget.consume()
66
+ return _monitor(model, plan, acquisition, source, boundaries, budget)
@@ -0,0 +1,78 @@
1
+ """Independent candidate-wise verification, never invokes monitor producer."""
2
+ from tgi.identity import decode
3
+ from tgi.frame_engine import canonical
4
+ from tgi.organization_snapshot import snapshot
5
+ from tgi.separation_check import verify_separating_requests
6
+
7
+ def _verify_monitor(model, plan, acquisition, source, boundaries, c, budget):
8
+ try:
9
+ if not isinstance(c, dict) or set(c) != {'policy', 'plan', 'source', 'scope', 'boundaries', 'events', 'result'}:
10
+ return False
11
+ if c['policy'] != 'stationary_acquisition_monitor_v1' or c['source'] != source or canonical(c['plan']) != canonical(plan):
12
+ return False
13
+ model = snapshot(model)
14
+ if not verify_separating_requests(model, plan):
15
+ return False
16
+ a = snapshot(acquisition)
17
+ if not isinstance(source, str) or not source or source not in a.episodes:
18
+ return False
19
+ scope = []
20
+ for sid, (raw, _) in sorted(a.episodes.items()):
21
+ budget.consume()
22
+ if not a._alive(sid):
23
+ return False
24
+ scope.append(dict(source=sid, frames=list(map(decode, raw))))
25
+ if canonical(c['scope']) != canonical(scope):
26
+ return False
27
+ frames, receipts = a.episodes[source]
28
+ if not isinstance(boundaries, (list, tuple)) or len(boundaries) < 2 or any((type(x) is not int for x in boundaries)) or (boundaries[0] != 0) or (boundaries[-1] != len(frames)) or any((b - a < 2 for a, b in zip(boundaries, boundaries[1:]))):
29
+ return False
30
+ if canonical(c['boundaries']) != canonical(list(boundaries)) or not isinstance(c['events'], list) or len(c['events']) != len(boundaries) - 1:
31
+ return False
32
+ verdicts = [[0, 0] for _ in plan['contexts']]
33
+ offset = 0
34
+ for step, (lo, hi) in enumerate(zip(boundaries, boundaries[1:])):
35
+ budget.consume()
36
+ query = decode(frames[lo])
37
+ observed = [decode(frames[i]) for i in range(lo + 1, hi)]
38
+ supported = []
39
+ unknown = []
40
+ if step == 0:
41
+ if query != plan['request'] or observed != plan['observed']:
42
+ return False
43
+ supported = list(range(len(verdicts)))
44
+ else:
45
+ for index, history in enumerate(verdicts):
46
+ budget.consume()
47
+ values = [g['value'] for row in plan['requests'] if row['query'] == query for g in row['responses'] if index in g['contexts']]
48
+ if not values:
49
+ unknown.append(index)
50
+ history[1] += 1
51
+ elif observed in values:
52
+ supported.append(index)
53
+ else:
54
+ history[0] += 1
55
+ possible = [i for i, vs in enumerate(verdicts) if vs[0] == 0]
56
+ definite = [i for i, vs in enumerate(verdicts) if vs == [0, 0]]
57
+ points = []
58
+ for i in range(lo, hi):
59
+ budget.consume()
60
+ n = len(frames[i])
61
+ origin = receipts[i].origin
62
+ points.append(dict(frame=i, start=0, stop=n, event_span=[offset, offset + n], identities=list(frames[i]), coordinates=[[origin[0] + j, *origin[1:]] for j in range(n)]))
63
+ offset += n
64
+ expected = dict(request=query, observed=observed, supported=supported, unknown=unknown, possible=possible, definite=definite, occurrences=points)
65
+ if canonical(c['events'][step]) != canonical(expected):
66
+ return False
67
+ status = 'CONTRADICTED' if not possible else 'INCOMPLETE' if possible != definite else 'CONSISTENT'
68
+ return canonical(c['result']) == canonical(dict(status=status, possible=possible, definite=definite))
69
+ except (ValueError, TypeError, KeyError, IndexError, AttributeError):
70
+ return False
71
+
72
+ from tgi.role_work import RoleSearchBudget
73
+
74
+ def verify_acquisition_monitor(model, plan, acquisition, source, boundaries, certificate, *, max_search_steps=None):
75
+ budget = RoleSearchBudget(max_search_steps)
76
+ with budget.scope():
77
+ budget.consume()
78
+ return _verify_monitor(model, plan, acquisition, source, boundaries, certificate, budget)
@@ -0,0 +1,70 @@
1
+ from tgi.compact_measured_path import _read_count
2
+ from tgi.identity import encode,decode
3
+ from tgi.acquisition_witness import certify_acquisition_witness
4
+ from tgi.organization import OMEGA_CRIT
5
+ from tgi.frame_engine import canonical
6
+ from tgi.compact_measured_path import _decimal_count
7
+
8
+ def build(left,right,alignments,direction,budget):
9
+ index={(a['left'],a['right'],a['direction']):k for k,a in enumerate(alignments)}
10
+ states=[(0,())];lookup={(0,()):0};ways=[1];edges=[];cursor=0
11
+ while cursor<len(states):
12
+ budget.consume()
13
+ mask,items=states[cursor];i=mask.bit_count()
14
+ if i<len(left):
15
+ for j in range(len(right)):
16
+ budget.consume()
17
+ if mask&(1<<j):continue
18
+ aid=index.get((i,j,direction))
19
+ if aid is None:continue
20
+ a=alignments[aid];mapping=dict(items);valid=True
21
+ for u,v,_,_ in a['positions']:
22
+ budget.consume()
23
+ if u in mapping and mapping[u]!=v:valid=False;break
24
+ mapping[u]=v
25
+ if not valid:continue
26
+ state=(mask|(1<<j),tuple(sorted(mapping.items())))
27
+ if state not in lookup:lookup[state]=len(states);states.append(state);ways.append(0)
28
+ target=lookup[state];ways[target]+=ways[cursor];edges.append([cursor,target,aid])
29
+ cursor+=1
30
+ return dict(direction=direction,nodes=[dict(mask=mask,mapping=[list(p) for p in items],count=_decimal_count(ways[i])) for i,(mask,items) in enumerate(states)],edges=edges,terminals=[i for i,(mask,_) in enumerate(states) if mask.bit_count()==len(left)])
31
+
32
+ def _produce(m,measurements,left,right,query,budget):
33
+ q=encode(query)
34
+ if not q or not isinstance(left,list) or not isinstance(right,list) or len(set(left))!=len(left) or len(set(right))!=len(right) or set(left)&set(right) or set(left)|set(right)!=set(m.episodes):raise ValueError('Complete disjoint channels required')
35
+ witness=certify_acquisition_witness(m,measurements);records={r['source']:r for r in witness['measurements']}
36
+ if len(records)!=len(measurements) or set(records)!=set(m.episodes):raise ValueError('Full measurements required')
37
+ for s,(frames,_) in m.episodes.items():
38
+ budget.consume()
39
+ r=records[s]
40
+ if len(frames)!=1 or r['frame']!=0 or r['start']!=0 or r['stop']!=len(frames[0]):raise ValueError('Full single-frame scope required')
41
+ left=sorted(left);right=sorted(right);clocks=sorted({r['clock'] for r in records.values()});enabled=len(left)==len(right) and len(clocks)==1;alignments=[];graphs=[];outcomes=[]
42
+ if enabled:
43
+ for i,a in enumerate(left):
44
+ for j,b in enumerate(right):
45
+ budget.consume()
46
+ if max(records[a]['lower'],records[b]['lower'])>min(records[a]['upper'],records[b]['upper']):continue
47
+ alignments.append(dict(left=i,right=j,direction=0,positions=[]));x=m.episodes[a][0][0];y=m.episodes[b][0][0]
48
+ if len(x)!=len(y):continue
49
+ for _ in x:budget.consume()
50
+ for direction in (-1,1):alignments.append(dict(left=i,right=j,direction=direction,positions=[[u,y[k if direction==1 else len(x)-1-k],k,k if direction==1 else len(x)-1-k] for k,u in enumerate(x)]))
51
+ for direction in (0,-1,1):
52
+ graph=build(left,right,alignments,direction,budget);graphs.append(graph)
53
+ if direction:
54
+ for terminal in graph['terminals']:
55
+ for _ in q:budget.consume()
56
+ node=graph['nodes'][terminal];mapping=dict(node['mapping']);missing=sorted(set(q)-set(mapping));ids=q if direction==1 else q[::-1]
57
+ fibers={}
58
+ for u,v in sorted(mapping.items()):budget.consume();fibers.setdefault(v,[]).append(u)
59
+ outcomes.append(dict(direction=direction,terminal=terminal,count=node['count'],inverse_fibers=[dict(output=v,inputs=us) for v,us in sorted(fibers.items())],missing=missing,output=None if missing else decode(tuple(mapping[u] for u in ids))))
60
+ count=sum(_read_count(o['count']) for o in outcomes);outputs=sorted({o['output'] for o in outcomes if o['output'] is not None});distinct=len({m.episodes[s][0][0] for s in left})
61
+ status='INCOMPLETE' if len(left)!=len(right) else 'CLOCK_UNDETERMINED' if len(clocks)!=1 else 'CONFLICT' if not count else 'INCOMPLETE' if distinct<OMEGA_CRIT else 'UNKNOWN_ID' if any(o['missing'] for o in outcomes) else 'AMBIGUOUS_OUTPUT' if len(outputs)!=1 else 'CONDITIONAL_OUTPUT'
62
+ return dict(query=query,left=left,right=right,witness=witness,alignments=alignments,graphs=graphs,outcomes=outcomes,alternative_count=_decimal_count(count),diversity=distinct,status=status,outputs=outputs,output=outputs[0] if status=='CONDITIONAL_OUTPUT' else None)
63
+
64
+
65
+ def certify_acquisition_projection(model,measurements,left,right,query,*,max_search_steps=None):
66
+ from .organization_snapshot import snapshot
67
+ from .role_work import RoleSearchBudget
68
+ budget=RoleSearchBudget(max_search_steps)
69
+ with budget.scope():
70
+ return dict(policy='acquisition_projection_v1',threshold=OMEGA_CRIT,**_produce(snapshot(model),[dict(r) for r in measurements],list(left) if isinstance(left,list) else left,list(right) if isinstance(right,list) else right,query,budget))
@@ -0,0 +1,93 @@
1
+ from tgi.compact_measured_path import _read_count
2
+ """Verify complete reachable assignment closure, not a producer rerun."""
3
+ from .identity import encode,decode
4
+ from .organization import OMEGA_CRIT
5
+ from .organization_snapshot import snapshot
6
+ from .acquisition_witness import verify_acquisition_witness
7
+ from .role_work import RoleSearchBudget
8
+ from .frame_engine import canonical
9
+ from .compact_measured_path import _decimal_count
10
+
11
+ def _graph(g,left,right,alignments,direction,budget):
12
+ if set(g)!={'direction','nodes','edges','terminals'} or type(g['direction']) is not int or g['direction']!=direction:raise ValueError('Graph schema')
13
+ nodes=g['nodes'];keys=[];lookup={}
14
+ for i,node in enumerate(nodes):
15
+ budget.consume()
16
+ if set(node)!={'mask','mapping','count'} or type(node['mask']) is not int or not 0<=node['mask']<(1<<len(right)):raise ValueError('State schema')
17
+ items=tuple(tuple(p) for p in node['mapping'])
18
+ if any(len(p)!=2 or any(type(x) is not int for x in p) for p in items) or items!=tuple(sorted(set(items))) or len({x for x,y in items})!=len(items):raise ValueError('Invalid state relation')
19
+ key=(node['mask'],items)
20
+ if key in lookup:raise ValueError('Duplicate state')
21
+ lookup[key]=i;keys.append(key)
22
+ if not keys or keys[0]!=(0,()):raise ValueError('Missing root')
23
+ index={(a['left'],a['right'],a['direction']):k for k,a in enumerate(alignments)};edges=[]
24
+ for source,(mask,items) in enumerate(keys):
25
+ i=mask.bit_count()
26
+ if i==len(left):continue
27
+ for j in range(len(right)):
28
+ budget.consume()
29
+ aid=index.get((i,j,direction))
30
+ if mask&(1<<j) or aid is None:continue
31
+ pairs=set(items)
32
+ for u,v,_,_ in alignments[aid]['positions']:budget.consume();pairs.add((u,v))
33
+ if len({x for x,y in pairs})!=len(pairs):continue
34
+ key=(mask|(1<<j),tuple(sorted(pairs)))
35
+ if key not in lookup:raise ValueError('Omitted continuation')
36
+ edges.append([source,lookup[key],aid])
37
+ if canonical(edges)!=canonical(g['edges']):raise ValueError('Incomplete transition inventory')
38
+ incoming=[[] for _ in nodes]
39
+ for a,b,_ in edges:incoming[b].append(a)
40
+ counts=[0]*len(nodes);counts[0]=1
41
+ for i in sorted(range(1,len(nodes)),key=lambda i:keys[i][0].bit_count()):
42
+ budget.consume();counts[i]=sum(counts[a] for a in incoming[i])
43
+ if any(v==0 for v in counts) or any(nodes[i]['count']!=_decimal_count(v) for i,v in enumerate(counts)):raise ValueError('Unreachable state or incorrect multiplicity')
44
+ terminals=[i for i,(mask,_) in enumerate(keys) if mask.bit_count()==len(left)]
45
+ if canonical(terminals)!=canonical(g['terminals']):raise ValueError('Terminal scope')
46
+ return terminals
47
+
48
+ def verify_acquisition_projection(model,measurements,left,right,query,c,*,max_search_steps=None):
49
+ budget=RoleSearchBudget(max_search_steps)
50
+ with budget.scope():
51
+ try:
52
+ if not isinstance(c,dict) or set(c)!={'policy','threshold','query','left','right','witness','alignments','graphs','outcomes','alternative_count','diversity','status','outputs','output'} or c['policy']!='acquisition_projection_v1' or type(c['threshold']) is not int or c['threshold']!=OMEGA_CRIT:return False
53
+ m=snapshot(model);q=encode(query);measurements=[dict(r) for r in measurements];left=list(left) if isinstance(left,list) else left;right=list(right) if isinstance(right,list) else right
54
+ if not q or not isinstance(left,list) or not isinstance(right,list) or len(set(left))!=len(left) or len(set(right))!=len(right) or set(left)&set(right) or set(left)|set(right)!=set(m.episodes):return False
55
+ if not verify_acquisition_witness(m,measurements,c['witness']):return False
56
+ records={r['source']:r for r in measurements}
57
+ if len(records)!=len(measurements) or set(records)!=set(m.episodes):return False
58
+ for s,(frames,_) in m.episodes.items():
59
+ budget.consume();r=records[s]
60
+ if len(frames)!=1 or (r['frame'],r['start'],r['stop'])!=(0,0,len(frames[0])):return False
61
+ left=sorted(left);right=sorted(right)
62
+ if c['query']!=query or canonical(c['left'])!=canonical(left) or canonical(c['right'])!=canonical(right):return False
63
+ clocks={r['clock'] for r in measurements};enabled=len(left)==len(right) and len(clocks)==1;alignments=[]
64
+ if enabled:
65
+ for i,a in enumerate(left):
66
+ for j,b in enumerate(right):
67
+ budget.consume()
68
+ if records[a]['upper']<records[b]['lower'] or records[b]['upper']<records[a]['lower']:continue
69
+ alignments.append(dict(left=i,right=j,direction=0,positions=[]));x=m.episodes[a][0][0];y=m.episodes[b][0][0]
70
+ if len(x)!=len(y):continue
71
+ for sign in (-1,1):
72
+ positions=[]
73
+ for k,u in enumerate(x):budget.consume();p=k if sign==1 else len(x)-1-k;positions.append([u,y[p],k,p])
74
+ alignments.append(dict(left=i,right=j,direction=sign,positions=positions))
75
+ if canonical(c['alignments'])!=canonical(alignments) or len(c['graphs'])!=(3 if enabled else 0):return False
76
+ outcomes=[]
77
+ for g,sign in zip(c['graphs'],(0,-1,1)):
78
+ terminals=_graph(g,left,right,alignments,sign,budget)
79
+ if not sign:continue
80
+ for terminal in terminals:
81
+ node=g['nodes'][terminal];mapping=dict(node['mapping']);missing=set();output=[]
82
+ for k in range(len(q)):
83
+ budget.consume();u=q[k if sign==1 else len(q)-1-k]
84
+ if u not in mapping:missing.add(u)
85
+ else:output.append(mapping[u])
86
+ fibers={}
87
+ for u,v in node['mapping']:budget.consume();fibers.setdefault(v,set()).add(u)
88
+ outcomes.append(dict(direction=sign,terminal=terminal,count=node['count'],inverse_fibers=[dict(output=v,inputs=sorted(us)) for v,us in sorted(fibers.items())],missing=sorted(missing),output=None if missing else decode(tuple(output))))
89
+ count=sum(_read_count(o['count']) for o in outcomes);outputs=sorted({o['output'] for o in outcomes if o['output'] is not None});distinct=len({m.episodes[s][0][0] for s in left})
90
+ status='INCOMPLETE' if len(left)!=len(right) else 'CLOCK_UNDETERMINED' if len(clocks)!=1 else 'CONFLICT' if not count else 'INCOMPLETE' if distinct<OMEGA_CRIT else 'UNKNOWN_ID' if any(o['missing'] for o in outcomes) else 'AMBIGUOUS_OUTPUT' if len(outputs)!=1 else 'CONDITIONAL_OUTPUT'
91
+ expected=dict(outcomes=outcomes,alternative_count=_decimal_count(count),diversity=distinct,status=status,outputs=outputs,output=outputs[0] if status=='CONDITIONAL_OUTPUT' else None)
92
+ return all(canonical(c[k])==canonical(v) for k,v in expected.items())
93
+ except (ValueError,TypeError,KeyError,IndexError,AttributeError):return False