deepdoc 3.1.0__tar.gz → 3.3.0__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 (153) hide show
  1. {deepdoc-3.1.0 → deepdoc-3.3.0}/PKG-INFO +1 -1
  2. {deepdoc-3.1.0 → deepdoc-3.3.0}/deepdoc/__init__.py +1 -1
  3. {deepdoc-3.1.0 → deepdoc-3.3.0}/deepdoc/planner/heuristics.py +0 -65
  4. {deepdoc-3.1.0 → deepdoc-3.3.0}/deepdoc/planner/nav_shaping.py +18 -47
  5. {deepdoc-3.1.0 → deepdoc-3.3.0}/deepdoc/site/builder/mkdocs_builder.py +405 -193
  6. deepdoc-3.3.0/deepdoc/site/builder/vendor/highlight.min.js +1232 -0
  7. deepdoc-3.3.0/deepdoc/site/builder/vendor/hljs-theme.css +10 -0
  8. deepdoc-3.3.0/deepdoc/site/builder/vendor/markdown-it.min.js +2 -0
  9. {deepdoc-3.1.0 → deepdoc-3.3.0}/deepdoc.egg-info/PKG-INFO +1 -1
  10. {deepdoc-3.1.0 → deepdoc-3.3.0}/deepdoc.egg-info/SOURCES.txt +3 -0
  11. {deepdoc-3.1.0 → deepdoc-3.3.0}/pyproject.toml +6 -1
  12. {deepdoc-3.1.0 → deepdoc-3.3.0}/tests/test_planner_granularity.py +137 -3
  13. {deepdoc-3.1.0 → deepdoc-3.3.0}/LICENSE +0 -0
  14. {deepdoc-3.1.0 → deepdoc-3.3.0}/README.md +0 -0
  15. {deepdoc-3.1.0 → deepdoc-3.3.0}/deepdoc/__main__.py +0 -0
  16. {deepdoc-3.1.0 → deepdoc-3.3.0}/deepdoc/benchmark_v2.py +0 -0
  17. {deepdoc-3.1.0 → deepdoc-3.3.0}/deepdoc/call_graph.py +0 -0
  18. {deepdoc-3.1.0 → deepdoc-3.3.0}/deepdoc/changelog_writer.py +0 -0
  19. {deepdoc-3.1.0 → deepdoc-3.3.0}/deepdoc/chatbot/__init__.py +0 -0
  20. {deepdoc-3.1.0 → deepdoc-3.3.0}/deepdoc/chatbot/answer_mixin.py +0 -0
  21. {deepdoc-3.1.0 → deepdoc-3.3.0}/deepdoc/chatbot/chunker.py +0 -0
  22. {deepdoc-3.1.0 → deepdoc-3.3.0}/deepdoc/chatbot/constants.py +0 -0
  23. {deepdoc-3.1.0 → deepdoc-3.3.0}/deepdoc/chatbot/deep_research.py +0 -0
  24. {deepdoc-3.1.0 → deepdoc-3.3.0}/deepdoc/chatbot/docs_summary.py +0 -0
  25. {deepdoc-3.1.0 → deepdoc-3.3.0}/deepdoc/chatbot/embeddings.py +0 -0
  26. {deepdoc-3.1.0 → deepdoc-3.3.0}/deepdoc/chatbot/indexer.py +0 -0
  27. {deepdoc-3.1.0 → deepdoc-3.3.0}/deepdoc/chatbot/linking.py +0 -0
  28. {deepdoc-3.1.0 → deepdoc-3.3.0}/deepdoc/chatbot/live_fallback_mixin.py +0 -0
  29. {deepdoc-3.1.0 → deepdoc-3.3.0}/deepdoc/chatbot/persistence.py +0 -0
  30. {deepdoc-3.1.0 → deepdoc-3.3.0}/deepdoc/chatbot/providers.py +0 -0
  31. {deepdoc-3.1.0 → deepdoc-3.3.0}/deepdoc/chatbot/retrieval_mixin.py +0 -0
  32. {deepdoc-3.1.0 → deepdoc-3.3.0}/deepdoc/chatbot/routes.py +0 -0
  33. {deepdoc-3.1.0 → deepdoc-3.3.0}/deepdoc/chatbot/scaffold.py +0 -0
  34. {deepdoc-3.1.0 → deepdoc-3.3.0}/deepdoc/chatbot/service.py +0 -0
  35. {deepdoc-3.1.0 → deepdoc-3.3.0}/deepdoc/chatbot/settings.py +0 -0
  36. {deepdoc-3.1.0 → deepdoc-3.3.0}/deepdoc/chatbot/source_archive.py +0 -0
  37. {deepdoc-3.1.0 → deepdoc-3.3.0}/deepdoc/chatbot/symbol_index.py +0 -0
  38. {deepdoc-3.1.0 → deepdoc-3.3.0}/deepdoc/chatbot/types.py +0 -0
  39. {deepdoc-3.1.0 → deepdoc-3.3.0}/deepdoc/cli.py +0 -0
  40. {deepdoc-3.1.0 → deepdoc-3.3.0}/deepdoc/config.py +0 -0
  41. {deepdoc-3.1.0 → deepdoc-3.3.0}/deepdoc/generator/__init__.py +0 -0
  42. {deepdoc-3.1.0 → deepdoc-3.3.0}/deepdoc/generator/consistency.py +0 -0
  43. {deepdoc-3.1.0 → deepdoc-3.3.0}/deepdoc/generator/evidence.py +0 -0
  44. {deepdoc-3.1.0 → deepdoc-3.3.0}/deepdoc/generator/generation.py +0 -0
  45. {deepdoc-3.1.0 → deepdoc-3.3.0}/deepdoc/generator/post_processors.py +0 -0
  46. {deepdoc-3.1.0 → deepdoc-3.3.0}/deepdoc/generator/validation.py +0 -0
  47. {deepdoc-3.1.0 → deepdoc-3.3.0}/deepdoc/llm/__init__.py +0 -0
  48. {deepdoc-3.1.0 → deepdoc-3.3.0}/deepdoc/llm/client.py +0 -0
  49. {deepdoc-3.1.0 → deepdoc-3.3.0}/deepdoc/llm/json_utils.py +0 -0
  50. {deepdoc-3.1.0 → deepdoc-3.3.0}/deepdoc/llm/litellm_compat.py +0 -0
  51. {deepdoc-3.1.0 → deepdoc-3.3.0}/deepdoc/llm/retry.py +0 -0
  52. {deepdoc-3.1.0 → deepdoc-3.3.0}/deepdoc/manifest.py +0 -0
  53. {deepdoc-3.1.0 → deepdoc-3.3.0}/deepdoc/openapi.py +0 -0
  54. {deepdoc-3.1.0 → deepdoc-3.3.0}/deepdoc/parser/__init__.py +0 -0
  55. {deepdoc-3.1.0 → deepdoc-3.3.0}/deepdoc/parser/api_detector.py +0 -0
  56. {deepdoc-3.1.0 → deepdoc-3.3.0}/deepdoc/parser/base.py +0 -0
  57. {deepdoc-3.1.0 → deepdoc-3.3.0}/deepdoc/parser/go_parser.py +0 -0
  58. {deepdoc-3.1.0 → deepdoc-3.3.0}/deepdoc/parser/js_ts_parser.py +0 -0
  59. {deepdoc-3.1.0 → deepdoc-3.3.0}/deepdoc/parser/php_parser.py +0 -0
  60. {deepdoc-3.1.0 → deepdoc-3.3.0}/deepdoc/parser/python_parser.py +0 -0
  61. {deepdoc-3.1.0 → deepdoc-3.3.0}/deepdoc/parser/registry.py +0 -0
  62. {deepdoc-3.1.0 → deepdoc-3.3.0}/deepdoc/parser/routes/__init__.py +0 -0
  63. {deepdoc-3.1.0 → deepdoc-3.3.0}/deepdoc/parser/routes/base.py +0 -0
  64. {deepdoc-3.1.0 → deepdoc-3.3.0}/deepdoc/parser/routes/common.py +0 -0
  65. {deepdoc-3.1.0 → deepdoc-3.3.0}/deepdoc/parser/routes/detector.py +0 -0
  66. {deepdoc-3.1.0 → deepdoc-3.3.0}/deepdoc/parser/routes/django.py +0 -0
  67. {deepdoc-3.1.0 → deepdoc-3.3.0}/deepdoc/parser/routes/express.py +0 -0
  68. {deepdoc-3.1.0 → deepdoc-3.3.0}/deepdoc/parser/routes/falcon.py +0 -0
  69. {deepdoc-3.1.0 → deepdoc-3.3.0}/deepdoc/parser/routes/fastify.py +0 -0
  70. {deepdoc-3.1.0 → deepdoc-3.3.0}/deepdoc/parser/routes/go.py +0 -0
  71. {deepdoc-3.1.0 → deepdoc-3.3.0}/deepdoc/parser/routes/js_shared.py +0 -0
  72. {deepdoc-3.1.0 → deepdoc-3.3.0}/deepdoc/parser/routes/laravel.py +0 -0
  73. {deepdoc-3.1.0 → deepdoc-3.3.0}/deepdoc/parser/routes/nestjs.py +0 -0
  74. {deepdoc-3.1.0 → deepdoc-3.3.0}/deepdoc/parser/routes/python_shared.py +0 -0
  75. {deepdoc-3.1.0 → deepdoc-3.3.0}/deepdoc/parser/routes/registry.py +0 -0
  76. {deepdoc-3.1.0 → deepdoc-3.3.0}/deepdoc/parser/routes/repo_resolver.py +0 -0
  77. {deepdoc-3.1.0 → deepdoc-3.3.0}/deepdoc/parser/vue_parser.py +0 -0
  78. {deepdoc-3.1.0 → deepdoc-3.3.0}/deepdoc/persistence_v2.py +0 -0
  79. {deepdoc-3.1.0 → deepdoc-3.3.0}/deepdoc/pipeline_v2.py +0 -0
  80. {deepdoc-3.1.0 → deepdoc-3.3.0}/deepdoc/planner/__init__.py +0 -0
  81. {deepdoc-3.1.0 → deepdoc-3.3.0}/deepdoc/planner/bucket_injection.py +0 -0
  82. {deepdoc-3.1.0 → deepdoc-3.3.0}/deepdoc/planner/bucket_refinement.py +0 -0
  83. {deepdoc-3.1.0 → deepdoc-3.3.0}/deepdoc/planner/common.py +0 -0
  84. {deepdoc-3.1.0 → deepdoc-3.3.0}/deepdoc/planner/endpoint_refs.py +0 -0
  85. {deepdoc-3.1.0 → deepdoc-3.3.0}/deepdoc/planner/engine.py +0 -0
  86. {deepdoc-3.1.0 → deepdoc-3.3.0}/deepdoc/planner/flow_candidates.py +0 -0
  87. {deepdoc-3.1.0 → deepdoc-3.3.0}/deepdoc/planner/specializations.py +0 -0
  88. {deepdoc-3.1.0 → deepdoc-3.3.0}/deepdoc/planner/topology.py +0 -0
  89. {deepdoc-3.1.0 → deepdoc-3.3.0}/deepdoc/planner/utils.py +0 -0
  90. {deepdoc-3.1.0 → deepdoc-3.3.0}/deepdoc/prompts/__init__.py +0 -0
  91. {deepdoc-3.1.0 → deepdoc-3.3.0}/deepdoc/prompts/bucket_types.py +0 -0
  92. {deepdoc-3.1.0 → deepdoc-3.3.0}/deepdoc/prompts/page_types.py +0 -0
  93. {deepdoc-3.1.0 → deepdoc-3.3.0}/deepdoc/prompts/selectors.py +0 -0
  94. {deepdoc-3.1.0 → deepdoc-3.3.0}/deepdoc/prompts/system.py +0 -0
  95. {deepdoc-3.1.0 → deepdoc-3.3.0}/deepdoc/prompts/update.py +0 -0
  96. {deepdoc-3.1.0 → deepdoc-3.3.0}/deepdoc/py.typed +0 -0
  97. {deepdoc-3.1.0 → deepdoc-3.3.0}/deepdoc/scanner/__init__.py +0 -0
  98. {deepdoc-3.1.0 → deepdoc-3.3.0}/deepdoc/scanner/artifacts.py +0 -0
  99. {deepdoc-3.1.0 → deepdoc-3.3.0}/deepdoc/scanner/clustering.py +0 -0
  100. {deepdoc-3.1.0 → deepdoc-3.3.0}/deepdoc/scanner/common.py +0 -0
  101. {deepdoc-3.1.0 → deepdoc-3.3.0}/deepdoc/scanner/database.py +0 -0
  102. {deepdoc-3.1.0 → deepdoc-3.3.0}/deepdoc/scanner/endpoints.py +0 -0
  103. {deepdoc-3.1.0 → deepdoc-3.3.0}/deepdoc/scanner/integrations.py +0 -0
  104. {deepdoc-3.1.0 → deepdoc-3.3.0}/deepdoc/scanner/runtime.py +0 -0
  105. {deepdoc-3.1.0 → deepdoc-3.3.0}/deepdoc/scanner/utils.py +0 -0
  106. {deepdoc-3.1.0 → deepdoc-3.3.0}/deepdoc/site/__init__.py +0 -0
  107. {deepdoc-3.1.0 → deepdoc-3.3.0}/deepdoc/site/builder/__init__.py +0 -0
  108. {deepdoc-3.1.0 → deepdoc-3.3.0}/deepdoc/site/builder/common.py +0 -0
  109. {deepdoc-3.1.0 → deepdoc-3.3.0}/deepdoc/site/builder/mdx_utils.py +0 -0
  110. {deepdoc-3.1.0 → deepdoc-3.3.0}/deepdoc/smart_update_v2.py +0 -0
  111. {deepdoc-3.1.0 → deepdoc-3.3.0}/deepdoc/source_metadata.py +0 -0
  112. {deepdoc-3.1.0 → deepdoc-3.3.0}/deepdoc/updater_v2.py +0 -0
  113. {deepdoc-3.1.0 → deepdoc-3.3.0}/deepdoc/v2_models.py +0 -0
  114. {deepdoc-3.1.0 → deepdoc-3.3.0}/deepdoc.egg-info/dependency_links.txt +0 -0
  115. {deepdoc-3.1.0 → deepdoc-3.3.0}/deepdoc.egg-info/entry_points.txt +0 -0
  116. {deepdoc-3.1.0 → deepdoc-3.3.0}/deepdoc.egg-info/requires.txt +0 -0
  117. {deepdoc-3.1.0 → deepdoc-3.3.0}/deepdoc.egg-info/top_level.txt +0 -0
  118. {deepdoc-3.1.0 → deepdoc-3.3.0}/setup.cfg +0 -0
  119. {deepdoc-3.1.0 → deepdoc-3.3.0}/tests/test_benchmark_scorecard.py +0 -0
  120. {deepdoc-3.1.0 → deepdoc-3.3.0}/tests/test_call_graph.py +0 -0
  121. {deepdoc-3.1.0 → deepdoc-3.3.0}/tests/test_changelog.py +0 -0
  122. {deepdoc-3.1.0 → deepdoc-3.3.0}/tests/test_chatbot_config.py +0 -0
  123. {deepdoc-3.1.0 → deepdoc-3.3.0}/tests/test_chatbot_embeddings.py +0 -0
  124. {deepdoc-3.1.0 → deepdoc-3.3.0}/tests/test_chatbot_eval.py +0 -0
  125. {deepdoc-3.1.0 → deepdoc-3.3.0}/tests/test_chatbot_index.py +0 -0
  126. {deepdoc-3.1.0 → deepdoc-3.3.0}/tests/test_chatbot_persistence.py +0 -0
  127. {deepdoc-3.1.0 → deepdoc-3.3.0}/tests/test_chatbot_providers.py +0 -0
  128. {deepdoc-3.1.0 → deepdoc-3.3.0}/tests/test_chatbot_query.py +0 -0
  129. {deepdoc-3.1.0 → deepdoc-3.3.0}/tests/test_chatbot_relationship.py +0 -0
  130. {deepdoc-3.1.0 → deepdoc-3.3.0}/tests/test_chatbot_scaffold.py +0 -0
  131. {deepdoc-3.1.0 → deepdoc-3.3.0}/tests/test_chatbot_source_archive.py +0 -0
  132. {deepdoc-3.1.0 → deepdoc-3.3.0}/tests/test_classify.py +0 -0
  133. {deepdoc-3.1.0 → deepdoc-3.3.0}/tests/test_cli_generate.py +0 -0
  134. {deepdoc-3.1.0 → deepdoc-3.3.0}/tests/test_cli_serve.py +0 -0
  135. {deepdoc-3.1.0 → deepdoc-3.3.0}/tests/test_cli_update.py +0 -0
  136. {deepdoc-3.1.0 → deepdoc-3.3.0}/tests/test_consistency_pass.py +0 -0
  137. {deepdoc-3.1.0 → deepdoc-3.3.0}/tests/test_flow_candidates.py +0 -0
  138. {deepdoc-3.1.0 → deepdoc-3.3.0}/tests/test_framework_fixtures.py +0 -0
  139. {deepdoc-3.1.0 → deepdoc-3.3.0}/tests/test_framework_support.py +0 -0
  140. {deepdoc-3.1.0 → deepdoc-3.3.0}/tests/test_generation_evidence.py +0 -0
  141. {deepdoc-3.1.0 → deepdoc-3.3.0}/tests/test_internal_docs_metadata.py +0 -0
  142. {deepdoc-3.1.0 → deepdoc-3.3.0}/tests/test_litellm_compat.py +0 -0
  143. {deepdoc-3.1.0 → deepdoc-3.3.0}/tests/test_llm_json_utils.py +0 -0
  144. {deepdoc-3.1.0 → deepdoc-3.3.0}/tests/test_llm_retry.py +0 -0
  145. {deepdoc-3.1.0 → deepdoc-3.3.0}/tests/test_mkdocs_builder.py +0 -0
  146. {deepdoc-3.1.0 → deepdoc-3.3.0}/tests/test_parallel_pipeline.py +0 -0
  147. {deepdoc-3.1.0 → deepdoc-3.3.0}/tests/test_parser_ranges.py +0 -0
  148. {deepdoc-3.1.0 → deepdoc-3.3.0}/tests/test_planner_consolidation.py +0 -0
  149. {deepdoc-3.1.0 → deepdoc-3.3.0}/tests/test_route_registry.py +0 -0
  150. {deepdoc-3.1.0 → deepdoc-3.3.0}/tests/test_runtime_scan.py +0 -0
  151. {deepdoc-3.1.0 → deepdoc-3.3.0}/tests/test_smart_update.py +0 -0
  152. {deepdoc-3.1.0 → deepdoc-3.3.0}/tests/test_stale.py +0 -0
  153. {deepdoc-3.1.0 → deepdoc-3.3.0}/tests/test_state.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: deepdoc
3
- Version: 3.1.0
3
+ Version: 3.3.0
4
4
  Summary: Auto-generate beautiful docs from any codebase
5
5
  Author: Pranav Kumar
6
6
  License: MIT
@@ -1,3 +1,3 @@
1
1
  """DeepDoc — Auto-generate beautiful docs from any codebase."""
2
2
 
3
- __version__ = "3.1.0"
3
+ __version__ = "3.3.0"
@@ -343,71 +343,6 @@ def _default_section_for_primary(primary: str) -> str:
343
343
  return "Architecture"
344
344
 
345
345
 
346
- def _section_rank(section: str, primary: str) -> int:
347
- backend_like = {
348
- "backend_service",
349
- "falcon_backend",
350
- "hybrid",
351
- }
352
- if primary in backend_like:
353
- order = [
354
- "Start Here",
355
- "Overview",
356
- "Core Workflows",
357
- "API Reference",
358
- "Data Model",
359
- "Background Jobs",
360
- "Integrations",
361
- "Runtime & Frameworks",
362
- "Interfaces",
363
- "Operations",
364
- "Design & Notes",
365
- "Testing",
366
- "CI/CD and Release",
367
- "Supporting Material",
368
- ]
369
- if section in order:
370
- return order.index(section)
371
- return len(order) + 10
372
-
373
- if primary == "research_training":
374
- order = [
375
- "Start Here",
376
- "Overview",
377
- "Model Architecture",
378
- "Training",
379
- "Optimization",
380
- "Data Pipeline",
381
- "Evaluation",
382
- "Inference & Runtime",
383
- "Interfaces",
384
- "Operations",
385
- "Research Context",
386
- "Design & Notes",
387
- "Testing",
388
- "CI/CD and Release",
389
- "Supporting Material",
390
- ]
391
- if section in order:
392
- return order.index(section)
393
- return len(order) + 10
394
-
395
- order = [
396
- "Start Here",
397
- "Overview",
398
- "Architecture",
399
- "Core API",
400
- "API Reference",
401
- "Integrations",
402
- "Operations",
403
- "Testing",
404
- "Design & Notes",
405
- "Supporting Material",
406
- ]
407
- if section in order:
408
- return order.index(section)
409
- return len(order) + 10
410
-
411
346
 
412
347
  def _attach_orphans_semantically(
413
348
  plan: DocPlan,
@@ -121,23 +121,10 @@ def _shape_plan_nav(
121
121
  continue
122
122
  _append_nav_slug(nav, "API Reference", bucket.slug)
123
123
 
124
- # Build section → tier map for three-tier nav ordering
125
- slug_to_bucket_map = {bucket.slug: bucket for bucket in plan.buckets}
126
- section_buckets_by_top: dict[str, list[DocBucket]] = defaultdict(list)
127
- for section, slugs in nav.items():
128
- top_section = _section_top(section)
129
- for slug in slugs:
130
- if slug in slug_to_bucket_map:
131
- section_buckets_by_top[top_section].append(slug_to_bucket_map[slug])
132
- section_tier_map = {
133
- top: _compute_section_tier(buckets_list)
134
- for top, buckets_list in section_buckets_by_top.items()
135
- }
136
-
137
124
  section_order = {section: idx for idx, section in enumerate(nav.keys())}
138
125
  ordered_sections = sorted(
139
126
  nav.keys(),
140
- key=lambda section: _section_sort_key(section, primary, section_depth, section_order, section_tier_map),
127
+ key=lambda section: _section_sort_key(section, primary, section_depth, section_order),
141
128
  )
142
129
 
143
130
  plan.nav_structure = {
@@ -330,49 +317,27 @@ def _build_section_depth_map(
330
317
  return section_depth
331
318
 
332
319
 
333
- def _compute_section_tier(buckets_in_section: list[DocBucket]) -> int:
334
- """Return 1=user-facing, 2=domain/feature, 3=infrastructure.
335
-
336
- Tier 1: sections containing intro, endpoint family, or endpoint-detail buckets.
337
- Tier 2: sections containing feature/integration/database/endpoint bucket types.
338
- Tier 3: everything else (foundational, infrastructure, utility).
339
- """
340
- for b in buckets_in_section:
341
- hints = b.generation_hints or {}
342
- if (
343
- hints.get("is_introduction_page")
344
- or hints.get("is_endpoint_family")
345
- or hints.get("include_endpoint_detail")
346
- ):
347
- return 1
348
- for b in buckets_in_section:
349
- if b.bucket_type in ("feature", "integration", "database", "endpoint", "endpoint_ref"):
350
- return 2
351
- return 3
352
-
353
-
354
320
  def _section_sort_key(
355
321
  section: str,
356
322
  primary: str,
357
323
  section_depth: dict[str, int],
358
324
  section_order: dict[str, int],
359
- section_tier_map: dict[str, int] | None = None,
360
325
  ) -> tuple:
361
326
  """Sort key for nav sections.
362
327
 
363
328
  Pins Start Here / Overview first and tail sections (Testing, CI/CD, Supporting
364
- Material) last. Everything in between is ordered by three tiers that preserve
365
- a newcomer reading journey (user-facing domain/feature infrastructure),
366
- with topology depth as a tiebreaker within each tier.
329
+ Material) last. Everything in between is ordered by topology depth:
330
+ entry-point-facing sections (depth 0-1) first, domain logic (depth 2-3) in
331
+ the middle, foundational sections (depth 4+) at the end.
367
332
  """
368
333
  top = _section_top(section)
369
334
 
370
335
  _FIRST = {"Start Here": 0, "Overview": 1}
371
336
  _LAST = {
372
- "Testing": 57,
373
- "CI/CD and Release": 58,
374
- "CI/CD & Release": 58,
375
- "Supporting Material": 59,
337
+ "Testing": 997,
338
+ "CI/CD and Release": 998,
339
+ "CI/CD & Release": 998,
340
+ "Supporting Material": 999,
376
341
  }
377
342
 
378
343
  if top in _FIRST:
@@ -380,10 +345,16 @@ def _section_sort_key(
380
345
  if top in _LAST:
381
346
  return (_LAST[top], section_order.get(section, 999), section)
382
347
 
383
- # Three-tier middle: user-facing (10+) → domain/feature (20+) → infrastructure (30+)
384
- # Within each tier, topology depth orders entry-point-facing sections first.
385
- tier = (section_tier_map or {}).get(top, 3)
386
- tier_base = 10 * tier
387
348
  depth = section_depth.get(top, 50)
349
+ # Three tiers derived purely from topology depth:
350
+ # depth 0-1 = entry-point-facing → user-facing (base 10)
351
+ # depth 2-3 = domain logic (base 20)
352
+ # depth 4+ = foundational/infrastructure (base 30)
353
+ if depth <= 1:
354
+ tier_base = 10
355
+ elif depth <= 3:
356
+ tier_base = 20
357
+ else:
358
+ tier_base = 30
388
359
  child_rank = 0 if section == top else 1
389
360
  return (tier_base + depth, child_rank, section_order.get(section, 999), section)