dialectical-framework 2.0.3__tar.gz → 2.0.4__tar.gz

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 (229) hide show
  1. {dialectical_framework-2.0.3 → dialectical_framework-2.0.4}/PKG-INFO +1 -1
  2. {dialectical_framework-2.0.3 → dialectical_framework-2.0.4}/pyproject.toml +1 -1
  3. {dialectical_framework-2.0.3 → dialectical_framework-2.0.4}/src/dialectical_framework/agents/consultant/consultant.py +17 -25
  4. {dialectical_framework-2.0.3 → dialectical_framework-2.0.4}/src/dialectical_framework/concerns/tetrad_candidates.py +7 -2
  5. {dialectical_framework-2.0.3 → dialectical_framework-2.0.4}/src/dialectical_framework/concerns/transformation_generation.py +13 -2
  6. {dialectical_framework-2.0.3 → dialectical_framework-2.0.4}/src/dialectical_framework/concerns/transformation_sketch.py +30 -12
  7. {dialectical_framework-2.0.3 → dialectical_framework-2.0.4}/src/dialectical_framework/concerns/view_sketch.py +8 -38
  8. {dialectical_framework-2.0.3 → dialectical_framework-2.0.4}/src/dialectical_framework/utils/edge_context.py +33 -0
  9. {dialectical_framework-2.0.3 → dialectical_framework-2.0.4}/LICENSE +0 -0
  10. {dialectical_framework-2.0.3 → dialectical_framework-2.0.4}/PATENTS +0 -0
  11. {dialectical_framework-2.0.3 → dialectical_framework-2.0.4}/README.md +0 -0
  12. {dialectical_framework-2.0.3 → dialectical_framework-2.0.4}/src/dialectical_framework/__init__.py +0 -0
  13. {dialectical_framework-2.0.3 → dialectical_framework-2.0.4}/src/dialectical_framework/agents/__init__.py +0 -0
  14. {dialectical_framework-2.0.3 → dialectical_framework-2.0.4}/src/dialectical_framework/agents/advisor/__init__.py +0 -0
  15. {dialectical_framework-2.0.3 → dialectical_framework-2.0.4}/src/dialectical_framework/agents/advisor/advisor.py +0 -0
  16. {dialectical_framework-2.0.3 → dialectical_framework-2.0.4}/src/dialectical_framework/agents/advisor/build_policy.py +0 -0
  17. {dialectical_framework-2.0.3 → dialectical_framework-2.0.4}/src/dialectical_framework/agents/advisor/migration.py +0 -0
  18. {dialectical_framework-2.0.3 → dialectical_framework-2.0.4}/src/dialectical_framework/agents/advisor/reply_hygiene.py +0 -0
  19. {dialectical_framework-2.0.3 → dialectical_framework-2.0.4}/src/dialectical_framework/agents/advisor/system_prompts.py +0 -0
  20. {dialectical_framework-2.0.3 → dialectical_framework-2.0.4}/src/dialectical_framework/agents/advisor/tools/__init__.py +0 -0
  21. {dialectical_framework-2.0.3 → dialectical_framework-2.0.4}/src/dialectical_framework/agents/advisor/tools/anchor.py +0 -0
  22. {dialectical_framework-2.0.3 → dialectical_framework-2.0.4}/src/dialectical_framework/agents/advisor/tools/deepen.py +0 -0
  23. {dialectical_framework-2.0.3 → dialectical_framework-2.0.4}/src/dialectical_framework/agents/advisor/tools/explore.py +0 -0
  24. {dialectical_framework-2.0.3 → dialectical_framework-2.0.4}/src/dialectical_framework/agents/advisor/tools/ingest.py +0 -0
  25. {dialectical_framework-2.0.3 → dialectical_framework-2.0.4}/src/dialectical_framework/agents/advisor/tools/note.py +0 -0
  26. {dialectical_framework-2.0.3 → dialectical_framework-2.0.4}/src/dialectical_framework/agents/advisor/tools/record_decision.py +0 -0
  27. {dialectical_framework-2.0.3 → dialectical_framework-2.0.4}/src/dialectical_framework/agents/advisor/tools/scoped.py +0 -0
  28. {dialectical_framework-2.0.3 → dialectical_framework-2.0.4}/src/dialectical_framework/agents/advisor/tools/sync.py +0 -0
  29. {dialectical_framework-2.0.3 → dialectical_framework-2.0.4}/src/dialectical_framework/agents/agent_context.py +0 -0
  30. {dialectical_framework-2.0.3 → dialectical_framework-2.0.4}/src/dialectical_framework/agents/analyst/__init__.py +0 -0
  31. {dialectical_framework-2.0.3 → dialectical_framework-2.0.4}/src/dialectical_framework/agents/analyst/analyst.py +0 -0
  32. {dialectical_framework-2.0.3 → dialectical_framework-2.0.4}/src/dialectical_framework/agents/analyst/skills/__init__.py +0 -0
  33. {dialectical_framework-2.0.3 → dialectical_framework-2.0.4}/src/dialectical_framework/agents/analyst/skills/anchor_theses.py +0 -0
  34. {dialectical_framework-2.0.3 → dialectical_framework-2.0.4}/src/dialectical_framework/agents/analyst/skills/edit_perspective.py +0 -0
  35. {dialectical_framework-2.0.3 → dialectical_framework-2.0.4}/src/dialectical_framework/agents/analyst/skills/expand_polarities.py +0 -0
  36. {dialectical_framework-2.0.3 → dialectical_framework-2.0.4}/src/dialectical_framework/agents/analyst/skills/find_polarities.py +0 -0
  37. {dialectical_framework-2.0.3 → dialectical_framework-2.0.4}/src/dialectical_framework/agents/analyst/skills/introduce_polarity.py +0 -0
  38. {dialectical_framework-2.0.3 → dialectical_framework-2.0.4}/src/dialectical_framework/agents/analyst/skills/sketch_tetrad.py +0 -0
  39. {dialectical_framework-2.0.3 → dialectical_framework-2.0.4}/src/dialectical_framework/agents/analyst/skills/surface_theses.py +0 -0
  40. {dialectical_framework-2.0.3 → dialectical_framework-2.0.4}/src/dialectical_framework/agents/analyst/system_prompts.py +0 -0
  41. {dialectical_framework-2.0.3 → dialectical_framework-2.0.4}/src/dialectical_framework/agents/analyst/tools/__init__.py +0 -0
  42. {dialectical_framework-2.0.3 → dialectical_framework-2.0.4}/src/dialectical_framework/agents/analyst/tools/place_statement.py +0 -0
  43. {dialectical_framework-2.0.3 → dialectical_framework-2.0.4}/src/dialectical_framework/agents/app_spec.py +0 -0
  44. {dialectical_framework-2.0.3 → dialectical_framework-2.0.4}/src/dialectical_framework/agents/apps.py +0 -0
  45. {dialectical_framework-2.0.3 → dialectical_framework-2.0.4}/src/dialectical_framework/agents/consultant/__init__.py +0 -0
  46. {dialectical_framework-2.0.3 → dialectical_framework-2.0.4}/src/dialectical_framework/agents/conversation_facilitator.py +0 -0
  47. {dialectical_framework-2.0.3 → dialectical_framework-2.0.4}/src/dialectical_framework/agents/execution_report.py +0 -0
  48. {dialectical_framework-2.0.3 → dialectical_framework-2.0.4}/src/dialectical_framework/agents/explorer/__init__.py +0 -0
  49. {dialectical_framework-2.0.3 → dialectical_framework-2.0.4}/src/dialectical_framework/agents/explorer/explorer.py +0 -0
  50. {dialectical_framework-2.0.3 → dialectical_framework-2.0.4}/src/dialectical_framework/agents/explorer/skills/__init__.py +0 -0
  51. {dialectical_framework-2.0.3 → dialectical_framework-2.0.4}/src/dialectical_framework/agents/explorer/skills/build_wheels.py +0 -0
  52. {dialectical_framework-2.0.3 → dialectical_framework-2.0.4}/src/dialectical_framework/agents/explorer/skills/explore_transformations.py +0 -0
  53. {dialectical_framework-2.0.3 → dialectical_framework-2.0.4}/src/dialectical_framework/agents/explorer/skills/generate_synthesis.py +0 -0
  54. {dialectical_framework-2.0.3 → dialectical_framework-2.0.4}/src/dialectical_framework/agents/explorer/system_prompts.py +0 -0
  55. {dialectical_framework-2.0.3 → dialectical_framework-2.0.4}/src/dialectical_framework/agents/explorer/tools/__init__.py +0 -0
  56. {dialectical_framework-2.0.3 → dialectical_framework-2.0.4}/src/dialectical_framework/agents/explorer/tools/create_nexus.py +0 -0
  57. {dialectical_framework-2.0.3 → dialectical_framework-2.0.4}/src/dialectical_framework/agents/explorer/tools/expand_nexus.py +0 -0
  58. {dialectical_framework-2.0.3 → dialectical_framework-2.0.4}/src/dialectical_framework/agents/explorer/tools/generate_synthesis.py +0 -0
  59. {dialectical_framework-2.0.3 → dialectical_framework-2.0.4}/src/dialectical_framework/agents/explorer/tools/present_exploration.py +0 -0
  60. {dialectical_framework-2.0.3 → dialectical_framework-2.0.4}/src/dialectical_framework/agents/orchestrator/__init__.py +0 -0
  61. {dialectical_framework-2.0.3 → dialectical_framework-2.0.4}/src/dialectical_framework/agents/orchestrator/tools/__init__.py +0 -0
  62. {dialectical_framework-2.0.3 → dialectical_framework-2.0.4}/src/dialectical_framework/agents/orchestrator/tools/add_input.py +0 -0
  63. {dialectical_framework-2.0.3 → dialectical_framework-2.0.4}/src/dialectical_framework/agents/orchestrator/tools/audit_feasibility.py +0 -0
  64. {dialectical_framework-2.0.3 → dialectical_framework-2.0.4}/src/dialectical_framework/agents/orchestrator/tools/create_dx_input.py +0 -0
  65. {dialectical_framework-2.0.3 → dialectical_framework-2.0.4}/src/dialectical_framework/agents/orchestrator/tools/digest_input.py +0 -0
  66. {dialectical_framework-2.0.3 → dialectical_framework-2.0.4}/src/dialectical_framework/agents/orchestrator/tools/discard.py +0 -0
  67. {dialectical_framework-2.0.3 → dialectical_framework-2.0.4}/src/dialectical_framework/agents/orchestrator/tools/get_schema.py +0 -0
  68. {dialectical_framework-2.0.3 → dialectical_framework-2.0.4}/src/dialectical_framework/agents/orchestrator/tools/inspect_node.py +0 -0
  69. {dialectical_framework-2.0.3 → dialectical_framework-2.0.4}/src/dialectical_framework/agents/orchestrator/tools/present_analysis.py +0 -0
  70. {dialectical_framework-2.0.3 → dialectical_framework-2.0.4}/src/dialectical_framework/agents/orchestrator/tools/query_graph.py +0 -0
  71. {dialectical_framework-2.0.3 → dialectical_framework-2.0.4}/src/dialectical_framework/agents/orchestrator/tools/read_digest.py +0 -0
  72. {dialectical_framework-2.0.3 → dialectical_framework-2.0.4}/src/dialectical_framework/agents/orchestrator/tools/read_input.py +0 -0
  73. {dialectical_framework-2.0.3 → dialectical_framework-2.0.4}/src/dialectical_framework/agents/reasonable_concern.py +0 -0
  74. {dialectical_framework-2.0.3 → dialectical_framework-2.0.4}/src/dialectical_framework/agents/stream_events.py +0 -0
  75. {dialectical_framework-2.0.3 → dialectical_framework-2.0.4}/src/dialectical_framework/agents/toolsets.py +0 -0
  76. {dialectical_framework-2.0.3 → dialectical_framework-2.0.4}/src/dialectical_framework/agents/turn_timing.py +0 -0
  77. {dialectical_framework-2.0.3 → dialectical_framework-2.0.4}/src/dialectical_framework/concerns/__init__.py +0 -0
  78. {dialectical_framework-2.0.3 → dialectical_framework-2.0.4}/src/dialectical_framework/concerns/ac_re_taxonomy.py +0 -0
  79. {dialectical_framework-2.0.3 → dialectical_framework-2.0.4}/src/dialectical_framework/concerns/action_extraction.py +0 -0
  80. {dialectical_framework-2.0.3 → dialectical_framework-2.0.4}/src/dialectical_framework/concerns/add_input.py +0 -0
  81. {dialectical_framework-2.0.3 → dialectical_framework-2.0.4}/src/dialectical_framework/concerns/ai_dto/__init__.py +0 -0
  82. {dialectical_framework-2.0.3 → dialectical_framework-2.0.4}/src/dialectical_framework/concerns/ai_dto/statement_dto.py +0 -0
  83. {dialectical_framework-2.0.3 → dialectical_framework-2.0.4}/src/dialectical_framework/concerns/ai_dto/statements_deck_dto.py +0 -0
  84. {dialectical_framework-2.0.3 → dialectical_framework-2.0.4}/src/dialectical_framework/concerns/antithesis_classification.py +0 -0
  85. {dialectical_framework-2.0.3 → dialectical_framework-2.0.4}/src/dialectical_framework/concerns/antithesis_extraction.py +0 -0
  86. {dialectical_framework-2.0.3 → dialectical_framework-2.0.4}/src/dialectical_framework/concerns/antithetical_thesis_detection.py +0 -0
  87. {dialectical_framework-2.0.3 → dialectical_framework-2.0.4}/src/dialectical_framework/concerns/aspect_classification.py +0 -0
  88. {dialectical_framework-2.0.3 → dialectical_framework-2.0.4}/src/dialectical_framework/concerns/aspect_generation.py +0 -0
  89. {dialectical_framework-2.0.3 → dialectical_framework-2.0.4}/src/dialectical_framework/concerns/build_status.py +0 -0
  90. {dialectical_framework-2.0.3 → dialectical_framework-2.0.4}/src/dialectical_framework/concerns/causality/__init__.py +0 -0
  91. {dialectical_framework-2.0.3 → dialectical_framework-2.0.4}/src/dialectical_framework/concerns/causality/causality_estimator.py +0 -0
  92. {dialectical_framework-2.0.3 → dialectical_framework-2.0.4}/src/dialectical_framework/concerns/causality/causality_estimator_balanced.py +0 -0
  93. {dialectical_framework-2.0.3 → dialectical_framework-2.0.4}/src/dialectical_framework/concerns/causality/causality_estimator_criteria.py +0 -0
  94. {dialectical_framework-2.0.3 → dialectical_framework-2.0.4}/src/dialectical_framework/concerns/causality/causality_estimator_desirable.py +0 -0
  95. {dialectical_framework-2.0.3 → dialectical_framework-2.0.4}/src/dialectical_framework/concerns/causality/causality_estimator_feasible.py +0 -0
  96. {dialectical_framework-2.0.3 → dialectical_framework-2.0.4}/src/dialectical_framework/concerns/causality/causality_estimator_realistic.py +0 -0
  97. {dialectical_framework-2.0.3 → dialectical_framework-2.0.4}/src/dialectical_framework/concerns/causality/causality_normalizer.py +0 -0
  98. {dialectical_framework-2.0.3 → dialectical_framework-2.0.4}/src/dialectical_framework/concerns/causality/estimator_resolver.py +0 -0
  99. {dialectical_framework-2.0.3 → dialectical_framework-2.0.4}/src/dialectical_framework/concerns/causality_estimation.py +0 -0
  100. {dialectical_framework-2.0.3 → dialectical_framework-2.0.4}/src/dialectical_framework/concerns/control_statements_check.py +0 -0
  101. {dialectical_framework-2.0.3 → dialectical_framework-2.0.4}/src/dialectical_framework/concerns/create_dx_input.py +0 -0
  102. {dialectical_framework-2.0.3 → dialectical_framework-2.0.4}/src/dialectical_framework/concerns/create_nexus.py +0 -0
  103. {dialectical_framework-2.0.3 → dialectical_framework-2.0.4}/src/dialectical_framework/concerns/decision_coherence_check.py +0 -0
  104. {dialectical_framework-2.0.3 → dialectical_framework-2.0.4}/src/dialectical_framework/concerns/decision_confirmation_check.py +0 -0
  105. {dialectical_framework-2.0.3 → dialectical_framework-2.0.4}/src/dialectical_framework/concerns/diagonal_oppositions_check.py +0 -0
  106. {dialectical_framework-2.0.3 → dialectical_framework-2.0.4}/src/dialectical_framework/concerns/dialectical_context.py +0 -0
  107. {dialectical_framework-2.0.3 → dialectical_framework-2.0.4}/src/dialectical_framework/concerns/discard.py +0 -0
  108. {dialectical_framework-2.0.3 → dialectical_framework-2.0.4}/src/dialectical_framework/concerns/display_text_edit.py +0 -0
  109. {dialectical_framework-2.0.3 → dialectical_framework-2.0.4}/src/dialectical_framework/concerns/expand_nexus.py +0 -0
  110. {dialectical_framework-2.0.3 → dialectical_framework-2.0.4}/src/dialectical_framework/concerns/perspective_combination.py +0 -0
  111. {dialectical_framework-2.0.3 → dialectical_framework-2.0.4}/src/dialectical_framework/concerns/perspective_validation.py +0 -0
  112. {dialectical_framework-2.0.3 → dialectical_framework-2.0.4}/src/dialectical_framework/concerns/positive_ac_re_apex_derivation.py +0 -0
  113. {dialectical_framework-2.0.3 → dialectical_framework-2.0.4}/src/dialectical_framework/concerns/record_decision.py +0 -0
  114. {dialectical_framework-2.0.3 → dialectical_framework-2.0.4}/src/dialectical_framework/concerns/scoring_scales.py +0 -0
  115. {dialectical_framework-2.0.3 → dialectical_framework-2.0.4}/src/dialectical_framework/concerns/source_digest.py +0 -0
  116. {dialectical_framework-2.0.3 → dialectical_framework-2.0.4}/src/dialectical_framework/concerns/statement_classification.py +0 -0
  117. {dialectical_framework-2.0.3 → dialectical_framework-2.0.4}/src/dialectical_framework/concerns/statement_deduplication.py +0 -0
  118. {dialectical_framework-2.0.3 → dialectical_framework-2.0.4}/src/dialectical_framework/concerns/statement_headline.py +0 -0
  119. {dialectical_framework-2.0.3 → dialectical_framework-2.0.4}/src/dialectical_framework/concerns/statement_placement.py +0 -0
  120. {dialectical_framework-2.0.3 → dialectical_framework-2.0.4}/src/dialectical_framework/concerns/synthesis_generation.py +0 -0
  121. {dialectical_framework-2.0.3 → dialectical_framework-2.0.4}/src/dialectical_framework/concerns/tetrad_grounding.py +0 -0
  122. {dialectical_framework-2.0.3 → dialectical_framework-2.0.4}/src/dialectical_framework/concerns/tetrad_sketch.py +0 -0
  123. {dialectical_framework-2.0.3 → dialectical_framework-2.0.4}/src/dialectical_framework/concerns/thesis_extraction.py +0 -0
  124. {dialectical_framework-2.0.3 → dialectical_framework-2.0.4}/src/dialectical_framework/concerns/transformation_audit.py +0 -0
  125. {dialectical_framework-2.0.3 → dialectical_framework-2.0.4}/src/dialectical_framework/dialectical_reasoning.py +0 -0
  126. {dialectical_framework-2.0.3 → dialectical_framework-2.0.4}/src/dialectical_framework/enums/__init__.py +0 -0
  127. {dialectical_framework-2.0.3 → dialectical_framework-2.0.4}/src/dialectical_framework/enums/causality_preset.py +0 -0
  128. {dialectical_framework-2.0.3 → dialectical_framework-2.0.4}/src/dialectical_framework/enums/di.py +0 -0
  129. {dialectical_framework-2.0.3 → dialectical_framework-2.0.4}/src/dialectical_framework/events/__init__.py +0 -0
  130. {dialectical_framework-2.0.3 → dialectical_framework-2.0.4}/src/dialectical_framework/events/graph_event.py +0 -0
  131. {dialectical_framework-2.0.3 → dialectical_framework-2.0.4}/src/dialectical_framework/events/graph_event_bus.py +0 -0
  132. {dialectical_framework-2.0.3 → dialectical_framework-2.0.4}/src/dialectical_framework/events/progress_event.py +0 -0
  133. {dialectical_framework-2.0.3 → dialectical_framework-2.0.4}/src/dialectical_framework/exceptions/__init__.py +0 -0
  134. {dialectical_framework-2.0.3 → dialectical_framework-2.0.4}/src/dialectical_framework/exceptions/node_errors.py +0 -0
  135. {dialectical_framework-2.0.3 → dialectical_framework-2.0.4}/src/dialectical_framework/exceptions/resolver_errors.py +0 -0
  136. {dialectical_framework-2.0.3 → dialectical_framework-2.0.4}/src/dialectical_framework/graph/__init__.py +0 -0
  137. {dialectical_framework-2.0.3 → dialectical_framework-2.0.4}/src/dialectical_framework/graph/composite_input_resolver.py +0 -0
  138. {dialectical_framework-2.0.3 → dialectical_framework-2.0.4}/src/dialectical_framework/graph/dialexity_input_resolver.py +0 -0
  139. {dialectical_framework-2.0.3 → dialectical_framework-2.0.4}/src/dialectical_framework/graph/estimation_manager.py +0 -0
  140. {dialectical_framework-2.0.3 → dialectical_framework-2.0.4}/src/dialectical_framework/graph/mixins/__init__.py +0 -0
  141. {dialectical_framework-2.0.3 → dialectical_framework-2.0.4}/src/dialectical_framework/graph/mixins/incremental_build_mixin.py +0 -0
  142. {dialectical_framework-2.0.3 → dialectical_framework-2.0.4}/src/dialectical_framework/graph/mixins/intent_mixin.py +0 -0
  143. {dialectical_framework-2.0.3 → dialectical_framework-2.0.4}/src/dialectical_framework/graph/mixins/persistable_mixin.py +0 -0
  144. {dialectical_framework-2.0.3 → dialectical_framework-2.0.4}/src/dialectical_framework/graph/nodes/__init__.py +0 -0
  145. {dialectical_framework-2.0.3 → dialectical_framework-2.0.4}/src/dialectical_framework/graph/nodes/assessable_entity.py +0 -0
  146. {dialectical_framework-2.0.3 → dialectical_framework-2.0.4}/src/dialectical_framework/graph/nodes/base_node.py +0 -0
  147. {dialectical_framework-2.0.3 → dialectical_framework-2.0.4}/src/dialectical_framework/graph/nodes/case.py +0 -0
  148. {dialectical_framework-2.0.3 → dialectical_framework-2.0.4}/src/dialectical_framework/graph/nodes/cycle.py +0 -0
  149. {dialectical_framework-2.0.3 → dialectical_framework-2.0.4}/src/dialectical_framework/graph/nodes/decision.py +0 -0
  150. {dialectical_framework-2.0.3 → dialectical_framework-2.0.4}/src/dialectical_framework/graph/nodes/estimation.py +0 -0
  151. {dialectical_framework-2.0.3 → dialectical_framework-2.0.4}/src/dialectical_framework/graph/nodes/ideas.py +0 -0
  152. {dialectical_framework-2.0.3 → dialectical_framework-2.0.4}/src/dialectical_framework/graph/nodes/input.py +0 -0
  153. {dialectical_framework-2.0.3 → dialectical_framework-2.0.4}/src/dialectical_framework/graph/nodes/nexus.py +0 -0
  154. {dialectical_framework-2.0.3 → dialectical_framework-2.0.4}/src/dialectical_framework/graph/nodes/note.py +0 -0
  155. {dialectical_framework-2.0.3 → dialectical_framework-2.0.4}/src/dialectical_framework/graph/nodes/perspective.py +0 -0
  156. {dialectical_framework-2.0.3 → dialectical_framework-2.0.4}/src/dialectical_framework/graph/nodes/polarity.py +0 -0
  157. {dialectical_framework-2.0.3 → dialectical_framework-2.0.4}/src/dialectical_framework/graph/nodes/rationale.py +0 -0
  158. {dialectical_framework-2.0.3 → dialectical_framework-2.0.4}/src/dialectical_framework/graph/nodes/statement.py +0 -0
  159. {dialectical_framework-2.0.3 → dialectical_framework-2.0.4}/src/dialectical_framework/graph/nodes/synthesis.py +0 -0
  160. {dialectical_framework-2.0.3 → dialectical_framework-2.0.4}/src/dialectical_framework/graph/nodes/transformation.py +0 -0
  161. {dialectical_framework-2.0.3 → dialectical_framework-2.0.4}/src/dialectical_framework/graph/nodes/transition.py +0 -0
  162. {dialectical_framework-2.0.3 → dialectical_framework-2.0.4}/src/dialectical_framework/graph/nodes/wheel.py +0 -0
  163. {dialectical_framework-2.0.3 → dialectical_framework-2.0.4}/src/dialectical_framework/graph/relationship_manager.py +0 -0
  164. {dialectical_framework-2.0.3 → dialectical_framework-2.0.4}/src/dialectical_framework/graph/relationships/__init__.py +0 -0
  165. {dialectical_framework-2.0.3 → dialectical_framework-2.0.4}/src/dialectical_framework/graph/relationships/action_reflection_relationship.py +0 -0
  166. {dialectical_framework-2.0.3 → dialectical_framework-2.0.4}/src/dialectical_framework/graph/relationships/belongs_to_cycle_relationship.py +0 -0
  167. {dialectical_framework-2.0.3 → dialectical_framework-2.0.4}/src/dialectical_framework/graph/relationships/belongs_to_nexus_relationship.py +0 -0
  168. {dialectical_framework-2.0.3 → dialectical_framework-2.0.4}/src/dialectical_framework/graph/relationships/changed_to_relationship.py +0 -0
  169. {dialectical_framework-2.0.3 → dialectical_framework-2.0.4}/src/dialectical_framework/graph/relationships/contradiction_of_relationship.py +0 -0
  170. {dialectical_framework-2.0.3 → dialectical_framework-2.0.4}/src/dialectical_framework/graph/relationships/critiques_relationship.py +0 -0
  171. {dialectical_framework-2.0.3 → dialectical_framework-2.0.4}/src/dialectical_framework/graph/relationships/distilled_to_relationship.py +0 -0
  172. {dialectical_framework-2.0.3 → dialectical_framework-2.0.4}/src/dialectical_framework/graph/relationships/estimates_relationship.py +0 -0
  173. {dialectical_framework-2.0.3 → dialectical_framework-2.0.4}/src/dialectical_framework/graph/relationships/explains_relationship.py +0 -0
  174. {dialectical_framework-2.0.3 → dialectical_framework-2.0.4}/src/dialectical_framework/graph/relationships/grounded_in_relationship.py +0 -0
  175. {dialectical_framework-2.0.3 → dialectical_framework-2.0.4}/src/dialectical_framework/graph/relationships/has_input_relationship.py +0 -0
  176. {dialectical_framework-2.0.3 → dialectical_framework-2.0.4}/src/dialectical_framework/graph/relationships/has_statement_relationship.py +0 -0
  177. {dialectical_framework-2.0.3 → dialectical_framework-2.0.4}/src/dialectical_framework/graph/relationships/has_wheel_relationship.py +0 -0
  178. {dialectical_framework-2.0.3 → dialectical_framework-2.0.4}/src/dialectical_framework/graph/relationships/immutable_structure.py +0 -0
  179. {dialectical_framework-2.0.3 → dialectical_framework-2.0.4}/src/dialectical_framework/graph/relationships/is_source_of_relationship.py +0 -0
  180. {dialectical_framework-2.0.3 → dialectical_framework-2.0.4}/src/dialectical_framework/graph/relationships/is_target_of_relationship.py +0 -0
  181. {dialectical_framework-2.0.3 → dialectical_framework-2.0.4}/src/dialectical_framework/graph/relationships/negative_side_of_relationship.py +0 -0
  182. {dialectical_framework-2.0.3 → dialectical_framework-2.0.4}/src/dialectical_framework/graph/relationships/opposite_direction_relationship.py +0 -0
  183. {dialectical_framework-2.0.3 → dialectical_framework-2.0.4}/src/dialectical_framework/graph/relationships/opposite_of_relationship.py +0 -0
  184. {dialectical_framework-2.0.3 → dialectical_framework-2.0.4}/src/dialectical_framework/graph/relationships/polarity_relationship.py +0 -0
  185. {dialectical_framework-2.0.3 → dialectical_framework-2.0.4}/src/dialectical_framework/graph/relationships/positive_side_of_relationship.py +0 -0
  186. {dialectical_framework-2.0.3 → dialectical_framework-2.0.4}/src/dialectical_framework/graph/relationships/provides_relationship.py +0 -0
  187. {dialectical_framework-2.0.3 → dialectical_framework-2.0.4}/src/dialectical_framework/graph/relationships/synthesis_of_relationship.py +0 -0
  188. {dialectical_framework-2.0.3 → dialectical_framework-2.0.4}/src/dialectical_framework/graph/rendering.py +0 -0
  189. {dialectical_framework-2.0.3 → dialectical_framework-2.0.4}/src/dialectical_framework/graph/repositories/__init__.py +0 -0
  190. {dialectical_framework-2.0.3 → dialectical_framework-2.0.4}/src/dialectical_framework/graph/repositories/case_repository.py +0 -0
  191. {dialectical_framework-2.0.3 → dialectical_framework-2.0.4}/src/dialectical_framework/graph/repositories/cycle_repository.py +0 -0
  192. {dialectical_framework-2.0.3 → dialectical_framework-2.0.4}/src/dialectical_framework/graph/repositories/decision_repository.py +0 -0
  193. {dialectical_framework-2.0.3 → dialectical_framework-2.0.4}/src/dialectical_framework/graph/repositories/input_repository.py +0 -0
  194. {dialectical_framework-2.0.3 → dialectical_framework-2.0.4}/src/dialectical_framework/graph/repositories/nexus_repository.py +0 -0
  195. {dialectical_framework-2.0.3 → dialectical_framework-2.0.4}/src/dialectical_framework/graph/repositories/node_repository.py +0 -0
  196. {dialectical_framework-2.0.3 → dialectical_framework-2.0.4}/src/dialectical_framework/graph/repositories/note_repository.py +0 -0
  197. {dialectical_framework-2.0.3 → dialectical_framework-2.0.4}/src/dialectical_framework/graph/repositories/perspective_repository.py +0 -0
  198. {dialectical_framework-2.0.3 → dialectical_framework-2.0.4}/src/dialectical_framework/graph/repositories/polarity_repository.py +0 -0
  199. {dialectical_framework-2.0.3 → dialectical_framework-2.0.4}/src/dialectical_framework/graph/repositories/schema_repository.py +0 -0
  200. {dialectical_framework-2.0.3 → dialectical_framework-2.0.4}/src/dialectical_framework/graph/repositories/statement_repository.py +0 -0
  201. {dialectical_framework-2.0.3 → dialectical_framework-2.0.4}/src/dialectical_framework/graph/repositories/transformation_repository.py +0 -0
  202. {dialectical_framework-2.0.3 → dialectical_framework-2.0.4}/src/dialectical_framework/graph/repositories/wheel_repository.py +0 -0
  203. {dialectical_framework-2.0.3 → dialectical_framework-2.0.4}/src/dialectical_framework/graph/scope_context.py +0 -0
  204. {dialectical_framework-2.0.3 → dialectical_framework-2.0.4}/src/dialectical_framework/graph/verbatim_input_resolver.py +0 -0
  205. {dialectical_framework-2.0.3 → dialectical_framework-2.0.4}/src/dialectical_framework/graph/views.py +0 -0
  206. {dialectical_framework-2.0.3 → dialectical_framework-2.0.4}/src/dialectical_framework/graph/wheel_segment.py +0 -0
  207. {dialectical_framework-2.0.3 → dialectical_framework-2.0.4}/src/dialectical_framework/graph/wheel_segment_polar_pair.py +0 -0
  208. {dialectical_framework-2.0.3 → dialectical_framework-2.0.4}/src/dialectical_framework/protocols/__init__.py +0 -0
  209. {dialectical_framework-2.0.3 → dialectical_framework-2.0.4}/src/dialectical_framework/protocols/has_config.py +0 -0
  210. {dialectical_framework-2.0.3 → dialectical_framework-2.0.4}/src/dialectical_framework/protocols/input_resolver.py +0 -0
  211. {dialectical_framework-2.0.3 → dialectical_framework-2.0.4}/src/dialectical_framework/py.typed +0 -0
  212. {dialectical_framework-2.0.3 → dialectical_framework-2.0.4}/src/dialectical_framework/settings.py +0 -0
  213. {dialectical_framework-2.0.3 → dialectical_framework-2.0.4}/src/dialectical_framework/utils/__init__.py +0 -0
  214. {dialectical_framework-2.0.3 → dialectical_framework-2.0.4}/src/dialectical_framework/utils/async_drain.py +0 -0
  215. {dialectical_framework-2.0.3 → dialectical_framework-2.0.4}/src/dialectical_framework/utils/bedrock_provider.py +0 -0
  216. {dialectical_framework-2.0.3 → dialectical_framework-2.0.4}/src/dialectical_framework/utils/call_census.py +0 -0
  217. {dialectical_framework-2.0.3 → dialectical_framework-2.0.4}/src/dialectical_framework/utils/chunking.py +0 -0
  218. {dialectical_framework-2.0.3 → dialectical_framework-2.0.4}/src/dialectical_framework/utils/concurrency.py +0 -0
  219. {dialectical_framework-2.0.3 → dialectical_framework-2.0.4}/src/dialectical_framework/utils/dc_replace.py +0 -0
  220. {dialectical_framework-2.0.3 → dialectical_framework-2.0.4}/src/dialectical_framework/utils/decompose_probability_uniformly.py +0 -0
  221. {dialectical_framework-2.0.3 → dialectical_framework-2.0.4}/src/dialectical_framework/utils/effect_logger.py +0 -0
  222. {dialectical_framework-2.0.3 → dialectical_framework-2.0.4}/src/dialectical_framework/utils/input_context.py +0 -0
  223. {dialectical_framework-2.0.3 → dialectical_framework-2.0.4}/src/dialectical_framework/utils/order_transitions.py +0 -0
  224. {dialectical_framework-2.0.3 → dialectical_framework-2.0.4}/src/dialectical_framework/utils/progress.py +0 -0
  225. {dialectical_framework-2.0.3 → dialectical_framework-2.0.4}/src/dialectical_framework/utils/retry_accounting.py +0 -0
  226. {dialectical_framework-2.0.3 → dialectical_framework-2.0.4}/src/dialectical_framework/utils/sequence_generation.py +0 -0
  227. {dialectical_framework-2.0.3 → dialectical_framework-2.0.4}/src/dialectical_framework/utils/thinking_compat.py +0 -0
  228. {dialectical_framework-2.0.3 → dialectical_framework-2.0.4}/src/dialectical_framework/utils/use_brain.py +0 -0
  229. {dialectical_framework-2.0.3 → dialectical_framework-2.0.4}/src/dialectical_framework/utils/utterance.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: dialectical-framework
3
- Version: 2.0.3
3
+ Version: 2.0.4
4
4
  Summary: A dialectical framework for augmented intelligence. AI reasoning powered with dialectics supports humans in: system optimization (psychology, engineering, business, politics, etc.); dispute resolution (mediation, conflicts, negotiations, etc.); decision-making (dilemmas, challenging situations, win-win, etc.).
5
5
  License: MIT
6
6
  Keywords: dialectics,dialectical-reasoning,synthesis,thesis-antithesis,ai,artificial-intelligence,llm,reasoning-framework,philosophy,logic,argumentation,conflict-resolution,decision-making,critical-thinking,semantic-graph,mirascope,pydantic,perspectives,polarity-reasoning
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "dialectical-framework"
3
- version = "2.0.3"
3
+ version = "2.0.4"
4
4
  description = "A dialectical framework for augmented intelligence. AI reasoning powered with dialectics supports humans in: system optimization (psychology, engineering, business, politics, etc.); dispute resolution (mediation, conflicts, negotiations, etc.); decision-making (dilemmas, challenging situations, win-win, etc.)."
5
5
  authors = ["Evaldas Taroza <evaldas@dialexity.com>"]
6
6
  readme = "README.md"
@@ -324,12 +324,7 @@ class Consultant:
324
324
  if messages:
325
325
  self._conversation.load_messages(messages)
326
326
  parts = [p for p in (preamble, method_prompt(include_decision)) if p]
327
- # Kept because the view turn's system prompt is this text plus the
328
- # static half of its request (`exploration_view`): appending keeps the
329
- # head a PREFIX of it, so the chat turns' cached prefix is readable by
330
- # the sketch turns instead of each paying for its own.
331
- self._system_prompt = "\n\n".join(parts)
332
- self._conversation.set_system_prompt(self._system_prompt)
327
+ self._conversation.set_system_prompt("\n\n".join(parts))
333
328
 
334
329
  async def chat(self, user_message: str) -> str:
335
330
  result = await self._conversation.submit(ChatResponse, user_message)
@@ -367,8 +362,7 @@ class Consultant:
367
362
  view shows what has been ESTABLISHED, and where `focus` asks for
368
363
  structure not yet worked out ("a perspective for the thesis you
369
364
  named") the turn builds it by the method first
370
- (`concerns/view_sketch.py`: the static instructions ride on the system
371
- prompt, the focus is the turn). What it built is
365
+ (`concerns/view_sketch.py::view_sketch_prompt`). What it built is
372
366
  kept in `messages` as the consultant's own words, so the next turn can
373
367
  be asked about a corner it just drew.
374
368
 
@@ -386,8 +380,7 @@ class Consultant:
386
380
  """
387
381
  from dialectical_framework.concerns.view_sketch import (
388
382
  ViewSketchDto, exploration_view_from_sketch, history_ask,
389
- history_text, perspective_from_sketch, view_sketch_focus,
390
- view_sketch_instructions)
383
+ history_text, perspective_from_sketch, view_sketch_prompt)
391
384
 
392
385
  import asyncio
393
386
  import dataclasses
@@ -397,19 +390,19 @@ class Consultant:
397
390
 
398
391
  level = self._conversation._thinking_kwargs().get("thinking")
399
392
  history = self._conversation._messages
400
- # The request travels in two places, not one. Its static half
401
- # (definitions, rules, the build procedure) goes on the SYSTEM prompt,
402
- # after this head's own, because that is where the provider's cache
403
- # breakpoint sits: as part of the user message it followed the history
404
- # and was re-prefilled at full rate on every draw (~1.2k tokens x N a
405
- # card, measured 2026-10-06). Only the focus — the person's own ask —
406
- # is the turn. Same words, and the history record is untouched
407
- # (`history_ask`, which is why the long request was never kept anyway).
408
- system = (
409
- f"{self._system_prompt}\n\n"
410
- f"{view_sketch_instructions(self._conversation.settings.component_length)}"
411
- )
412
- ask = view_sketch_focus(focus)
393
+ # The WHOLE request is the turn's user message, its "Answer with ONE
394
+ # JSON object" included — by measurement, not habit. For one day
395
+ # (2026-10-06) the static instructions rode on the system prompt so the
396
+ # cache would cover them (~$0.007 a card) and only "What to show: ..."
397
+ # was the turn. First cards did not notice; a RETRY did: its history
398
+ # already holds "Show me: ..." and the previous drawing in PROSE, and with
399
+ # a bare focus as the last user turn the model answered in prose too —
400
+ # 1.75 parse retries a retry card, 4.75 view-turn calls instead of 3,
401
+ # 33 s instead of 20 (`tests/e2e/probe_view_turn_retry_calls.py`, 8
402
+ # utterances; the first app had measured the same 4.6 calls and +17 s).
403
+ # The request->prose pair `history_ask` keeps OUT of the history is the
404
+ # same trap; the long request as the last turn is what holds the format.
405
+ request = view_sketch_prompt(focus, self._conversation.settings.component_length)
413
406
 
414
407
  async def draw() -> ViewSketchDto:
415
408
  # Each draw works on a COPY of the history: the turns run in
@@ -417,8 +410,7 @@ class Consultant:
417
410
  # read. What the view leaves behind is appended once, below.
418
411
  sketch_turn = ConversationFacilitator(format_mode="json", thinking=level)
419
412
  sketch_turn._messages = list(history)
420
- sketch_turn.set_system_prompt(system)
421
- return await sketch_turn.submit(ViewSketchDto, ask)
413
+ return await sketch_turn.submit(ViewSketchDto, request)
422
414
 
423
415
  n = clamp_attempts(attempts)
424
416
  # Fully parallel, deliberately. On a COLD cache all N draws write the
@@ -129,8 +129,13 @@ async def judge_sketches(
129
129
  it picked by position and ties;
130
130
  - one call per draft with both statements in it (the same lean prompt):
131
131
  73% against 90%, the same winner as this judge in 23/40 — stable with
132
- itself, but measuring something else.
133
- A cheaper judge has to be measured against this one on that probe first.
132
+ itself, but measuring something else;
133
+ - THIS prompt with each reasoning field capped at one short sentence
134
+ (the score is written before the reasoning, so the cap looked free):
135
+ output 534 -> 181 tokens a call, but 78% against 90%, scores +0.05, the
136
+ same winner as this judge in 29/40. The reasoning is not dead weight.
137
+ A cheaper judge has to be measured against this one on that probe first;
138
+ the owner closed the cost question at this point (2026-10-06).
134
139
  """
135
140
 
136
141
  async def one(tension: Any) -> Optional[SketchVerdict]:
@@ -248,7 +248,17 @@ class ReSideCompletionDto(BaseModel):
248
248
  description="Proactiveness category for Re+"
249
249
  )
250
250
 
251
- # Re- fields
251
+ # Re- fields. The weak position of the staged generator, measured
252
+ # 2026-10-06 (`tests/e2e/probe_staged_endpoints.py`, 102 Transformations on
253
+ # 17 one-tension wheels, read with the theory-faithful `TransitionVerdict`):
254
+ # Re- valid 49% against Ac- 70%, and it is the LANDING that fails (59%
255
+ # land in T-; 27% valid on T->A edges). The prompt asked for "the
256
+ # reflection without the action", which the writer read as "keep watching,
257
+ # do nothing" — and wherever A is the passive pole, doing nothing is A's
258
+ # trap, not T's. Two `re_minus_from` / `re_minus_into` fields ahead of these
259
+ # (the one-shot's fix) moved it within noise and were reverted; the
260
+ # landing is now named in `_generate_re_side`'s Re- instruction instead.
261
+ # See docs/dev-notes/one-shot-transformation.md.
252
262
  re_minus_headline: str = Field(description="Re- headline (component length)")
253
263
  re_minus_statement: str = Field(description="Re- statement (fuller than the headline)")
254
264
  re_minus_explanation: str = Field(
@@ -641,7 +651,8 @@ Given their action, what reflection does it trigger that leads to growth?
641
651
 
642
652
  What happens when their action IS taken in, but nothing you do grounds that reflection?
643
653
  - What Re+ ITSELF degenerates into when Ac+ is absent — an overextension of the reflection, not the absence of one
644
- - Path: the Reflection Perspective's positive regresses you toward your negative
654
+ - Where it LANDS is what makes it Re-: it ends in the A- line of <reflection_perspective> — YOUR OWN trap. It starts from that block's T+ line (the other side's strength); you need not name the start, but the landing must be your trap
655
+ - The common miss: "keep watching and do nothing". When the other side is the passive one, doing nothing just leaves THEIR trap in place (the block's T- line) — that is not Re-. Re- is your reflecting, overdone, carrying YOU into your own trap
645
656
  - NOT the same failure as Ac-: Ac- is your action left unreflected, Re- is your reflection left unacted
646
657
  - Your Ac+ must CONTRADICT Re- (your positive action opposes this regression)
647
658
  - Usually lower insight than Re+
@@ -32,9 +32,10 @@ state, scored 11/17 on the third-trap auditor where a call that skipped the
32
32
  poles and stated the theory loosely scored 0/17 (`one-shot-transformation.md`,
33
33
  arms 1 and 2; the auditor is saturated by the either/or instruction, so read
34
34
  that as compliance). The endpoint half of the minus definitions was added
35
- afterwards and, stated in text alone, did NOT land: the first app measured it
36
- at 14-30% and `tests/e2e/probe_transformation_sketch.py` at 22% / 18% (Ac- /
37
- Re-). What lands the ends is the DTO, not the sentence: the writer names where
35
+ afterwards and, stated in text alone, did NOT land: valid Ac- / Re- in 30% /
36
+ 26% of drafts by the theory-faithful auditor (`probe_transition_rescore.py`;
37
+ the app's stricter auditor read 14-30%). What lands the ends is the DTO, not
38
+ the sentence: the writer names where
38
39
  each minus line starts and lands before writing it (`TransformationSketchDto`
39
40
  says why and by how much). That probe is the gate for any change to the
40
41
  definition text or those fields. Arm 1 is not evidence against the endpoints:
@@ -143,15 +144,25 @@ class TransformationSketchDto(BaseModel):
143
144
 
144
145
  `ac_minus_from` / `ac_minus_into` (and the Re- pair) come BEFORE their
145
146
  line on purpose, and they are the measured fix, not decoration. Stating the
146
- ends in the definition does not make the writer use them: the shipped text
147
- put Ac- on T+ -> A- in 22% of drafts and Re- on A+ -> T- in 18%, because
148
- "the action without the reflection" reads like the tetrad's own "T+ without
149
- A+ yields T-" and the line lands on T's OWN trap. Making the writer name
150
- the start and the landing first moved both to 60% / 58% (+38 / +40, both
151
- clearing noise), with the makeup reads and S- unchanged within noise
152
- (`tests/e2e/probe_transformation_sketch.py`, 25 tetrads x 2 reps,
153
- 2026-10-06). A host may ignore the four scaffold fields; their job is done
154
- by the time the line is written.
147
+ ends in the definition does not make the writer use them: with the text
148
+ alone a valid Ac- (lands in A-, is the action degenerated, does not start
149
+ from A+) came back in 30% of drafts and a valid Re- in 26%, because "the
150
+ action without the reflection" reads like the tetrad's own "T+ without A+
151
+ yields T-" and the line lands on T's OWN trap. Making the writer name the
152
+ start and the landing first moved them to 56% / 62% (paired +26 / +36, both
153
+ clearing noise), S- unchanged within noise (`tests/e2e/probe_transformation_sketch.py`,
154
+ 25 tetrads x 2 reps, 2026-10-06, re-read by `probe_transition_rescore.py`
155
+ with the auditor three blind theory reviewers agreed with on 51/52 clear
156
+ cases; the app's stricter auditor had read 22/18% -> 60/58%). A host may
157
+ ignore the four scaffold fields; their job is done by the time the line is
158
+ written.
159
+
160
+ The price to watch, OPEN: the ends rose and the makeup reads dipped
161
+ ("Re- is the reflection itself" 94% -> 88% here, within noise; the first
162
+ app's pill measured 98% -> 80% in its own voice). A line written to land
163
+ on A+ -> T- can stop reading as the reflection overdone. If a host's
164
+ makeup read keeps falling, that is a trade to measure on this probe, not
165
+ a reason to drop the fields by eye.
155
166
 
156
167
  Hosts SUBCLASS it to add their own person-facing fields after these, so
157
168
  the derivation and the words that rest on it stay one call: the first
@@ -270,6 +281,13 @@ class TransformationSketch(ReasonableConcern[TransformationSketchDto], SettingsA
270
281
  class: it subclasses `TransformationSketchDto` and embeds
271
282
  `TRANSFORMATION_BUILD_PROCEDURE` in its own system prompt, so the theory
272
283
  is still the framework's and the voice is the host's.
284
+
285
+ A host that writes person-facing text from the result in a SECOND call
286
+ must tell that call the lines are meaning only, not wording to reuse:
287
+ otherwise it echoes them, and the lines are written to the theory's
288
+ shape, not to a person. Measured by the first app on its card text
289
+ (19–21 points lost until its writer said so; the record is in that app's
290
+ repo).
273
291
  """
274
292
 
275
293
  def __init__(self) -> None:
@@ -186,22 +186,8 @@ For each pair:
186
186
  3. Re-read both aspects against step 1 for two distinct failures. (a) Wrong parent: if one is really the OTHER parent developed, rewrite it from its own parent. (b) {PLUS_RESTATEMENT_CHECK}"""
187
187
 
188
188
 
189
- def view_sketch_focus(focus: Optional[str]) -> str:
190
- """The one per-call line of the request: what this draw is to show.
191
-
192
- Split from the instructions so the Consultant can send this alone as the
193
- turn's user message and carry the static half on the system prompt, where
194
- the provider's cache breakpoint already sits (`view_sketch_instructions`).
195
- """
196
- return (
197
- f"What to show: {focus}"
198
- if focus and focus.strip()
199
- else "What to show: the tensions this conversation has worked out so far."
200
- )
201
-
202
-
203
- def view_sketch_instructions(max_words: int) -> str:
204
- """The STATIC half of the view turn's request — everything but the focus.
189
+ def view_sketch_prompt(focus: Optional[str], max_words: int) -> str:
190
+ """The structured turn's request, over the consultant's own conversation.
205
191
 
206
192
  Two instructions in one, because the ask is one or the other and the model
207
193
  knows which: render what is ESTABLISHED (a tension already named and taken
@@ -217,20 +203,15 @@ def view_sketch_instructions(max_words: int) -> str:
217
203
  (docs/dev-notes/antithesis-selection.md, 2026-10-02). The thesis is asked
218
204
  for as a STANCE (`THESIS_IS_A_STANCE`): on 20 questions the turn echoed the
219
205
  question as T in 6 before the ask was here (the alsotrue app repo, docs/lab-notes-entry.md).
220
-
221
- Static because every word of it is fixed per deployment (`max_words` comes
222
- from settings), which is what lets the Consultant append it to its system
223
- prompt: as a user message it sat after the history and was re-prefilled at
224
- full rate on every draw — ~1.2k tokens x N per card, measured 2026-10-06.
225
- On the system prompt it rides inside the cached prefix. This is a cache
226
- placement, not a content change; the one thing it does move is WHERE the
227
- focus line sits, from just under the opening paragraph to the end of the
228
- turn (`tests/e2e/probe_view_turn_ask.py` is the instrument if that is ever
229
- suspected of mattering).
230
206
  """
207
+ focus_line = (
208
+ f"What to show: {focus}\n\n"
209
+ if focus and focus.strip()
210
+ else "What to show: the tensions this conversation has worked out so far.\n\n"
211
+ )
231
212
  return f"""Draw the structure of this conversation as dialectical tetrads. Answer with ONE JSON object in the requested schema and nothing else — no prose. Earlier drawings in this conversation are recorded in prose; that is their record, not the format of this answer.
232
213
 
233
- {ASPECT_DEFINITIONS}
214
+ {focus_line}{ASPECT_DEFINITIONS}
234
215
 
235
216
  Rules for what goes in the view:
236
217
  - Show what this conversation has ESTABLISHED: a tension you named and the person took up is drawn as you both have it, in their terms. Do not re-derive what is already on the table.
@@ -247,17 +228,6 @@ Rules for what goes in the view:
247
228
  Write every position in the person's own terms, {max_words} words or fewer each."""
248
229
 
249
230
 
250
- def view_sketch_prompt(focus: Optional[str], max_words: int) -> str:
251
- """The whole request as ONE user message: the instructions and the focus.
252
-
253
- The shape for a caller with no system prompt of its own to append to — the
254
- probes and the harness. The Consultant sends the two halves apart
255
- (`view_sketch_instructions` on the system prompt, `view_sketch_focus` as
256
- the turn), which is the same words in a different place.
257
- """
258
- return f"{view_sketch_instructions(max_words)}\n\n{view_sketch_focus(focus)}"
259
-
260
-
261
231
  # --- The view shaping (pure) ----------------------------------------------
262
232
 
263
233
 
@@ -104,9 +104,42 @@ def build_edge_context(source_segment: WheelSegment, target_segment: WheelSegmen
104
104
  if target_t_minus:
105
105
  parts.append(f"A-: {target_t_minus[0].prompt_text}")
106
106
 
107
+ if _crosses_tensions(source_segment, target_segment):
108
+ parts.append(CROSS_TENSION_NOTE)
109
+
107
110
  return "\n".join(parts)
108
111
 
109
112
 
113
+ #: Said whenever the two segments belong to DIFFERENT tensions — every edge of a
114
+ #: wheel with two or more tensions. The labels above are relative ("A" is just the
115
+ #: target), and at N >= 2 the writer read that "A" as T's own antithesis: on ten
116
+ #: two-tension wheels a third of the staged Ac+ (28% / 35%, two generations) turned
117
+ #: T's trap into T's OWN tension's strength instead of this target's, while a
118
+ #: one-shot prompt carrying this sentence did so in 4% / 18%
119
+ #: (`tests/e2e/probe_n2_one_shot_edge.py`, 2026-10-06). On a one-tension wheel the
120
+ #: target IS the other side of T's tension, so nothing is said there.
121
+ CROSS_TENSION_NOTE = (
122
+ "(T and A above come from TWO DIFFERENT tensions: do not read A as the other "
123
+ "side of T's own tension — a move that ends in T's own opposite has not "
124
+ "reached this A.)"
125
+ )
126
+
127
+
128
+ def _crosses_tensions(source_segment: WheelSegment, target_segment: WheelSegment) -> bool:
129
+ """True when the target is NOT the other side of the source's own tension.
130
+
131
+ By the statements, not the perspectives: two readings of one polarity are
132
+ different perspectives over the SAME tension, and their edge is not a
133
+ crossing. Unknown (a missing statement) reads as not crossing — the note is
134
+ an aid, and saying nothing is the old behaviour.
135
+ """
136
+ own_other = source_segment.opposite.t.get()
137
+ target_t = target_segment.t.get()
138
+ if not own_other or not target_t:
139
+ return False
140
+ return own_other[0].hash != target_t[0].hash
141
+
142
+
110
143
  def build_coarser_context(parents: list[CoarserTransformation]) -> Optional[str]:
111
144
  """
112
145
  Build hierarchical refinement context from coarser parent Transformations.