coltrace 0.1.0.dev10__tar.gz → 0.1.0.dev11__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 (151) hide show
  1. {coltrace-0.1.0.dev10/src/coltrace.egg-info → coltrace-0.1.0.dev11}/PKG-INFO +2 -2
  2. {coltrace-0.1.0.dev10 → coltrace-0.1.0.dev11}/README.md +1 -1
  3. {coltrace-0.1.0.dev10 → coltrace-0.1.0.dev11}/docs/backlog.md +2 -0
  4. {coltrace-0.1.0.dev10 → coltrace-0.1.0.dev11}/docs/compatibility-checkpoint.md +40 -1
  5. {coltrace-0.1.0.dev10 → coltrace-0.1.0.dev11}/docs/decisions.md +3 -0
  6. {coltrace-0.1.0.dev10 → coltrace-0.1.0.dev11}/docs/lineage-json.md +14 -0
  7. {coltrace-0.1.0.dev10 → coltrace-0.1.0.dev11}/docs/supported-patterns.md +17 -4
  8. {coltrace-0.1.0.dev10 → coltrace-0.1.0.dev11}/docs/troubleshooting.md +20 -4
  9. {coltrace-0.1.0.dev10 → coltrace-0.1.0.dev11}/examples/notebook_cell.py +298 -195
  10. {coltrace-0.1.0.dev10 → coltrace-0.1.0.dev11}/pyproject.toml +1 -1
  11. {coltrace-0.1.0.dev10 → coltrace-0.1.0.dev11}/src/coltrace/__init__.py +1 -1
  12. {coltrace-0.1.0.dev10 → coltrace-0.1.0.dev11}/src/coltrace/analysis.py +16 -1
  13. {coltrace-0.1.0.dev10 → coltrace-0.1.0.dev11}/src/coltrace/cli.py +31 -22
  14. {coltrace-0.1.0.dev10 → coltrace-0.1.0.dev11}/src/coltrace/graph.py +178 -9
  15. {coltrace-0.1.0.dev10 → coltrace-0.1.0.dev11}/src/coltrace/journey.py +163 -2
  16. {coltrace-0.1.0.dev10 → coltrace-0.1.0.dev11}/src/coltrace/lineage_models.py +1 -1
  17. {coltrace-0.1.0.dev10 → coltrace-0.1.0.dev11}/src/coltrace/models.py +1 -1
  18. {coltrace-0.1.0.dev10 → coltrace-0.1.0.dev11}/src/coltrace/templates/graph.html +469 -444
  19. {coltrace-0.1.0.dev10 → coltrace-0.1.0.dev11/src/coltrace.egg-info}/PKG-INFO +2 -2
  20. {coltrace-0.1.0.dev10 → coltrace-0.1.0.dev11}/src/coltrace.egg-info/SOURCES.txt +1 -0
  21. coltrace-0.1.0.dev11/tests/integration/test_journey_reach.py +180 -0
  22. {coltrace-0.1.0.dev10 → coltrace-0.1.0.dev11}/LICENSE +0 -0
  23. {coltrace-0.1.0.dev10 → coltrace-0.1.0.dev11}/MANIFEST.in +0 -0
  24. {coltrace-0.1.0.dev10 → coltrace-0.1.0.dev11}/docs/accuracy.md +0 -0
  25. {coltrace-0.1.0.dev10 → coltrace-0.1.0.dev11}/docs/architecture.md +0 -0
  26. {coltrace-0.1.0.dev10 → coltrace-0.1.0.dev11}/docs/column-history.md +0 -0
  27. {coltrace-0.1.0.dev10 → coltrace-0.1.0.dev11}/docs/column-journey-checkpoint.md +0 -0
  28. {coltrace-0.1.0.dev10 → coltrace-0.1.0.dev11}/docs/database-patterns.md +0 -0
  29. {coltrace-0.1.0.dev10 → coltrace-0.1.0.dev11}/docs/database-sources.md +0 -0
  30. {coltrace-0.1.0.dev10 → coltrace-0.1.0.dev11}/docs/discovery-json.md +0 -0
  31. {coltrace-0.1.0.dev10 → coltrace-0.1.0.dev11}/docs/extraction-architectures.md +0 -0
  32. {coltrace-0.1.0.dev10 → coltrace-0.1.0.dev11}/docs/graph-workspace-checkpoint.md +0 -0
  33. {coltrace-0.1.0.dev10 → coltrace-0.1.0.dev11}/docs/history-checkpoint.md +0 -0
  34. {coltrace-0.1.0.dev10 → coltrace-0.1.0.dev11}/docs/mvp-checkpoint.md +0 -0
  35. {coltrace-0.1.0.dev10 → coltrace-0.1.0.dev11}/docs/nlp-checkpoint.md +0 -0
  36. {coltrace-0.1.0.dev10 → coltrace-0.1.0.dev11}/docs/other-column-checkpoint.md +0 -0
  37. {coltrace-0.1.0.dev10 → coltrace-0.1.0.dev11}/docs/pandas-sources-proposal.md +0 -0
  38. {coltrace-0.1.0.dev10 → coltrace-0.1.0.dev11}/docs/phase-1.md +0 -0
  39. {coltrace-0.1.0.dev10 → coltrace-0.1.0.dev11}/docs/read-capture.md +0 -0
  40. {coltrace-0.1.0.dev10 → coltrace-0.1.0.dev11}/docs/source-checkpoint.md +0 -0
  41. {coltrace-0.1.0.dev10 → coltrace-0.1.0.dev11}/examples/database_pipeline/README.md +0 -0
  42. {coltrace-0.1.0.dev10 → coltrace-0.1.0.dev11}/examples/database_pipeline/build_query.py +0 -0
  43. {coltrace-0.1.0.dev10 → coltrace-0.1.0.dev11}/examples/database_pipeline/pipeline.py +0 -0
  44. {coltrace-0.1.0.dev10 → coltrace-0.1.0.dev11}/examples/database_pipeline/pyproject.toml +0 -0
  45. {coltrace-0.1.0.dev10 → coltrace-0.1.0.dev11}/examples/databricks_project/README.md +0 -0
  46. {coltrace-0.1.0.dev10 → coltrace-0.1.0.dev11}/examples/databricks_project/main_orchestrator.py +0 -0
  47. {coltrace-0.1.0.dev10 → coltrace-0.1.0.dev11}/examples/databricks_project/pipeline_a/__init__.py +0 -0
  48. {coltrace-0.1.0.dev10 → coltrace-0.1.0.dev11}/examples/databricks_project/pipeline_a/extract/__init__.py +0 -0
  49. {coltrace-0.1.0.dev10 → coltrace-0.1.0.dev11}/examples/databricks_project/pipeline_a/extract/primary_extract.py +0 -0
  50. {coltrace-0.1.0.dev10 → coltrace-0.1.0.dev11}/examples/databricks_project/pipeline_a/extract/quality_extract.py +0 -0
  51. {coltrace-0.1.0.dev10 → coltrace-0.1.0.dev11}/examples/databricks_project/pipeline_a/main_orchestrator.py +0 -0
  52. {coltrace-0.1.0.dev10 → coltrace-0.1.0.dev11}/examples/databricks_project/pipeline_a/publish/__init__.py +0 -0
  53. {coltrace-0.1.0.dev10 → coltrace-0.1.0.dev11}/examples/databricks_project/pipeline_a/publish/serialize_webapp.py +0 -0
  54. {coltrace-0.1.0.dev10 → coltrace-0.1.0.dev11}/examples/databricks_project/pipeline_a/transform/__init__.py +0 -0
  55. {coltrace-0.1.0.dev10 → coltrace-0.1.0.dev11}/examples/databricks_project/pipeline_a/transform/combine_sources.py +0 -0
  56. {coltrace-0.1.0.dev10 → coltrace-0.1.0.dev11}/examples/databricks_project/pipeline_a/transform/priority_rank.py +0 -0
  57. {coltrace-0.1.0.dev10 → coltrace-0.1.0.dev11}/examples/databricks_project/shared/__init__.py +0 -0
  58. {coltrace-0.1.0.dev10 → coltrace-0.1.0.dev11}/examples/databricks_project/shared/config.py +0 -0
  59. {coltrace-0.1.0.dev10 → coltrace-0.1.0.dev11}/examples/databricks_project/shared/token_tracker.py +0 -0
  60. {coltrace-0.1.0.dev10 → coltrace-0.1.0.dev11}/examples/databricks_project/shared/topic_changes_extract.py +0 -0
  61. {coltrace-0.1.0.dev10 → coltrace-0.1.0.dev11}/examples/databricks_project/shared/warehouse.py +0 -0
  62. {coltrace-0.1.0.dev10 → coltrace-0.1.0.dev11}/examples/pricing_pipeline/extract/prices.py +0 -0
  63. {coltrace-0.1.0.dev10 → coltrace-0.1.0.dev11}/examples/pricing_pipeline/features/pricing.py +0 -0
  64. {coltrace-0.1.0.dev10 → coltrace-0.1.0.dev11}/examples/pricing_pipeline/pipeline.py +0 -0
  65. {coltrace-0.1.0.dev10 → coltrace-0.1.0.dev11}/examples/pricing_pipeline/transform/pricing.py +0 -0
  66. {coltrace-0.1.0.dev10 → coltrace-0.1.0.dev11}/examples/read_capture/README.md +0 -0
  67. {coltrace-0.1.0.dev10 → coltrace-0.1.0.dev11}/examples/read_capture/project/input.csv +0 -0
  68. {coltrace-0.1.0.dev10 → coltrace-0.1.0.dev11}/examples/read_capture/project/pipeline.py +0 -0
  69. {coltrace-0.1.0.dev10 → coltrace-0.1.0.dev11}/examples/read_capture/run_capture.py +0 -0
  70. {coltrace-0.1.0.dev10 → coltrace-0.1.0.dev11}/examples/robustness_pipeline/README.md +0 -0
  71. {coltrace-0.1.0.dev10 → coltrace-0.1.0.dev11}/examples/robustness_pipeline/extract.py +0 -0
  72. {coltrace-0.1.0.dev10 → coltrace-0.1.0.dev11}/examples/robustness_pipeline/pipeline.py +0 -0
  73. {coltrace-0.1.0.dev10 → coltrace-0.1.0.dev11}/examples/robustness_pipeline/transform.py +0 -0
  74. {coltrace-0.1.0.dev10 → coltrace-0.1.0.dev11}/examples/sample_pipeline/prices.py +0 -0
  75. {coltrace-0.1.0.dev10 → coltrace-0.1.0.dev11}/examples/text_pipeline/README.md +0 -0
  76. {coltrace-0.1.0.dev10 → coltrace-0.1.0.dev11}/examples/text_pipeline/pipeline.py +0 -0
  77. {coltrace-0.1.0.dev10 → coltrace-0.1.0.dev11}/examples/text_pipeline/processing.py +0 -0
  78. {coltrace-0.1.0.dev10 → coltrace-0.1.0.dev11}/examples/text_pipeline/readers.py +0 -0
  79. {coltrace-0.1.0.dev10 → coltrace-0.1.0.dev11}/examples/text_pipeline/text.py +0 -0
  80. {coltrace-0.1.0.dev10 → coltrace-0.1.0.dev11}/setup.cfg +0 -0
  81. {coltrace-0.1.0.dev10 → coltrace-0.1.0.dev11}/src/coltrace/__main__.py +0 -0
  82. {coltrace-0.1.0.dev10 → coltrace-0.1.0.dev11}/src/coltrace/callbacks.py +0 -0
  83. {coltrace-0.1.0.dev10 → coltrace-0.1.0.dev11}/src/coltrace/capture.py +0 -0
  84. {coltrace-0.1.0.dev10 → coltrace-0.1.0.dev11}/src/coltrace/collector.py +0 -0
  85. {coltrace-0.1.0.dev10 → coltrace-0.1.0.dev11}/src/coltrace/compatibility.py +0 -0
  86. {coltrace-0.1.0.dev10 → coltrace-0.1.0.dev11}/src/coltrace/exporters.py +0 -0
  87. {coltrace-0.1.0.dev10 → coltrace-0.1.0.dev11}/src/coltrace/history.py +0 -0
  88. {coltrace-0.1.0.dev10 → coltrace-0.1.0.dev11}/src/coltrace/nosql_sources.py +0 -0
  89. {coltrace-0.1.0.dev10 → coltrace-0.1.0.dev11}/src/coltrace/notebooks.py +0 -0
  90. {coltrace-0.1.0.dev10 → coltrace-0.1.0.dev11}/src/coltrace/pandas_api.py +0 -0
  91. {coltrace-0.1.0.dev10 → coltrace-0.1.0.dev11}/src/coltrace/py.typed +0 -0
  92. {coltrace-0.1.0.dev10 → coltrace-0.1.0.dev11}/src/coltrace/scanner.py +0 -0
  93. {coltrace-0.1.0.dev10 → coltrace-0.1.0.dev11}/src/coltrace/source_models.py +0 -0
  94. {coltrace-0.1.0.dev10 → coltrace-0.1.0.dev11}/src/coltrace/source_readers.py +0 -0
  95. {coltrace-0.1.0.dev10 → coltrace-0.1.0.dev11}/src/coltrace/sql_sources.py +0 -0
  96. {coltrace-0.1.0.dev10 → coltrace-0.1.0.dev11}/src/coltrace/visual_layout.py +0 -0
  97. {coltrace-0.1.0.dev10 → coltrace-0.1.0.dev11}/src/coltrace.egg-info/dependency_links.txt +0 -0
  98. {coltrace-0.1.0.dev10 → coltrace-0.1.0.dev11}/src/coltrace.egg-info/entry_points.txt +0 -0
  99. {coltrace-0.1.0.dev10 → coltrace-0.1.0.dev11}/src/coltrace.egg-info/requires.txt +0 -0
  100. {coltrace-0.1.0.dev10 → coltrace-0.1.0.dev11}/src/coltrace.egg-info/top_level.txt +0 -0
  101. {coltrace-0.1.0.dev10 → coltrace-0.1.0.dev11}/tests/fixtures/sample_pipeline/extract/prices.py +0 -0
  102. {coltrace-0.1.0.dev10 → coltrace-0.1.0.dev11}/tests/fixtures/sample_pipeline/features/pricing.py +0 -0
  103. {coltrace-0.1.0.dev10 → coltrace-0.1.0.dev11}/tests/fixtures/sample_pipeline/pipeline.py +0 -0
  104. {coltrace-0.1.0.dev10 → coltrace-0.1.0.dev11}/tests/fixtures/sample_pipeline/transform/pricing.py +0 -0
  105. {coltrace-0.1.0.dev10 → coltrace-0.1.0.dev11}/tests/integration/test_annotation_effects.py +0 -0
  106. {coltrace-0.1.0.dev10 → coltrace-0.1.0.dev11}/tests/integration/test_callback_roles.py +0 -0
  107. {coltrace-0.1.0.dev10 → coltrace-0.1.0.dev11}/tests/integration/test_capture_workflow.py +0 -0
  108. {coltrace-0.1.0.dev10 → coltrace-0.1.0.dev11}/tests/integration/test_cli.py +0 -0
  109. {coltrace-0.1.0.dev10 → coltrace-0.1.0.dev11}/tests/integration/test_column_story.py +0 -0
  110. {coltrace-0.1.0.dev10 → coltrace-0.1.0.dev11}/tests/integration/test_compatibility_cli.py +0 -0
  111. {coltrace-0.1.0.dev10 → coltrace-0.1.0.dev11}/tests/integration/test_conditional_flow.py +0 -0
  112. {coltrace-0.1.0.dev10 → coltrace-0.1.0.dev11}/tests/integration/test_database_sources.py +0 -0
  113. {coltrace-0.1.0.dev10 → coltrace-0.1.0.dev11}/tests/integration/test_databricks_example.py +0 -0
  114. {coltrace-0.1.0.dev10 → coltrace-0.1.0.dev11}/tests/integration/test_extraction_architectures.py +0 -0
  115. {coltrace-0.1.0.dev10 → coltrace-0.1.0.dev11}/tests/integration/test_journey_boundaries.py +0 -0
  116. {coltrace-0.1.0.dev10 → coltrace-0.1.0.dev11}/tests/integration/test_lineage_acceptance.py +0 -0
  117. {coltrace-0.1.0.dev10 → coltrace-0.1.0.dev11}/tests/integration/test_nosql_extraction.py +0 -0
  118. {coltrace-0.1.0.dev10 → coltrace-0.1.0.dev11}/tests/integration/test_notebook_reporting.py +0 -0
  119. {coltrace-0.1.0.dev10 → coltrace-0.1.0.dev11}/tests/integration/test_other_column_stories.py +0 -0
  120. {coltrace-0.1.0.dev10 → coltrace-0.1.0.dev11}/tests/integration/test_pandas_boundaries.py +0 -0
  121. {coltrace-0.1.0.dev10 → coltrace-0.1.0.dev11}/tests/integration/test_pandas_observation.py +0 -0
  122. {coltrace-0.1.0.dev10 → coltrace-0.1.0.dev11}/tests/integration/test_production_patterns.py +0 -0
  123. {coltrace-0.1.0.dev10 → coltrace-0.1.0.dev11}/tests/integration/test_project_compatibility.py +0 -0
  124. {coltrace-0.1.0.dev10 → coltrace-0.1.0.dev11}/tests/integration/test_public_project_patterns.py +0 -0
  125. {coltrace-0.1.0.dev10 → coltrace-0.1.0.dev11}/tests/integration/test_reader_inventory.py +0 -0
  126. {coltrace-0.1.0.dev10 → coltrace-0.1.0.dev11}/tests/integration/test_resolution_boundaries.py +0 -0
  127. {coltrace-0.1.0.dev10 → coltrace-0.1.0.dev11}/tests/integration/test_result_containers.py +0 -0
  128. {coltrace-0.1.0.dev10 → coltrace-0.1.0.dev11}/tests/integration/test_scan_project.py +0 -0
  129. {coltrace-0.1.0.dev10 → coltrace-0.1.0.dev11}/tests/integration/test_source_config.py +0 -0
  130. {coltrace-0.1.0.dev10 → coltrace-0.1.0.dev11}/tests/integration/test_source_precision.py +0 -0
  131. {coltrace-0.1.0.dev10 → coltrace-0.1.0.dev11}/tests/integration/test_sql_reader_boundaries.py +0 -0
  132. {coltrace-0.1.0.dev10 → coltrace-0.1.0.dev11}/tests/integration/test_sql_templates.py +0 -0
  133. {coltrace-0.1.0.dev10 → coltrace-0.1.0.dev11}/tests/integration/test_text_pipeline.py +0 -0
  134. {coltrace-0.1.0.dev10 → coltrace-0.1.0.dev11}/tests/integration/test_unified_pipeline_shapes.py +0 -0
  135. {coltrace-0.1.0.dev10 → coltrace-0.1.0.dev11}/tests/unit/test_analysis.py +0 -0
  136. {coltrace-0.1.0.dev10 → coltrace-0.1.0.dev11}/tests/unit/test_callbacks.py +0 -0
  137. {coltrace-0.1.0.dev10 → coltrace-0.1.0.dev11}/tests/unit/test_collector.py +0 -0
  138. {coltrace-0.1.0.dev10 → coltrace-0.1.0.dev11}/tests/unit/test_compatibility.py +0 -0
  139. {coltrace-0.1.0.dev10 → coltrace-0.1.0.dev11}/tests/unit/test_exporters.py +0 -0
  140. {coltrace-0.1.0.dev10 → coltrace-0.1.0.dev11}/tests/unit/test_graph.py +0 -0
  141. {coltrace-0.1.0.dev10 → coltrace-0.1.0.dev11}/tests/unit/test_graph_workspace.py +0 -0
  142. {coltrace-0.1.0.dev10 → coltrace-0.1.0.dev11}/tests/unit/test_history.py +0 -0
  143. {coltrace-0.1.0.dev10 → coltrace-0.1.0.dev11}/tests/unit/test_journey.py +0 -0
  144. {coltrace-0.1.0.dev10 → coltrace-0.1.0.dev11}/tests/unit/test_nosql_sources.py +0 -0
  145. {coltrace-0.1.0.dev10 → coltrace-0.1.0.dev11}/tests/unit/test_notebooks.py +0 -0
  146. {coltrace-0.1.0.dev10 → coltrace-0.1.0.dev11}/tests/unit/test_read_capture.py +0 -0
  147. {coltrace-0.1.0.dev10 → coltrace-0.1.0.dev11}/tests/unit/test_scanner.py +0 -0
  148. {coltrace-0.1.0.dev10 → coltrace-0.1.0.dev11}/tests/unit/test_source_models.py +0 -0
  149. {coltrace-0.1.0.dev10 → coltrace-0.1.0.dev11}/tests/unit/test_source_presentation.py +0 -0
  150. {coltrace-0.1.0.dev10 → coltrace-0.1.0.dev11}/tests/unit/test_sql_sources.py +0 -0
  151. {coltrace-0.1.0.dev10 → coltrace-0.1.0.dev11}/tests/unit/test_visual_layout.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: coltrace
3
- Version: 0.1.0.dev10
3
+ Version: 0.1.0.dev11
4
4
  Summary: Static Pandas column lineage, impact analysis, and local dependency graphs
5
5
  Author: Cristiano Diniz
6
6
  License-Expression: MIT
@@ -32,7 +32,7 @@ column versions across direct function calls. Static scanning never imports or
32
32
  executes the project or reads its input data. Optional read capture observes
33
33
  column labels while you explicitly execute your own pipeline.
34
34
 
35
- **Development preview: `0.1.0.dev10`.** The supported subset is deliberately small.
35
+ **Development preview: `0.1.0.dev11`.** The supported subset is deliberately small.
36
36
  Unsupported operations produce diagnostics and may interrupt lineage. A graph
37
37
  with no edge is not proof that a dependency does not exist.
38
38
 
@@ -6,7 +6,7 @@ column versions across direct function calls. Static scanning never imports or
6
6
  executes the project or reads its input data. Optional read capture observes
7
7
  column labels while you explicitly execute your own pipeline.
8
8
 
9
- **Development preview: `0.1.0.dev10`.** The supported subset is deliberately small.
9
+ **Development preview: `0.1.0.dev11`.** The supported subset is deliberately small.
10
10
  Unsupported operations produce diagnostics and may interrupt lineage. A graph
11
11
  with no edge is not proof that a dependency does not exist.
12
12
 
@@ -84,6 +84,8 @@ not a capability of the published release.
84
84
  | CT-118 | Executor fan-out (`ThreadPoolExecutor.submit`, `as_completed`, `map`) and `tqdm` wrappers | Proposed: seen in LLM enrichment steps of the unified pipeline |
85
85
  | CT-119 | Control dependencies of dict values built under guards | Proposed |
86
86
  | CT-120 | Series index operations (`s.index[mask]`, `Series.get(label)`) after aggregation | Proposed: seen in a Pareto topic selection |
87
+ | CT-121 | Dict and JSON outputs as destinations (`json.dump`, `f.write(json.dumps(...))` of values from cells) | Proposed: a co-occurrence extraction reaches a JSON config only through dicts |
88
+ | CT-122 | Journey reach, logical columns, grouped steps, compact notebook/CLI output | Implemented dev11 |
87
89
  | CT-095 | Lazy materialization | Proposed: avoid eager pass copies of every known column on each row operation for very wide frames |
88
90
 
89
91
  ## Next checkpoint
@@ -1,6 +1,6 @@
1
1
  # Project compatibility checkpoint
2
2
 
3
- Local checkpoint: `0.1.0.dev10`, 2026-11-05 (dev7 to dev9 sections below are
3
+ Local checkpoint: `0.1.0.dev11`, 2026-11-05 (dev7 to dev10 sections below are
4
4
  kept as history). Publication is a separate step.
5
5
  This work responds to an anonymized compatibility report produced inside the
6
6
  user's company. The private project was not accessed, copied or executed; every
@@ -332,6 +332,45 @@ extraction census, warnings fell in 9 of 18 projects (for example 67 to 39 and
332
332
  library calls; one of those calls was `load_table_from_dataframe`, which is now
333
333
  a recorded export.
334
334
 
335
+ ## Sixth round: the dev10 run on the private pipeline (dev11)
336
+
337
+ The user ran dev10 on the private pipeline and sent the cell output and the run
338
+ artifacts. The analysis matched the anonymized copy (6,413 column versions,
339
+ 598 frames, 40 sources; the target database column had the same 19 downstream
340
+ columns). Two complaints remained, both about how results were presented and
341
+ selected:
342
+
343
+ 1. The target database column's journey "only showed references". Every step
344
+ sat on the extraction line (the SQL fields computed from the column and its
345
+ row controls), repeated once per calling context, and the outcome read "Last
346
+ recorded use; no later destination was established", although its derived
347
+ columns reach the published exports.
348
+ 2. Selecting the SQL output by name "gave an error". The cell in use was an
349
+ older copy that stops at an ambiguous name and prints every informational
350
+ note; its list held 85 identities. With the current cell, the first identity
351
+ was a secondary extraction of the same name (a totals query), not the one the
352
+ transform uses.
353
+
354
+ Fixes: `journey.reach` and `journey.outcomes` follow the values into derived
355
+ columns up to their exports (ADR-083); `journey.step_groups` counts repeated
356
+ steps per place (ADR-085); `LineageGraph.logical_columns` groups identities into
357
+ same-name lineages, and ranking starts from where a frame's story of the column
358
+ begins, then prefers the family the pipeline transforms (ADR-084). Export events
359
+ name their target instead of an option such as `orient="records"`. The notebook
360
+ cell and `coltrace trace` print the grouped journey, where the values go and
361
+ each derived column's definition, transformations and exports.
362
+
363
+ On the anonymized copy the name now resolves to 10 logical columns (from 85
364
+ identities); the first is the extraction the transform uses, and the database
365
+ column's journey ends with "Values reach 2 recorded export(s)". The cell prints
366
+ about 150 lines for either selection.
367
+
368
+ 1,051 tests pass (7 new in `test_journey_reach.py`); precision checks stay at
369
+ 14/14 expected and 0/9 forbidden. Measuring the new ranking on owid exposed a
370
+ slowdown introduced during the change (an undirected view rebuilt per lookup:
371
+ 41 s to rank 6,629 identities of one name); it was fixed before release
372
+ (0.15 s). Trace time on owid is unchanged (10 to 13 s per column, as before).
373
+
335
374
  ## Remaining boundaries
336
375
 
337
376
  This is still bounded abstract interpretation, not a general control-flow solver.
@@ -87,6 +87,9 @@ choices made within the user's authorization.
87
87
  | ADR-080 | Promote unresolved results at DataFrame parameters | Same evidence as ADR-057, observed in the callee; one frame per result object, so later uses share its identity |
88
88
  | ADR-081 | BigQuery `UNNEST`, STRUCT paths and `USING` | Nested fields are columns named by their path; `USING` keys are controls of both sides and an unqualified key is their `COALESCE`; physical tables are assumed to hold a key only as the single remaining candidate |
89
89
  | ADR-082 | Warehouse writers are exports | `load_table_from_dataframe`, `write_pandas` and `to_gbq` read the frame they receive; treating them as opaque invalidated it |
90
+ | ADR-083 | Journeys follow values into derived columns | A database column's journey ended at the SQL that read it, so users saw only references; `reach` and `outcomes` show where its values go while `fate` keeps the column's own outcome |
91
+ | ADR-084 | Logical columns for ambiguous names | 85 identities of one name were unusable as a choice; same-name lineages group them, and ranking starts from where a frame's story of the column begins, then prefers the family the pipeline transforms |
92
+ | ADR-085 | Count repeated steps per place | An extractor called per segment repeated each step per calling context; grouped steps keep every record in JSON while readers see each action once |
90
93
 
91
94
  The initial codename was FeatureTrace. The early architecture proposed reusable
92
95
  function summaries; direct contextual interpretation is used first because it
@@ -204,6 +204,20 @@ The last recorded terminal outcome is a branch-local observation, not a claim
204
204
  that no other frame branch retains or consumes the column.
205
205
  These journey additions do not change the persisted snapshot structure.
206
206
 
207
+ From dev11 the journey also answers where a column's values go when the column
208
+ itself ends early (a database column read by SQL ends at the extraction):
209
+
210
+ | Field | Content |
211
+ | --- | --- |
212
+ | `step_groups` | One entry per `relationship`, `kind`, `label`, location and scope, with `count` (records from repeated calls or loop iterations), distinct `contexts`, `step_ids`, the weakest `evidence`, `explanation` and the first `expression` |
213
+ | `outcomes` | Derived columns by name, nearest first: `name`, a representative `column_id`, all `column_ids`, `families`, `distance`, `relationship`, `definitions`, `actions` (applications, writes, derivations), `destinations` (exports) and the most informative `fate` among its families |
214
+ | `reach` | `status` (`exported`, `boundary`, `derived`, or the column's own fate status), a `label`, `derived_names`, and `destinations`, each export site with the column names (`via`) that carry the values there |
215
+
216
+ `fate` keeps describing the selected column's own family. Export events are
217
+ labeled by their target (`Export DataFrame to "out.csv"`) or, without one, by the
218
+ method (`Export DataFrame with to_json`); options such as `orient` are never
219
+ reported as a destination.
220
+
207
221
  ## Validation and evolution
208
222
 
209
223
  `load_report` validates schema kind/version, record fields and types, evidence
@@ -414,10 +414,23 @@ SQL text is a SQL client, not a Pandas DataFrame using `DataFrame.query`.
414
414
 
415
415
  `LineageGraph.candidates(name)` lists every identity a name matches, most likely
416
416
  origin first: analyses of called code before uncalled-function templates, then
417
- database column, source field, write, and stronger evidence. `select` still
418
- raises `AmbiguousColumnError` for distinct lineages (its `candidates` use the
419
- same order); ranking never merges them. The notebook cell continues with the
420
- first candidate by default (`ON_AMBIGUOUS = "first"`).
417
+ where the frame's story of that column starts (database column, source field,
418
+ write; from dev11 a source overwritten in place, such as
419
+ `df["x"] = pd.to_numeric(df["x"])`, still counts as a source), and stronger
420
+ evidence. Among equally likely first origins (one extraction issued by several
421
+ extractors; at most 64 tied families), the family whose values reach more
422
+ derived columns comes first. `select` still raises `AmbiguousColumnError` for
423
+ distinct lineages (its `candidates` use the same order); ranking never merges
424
+ them.
425
+
426
+ `LineageGraph.logical_columns(candidates)` (dev11) groups those identities into
427
+ logical columns: every version of the name joined by same-name relations
428
+ (copies, in-place cleanups, named aggregations, the `concat` of per-segment
429
+ frames). Two separate extractions of one name stay separate. Each entry gives
430
+ the first version (`column`), the function that issued the extraction (`via`),
431
+ the number of versions, the names derived from its values and the exports they
432
+ reach. The notebook cell lists logical columns instead of every identity and
433
+ continues with the first one by default (`ON_AMBIGUOUS = "first"`).
421
434
 
422
435
  ## Values, labels and records across a notebook pipeline (dev10)
423
436
 
@@ -118,12 +118,28 @@ unresolved facts. Reusing one after upgrading will not show newly supported edge
118
118
 
119
119
  Use the current `examples/notebook_cell.py`. Cells copied before dev7 print every
120
120
  informational note (thousands of `CT_CONDITIONAL_FLOW` lines), which notebook
121
- platforms truncate, and label modeled names as "Observed names". The current
122
- cell prints counts, grouped warnings, ranked candidates and, when `FUNCTION` or
123
- `MODULE` filters exclude a name, the identities that exist without them. Keep
124
- helper scripts (for example a one-off patch script) out of the analysis with
121
+ platforms truncate, and label modeled names as "Observed names". Older cells also
122
+ stop at an ambiguous name ("Multiple identities. Set COLUMN_ID ...") and list
123
+ every identity. The current cell prints counts, grouped warnings, logical
124
+ columns for an ambiguous name (continuing with the first), the journey with
125
+ repeated steps counted, where the values go, and each derived column's
126
+ definition, transformations and exports. When `FUNCTION` or `MODULE` filters
127
+ exclude a name it lists the identities that exist without them. Keep helper
128
+ scripts (for example a one-off patch script) out of the analysis with
125
129
  `.coltraceignore`.
126
130
 
131
+ ## A database column's journey only shows SQL references
132
+
133
+ A database column read by SQL text ends at the extraction: its own steps are the
134
+ SQL fields computed from it (`derivation`) and its uses in `WHERE`, `JOIN` or
135
+ `GROUP BY` (row controls), and its own outcome is "last recorded use". From
136
+ dev11 the journey follows its values into those derived columns: `reach` names
137
+ the exports they reach and `outcomes` lists each derived column with where it is
138
+ defined, transformed and exported. To follow one derived column in detail,
139
+ select it by name; for a name produced by several extractions, the first logical
140
+ column is the one the pipeline goes on to transform, and `FUNCTION` set to the
141
+ extractor narrows it explicitly.
142
+
127
143
  ## A column used inside SQL is not found
128
144
 
129
145
  Since dev8, columns read by SQL text are `table` columns and can be selected