conexus 4.2.2__tar.gz → 4.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 (550) hide show
  1. {conexus-4.2.2 → conexus-4.3.0}/.beads/interactions.jsonl +65 -0
  2. {conexus-4.2.2 → conexus-4.3.0}/.claude-plugin/marketplace.json +2 -2
  3. {conexus-4.2.2 → conexus-4.3.0}/.gitignore +2 -0
  4. {conexus-4.2.2 → conexus-4.3.0}/CHANGELOG.md +30 -0
  5. {conexus-4.2.2 → conexus-4.3.0}/PKG-INFO +1 -1
  6. {conexus-4.2.2 → conexus-4.3.0}/docs/architecture.md +8 -0
  7. {conexus-4.2.2 → conexus-4.3.0}/docs/cli-reference.md +6 -1
  8. {conexus-4.2.2 → conexus-4.3.0}/docs/rdr/README.md +2 -0
  9. conexus-4.3.0/docs/rdr/rdr-077-projection-quality-similarity-icf.md +367 -0
  10. conexus-4.3.0/docs/rdr/rdr-078-unified-context-graph-and-retrieval.md +153 -0
  11. {conexus-4.2.2 → conexus-4.3.0}/docs/storage-tiers.md +1 -1
  12. conexus-4.3.0/docs/taxonomy-projection-tuning.md +203 -0
  13. {conexus-4.2.2 → conexus-4.3.0}/docs/taxonomy.md +28 -0
  14. {conexus-4.2.2 → conexus-4.3.0}/nx/.claude-plugin/plugin.json +1 -1
  15. {conexus-4.2.2 → conexus-4.3.0}/nx/CHANGELOG.md +4 -0
  16. {conexus-4.2.2 → conexus-4.3.0}/pyproject.toml +1 -1
  17. {conexus-4.2.2 → conexus-4.3.0}/sn/.claude-plugin/plugin.json +1 -1
  18. {conexus-4.2.2 → conexus-4.3.0}/src/nexus/commands/taxonomy_cmd.py +341 -56
  19. {conexus-4.2.2 → conexus-4.3.0}/src/nexus/corpus.py +29 -0
  20. {conexus-4.2.2 → conexus-4.3.0}/src/nexus/db/migrations.py +66 -2
  21. {conexus-4.2.2 → conexus-4.3.0}/src/nexus/db/t2/catalog_taxonomy.py +592 -17
  22. {conexus-4.2.2 → conexus-4.3.0}/src/nexus/mcp_infra.py +14 -8
  23. {conexus-4.2.2 → conexus-4.3.0}/tests/test_migrations.py +1 -1
  24. {conexus-4.2.2 → conexus-4.3.0}/tests/test_phase5_integration.py +2 -1
  25. conexus-4.3.0/tests/test_projection_quality.py +1129 -0
  26. {conexus-4.2.2 → conexus-4.3.0}/tests/test_taxonomy.py +9 -6
  27. {conexus-4.2.2 → conexus-4.3.0}/tests/test_taxonomy_e2e.py +5 -4
  28. {conexus-4.2.2 → conexus-4.3.0}/tests/test_upgrade_e2e.py +2 -1
  29. {conexus-4.2.2 → conexus-4.3.0}/uv.lock +1 -1
  30. {conexus-4.2.2 → conexus-4.3.0}/.beads/.gitignore +0 -0
  31. {conexus-4.2.2 → conexus-4.3.0}/.beads/README.md +0 -0
  32. {conexus-4.2.2 → conexus-4.3.0}/.beads/config.yaml +0 -0
  33. {conexus-4.2.2 → conexus-4.3.0}/.beads/hooks/post-checkout +0 -0
  34. {conexus-4.2.2 → conexus-4.3.0}/.beads/hooks/post-merge +0 -0
  35. {conexus-4.2.2 → conexus-4.3.0}/.beads/hooks/pre-commit +0 -0
  36. {conexus-4.2.2 → conexus-4.3.0}/.beads/hooks/pre-push +0 -0
  37. {conexus-4.2.2 → conexus-4.3.0}/.beads/hooks/prepare-commit-msg +0 -0
  38. {conexus-4.2.2 → conexus-4.3.0}/.beads/issues.jsonl +0 -0
  39. {conexus-4.2.2 → conexus-4.3.0}/.beads/metadata.json +0 -0
  40. {conexus-4.2.2 → conexus-4.3.0}/.claude/skills/release.md +0 -0
  41. {conexus-4.2.2 → conexus-4.3.0}/.devcontainer/Dockerfile +0 -0
  42. {conexus-4.2.2 → conexus-4.3.0}/.devcontainer/devcontainer.json +0 -0
  43. {conexus-4.2.2 → conexus-4.3.0}/.dockerignore +0 -0
  44. {conexus-4.2.2 → conexus-4.3.0}/.env.example +0 -0
  45. {conexus-4.2.2 → conexus-4.3.0}/.gitattributes +0 -0
  46. {conexus-4.2.2 → conexus-4.3.0}/.github/workflows/ci.yml +0 -0
  47. {conexus-4.2.2 → conexus-4.3.0}/.github/workflows/release.yml +0 -0
  48. {conexus-4.2.2 → conexus-4.3.0}/.markdownlint.json +0 -0
  49. {conexus-4.2.2 → conexus-4.3.0}/.plans/rdr-066-plan.md +0 -0
  50. {conexus-4.2.2 → conexus-4.3.0}/AGENTS.md +0 -0
  51. {conexus-4.2.2 → conexus-4.3.0}/CLAUDE.md +0 -0
  52. {conexus-4.2.2 → conexus-4.3.0}/Formula/nx.rb +0 -0
  53. {conexus-4.2.2 → conexus-4.3.0}/LICENSE +0 -0
  54. {conexus-4.2.2 → conexus-4.3.0}/README.md +0 -0
  55. {conexus-4.2.2 → conexus-4.3.0}/docs/README.md +0 -0
  56. {conexus-4.2.2 → conexus-4.3.0}/docs/catalog.md +0 -0
  57. {conexus-4.2.2 → conexus-4.3.0}/docs/configuration.md +0 -0
  58. {conexus-4.2.2 → conexus-4.3.0}/docs/contributing.md +0 -0
  59. {conexus-4.2.2 → conexus-4.3.0}/docs/getting-started.md +0 -0
  60. {conexus-4.2.2 → conexus-4.3.0}/docs/historical.md +0 -0
  61. {conexus-4.2.2 → conexus-4.3.0}/docs/logging.md +0 -0
  62. {conexus-4.2.2 → conexus-4.3.0}/docs/mcp-servers.md +0 -0
  63. {conexus-4.2.2 → conexus-4.3.0}/docs/memory-and-tasks.md +0 -0
  64. {conexus-4.2.2 → conexus-4.3.0}/docs/postmortem/2026-03-23-pdf-index-collection-mismatch.md +0 -0
  65. {conexus-4.2.2 → conexus-4.3.0}/docs/postmortem/2026-03-24-pdf-index-fix-not-applied.md +0 -0
  66. {conexus-4.2.2 → conexus-4.3.0}/docs/querying-guide.md +0 -0
  67. {conexus-4.2.2 → conexus-4.3.0}/docs/rdr/post-mortem/001-rdr-process-validation.md +0 -0
  68. {conexus-4.2.2 → conexus-4.3.0}/docs/rdr/post-mortem/002-t2-status-synchronization.md +0 -0
  69. {conexus-4.2.2 → conexus-4.3.0}/docs/rdr/post-mortem/010-t1-http-server.md +0 -0
  70. {conexus-4.2.2 → conexus-4.3.0}/docs/rdr/post-mortem/011-pdf-ingest-test-coverage.md +0 -0
  71. {conexus-4.2.2 → conexus-4.3.0}/docs/rdr/post-mortem/012-pdfplumber-extraction-tier.md +0 -0
  72. {conexus-4.2.2 → conexus-4.3.0}/docs/rdr/post-mortem/014-knowledge-base-retrieval-quality.md +0 -0
  73. {conexus-4.2.2 → conexus-4.3.0}/docs/rdr/post-mortem/015-indexing-pipeline-rethink.md +0 -0
  74. {conexus-4.2.2 → conexus-4.3.0}/docs/rdr/post-mortem/016-ast-chunk-line-range-bug.md +0 -0
  75. {conexus-4.2.2 → conexus-4.3.0}/docs/rdr/post-mortem/017-indexing-progress-reporting.md +0 -0
  76. {conexus-4.2.2 → conexus-4.3.0}/docs/rdr/post-mortem/018-replace-serve-with-git-hooks.md +0 -0
  77. {conexus-4.2.2 → conexus-4.3.0}/docs/rdr/post-mortem/023-agent-tool-permissions-audit.md +0 -0
  78. {conexus-4.2.2 → conexus-4.3.0}/docs/rdr/post-mortem/024-rdr-process-guardrails.md +0 -0
  79. {conexus-4.2.2 → conexus-4.3.0}/docs/rdr/post-mortem/028-language-registry-unification.md +0 -0
  80. {conexus-4.2.2 → conexus-4.3.0}/docs/rdr/post-mortem/029-pipeline-versioning.md +0 -0
  81. {conexus-4.2.2 → conexus-4.3.0}/docs/rdr/post-mortem/048-streaming-pdf-pipeline.md +0 -0
  82. {conexus-4.2.2 → conexus-4.3.0}/docs/rdr/post-mortem/049-git-backed-catalog.md +0 -0
  83. {conexus-4.2.2 → conexus-4.3.0}/docs/rdr/post-mortem/050-catalog-query-integration.md +0 -0
  84. {conexus-4.2.2 → conexus-4.3.0}/docs/rdr/post-mortem/051-link-lifecycle.md +0 -0
  85. {conexus-4.2.2 → conexus-4.3.0}/docs/rdr/post-mortem/052-catalog-first-query-routing.md +0 -0
  86. {conexus-4.2.2 → conexus-4.3.0}/docs/rdr/post-mortem/053-xanadu-fidelity.md +0 -0
  87. {conexus-4.2.2 → conexus-4.3.0}/docs/rdr/post-mortem/058-pipeline-orchestration-plan-reuse.md +0 -0
  88. {conexus-4.2.2 → conexus-4.3.0}/docs/rdr/post-mortem/060-catalog-path-rationalization-link-usability.md +0 -0
  89. {conexus-4.2.2 → conexus-4.3.0}/docs/rdr/post-mortem/063-t2-domain-split.md +0 -0
  90. {conexus-4.2.2 → conexus-4.3.0}/docs/rdr/post-mortem/065-close-time-funnel-hardening.md +0 -0
  91. {conexus-4.2.2 → conexus-4.3.0}/docs/rdr/post-mortem/067-cross-project-rdr-audit-loop.md +0 -0
  92. {conexus-4.2.2 → conexus-4.3.0}/docs/rdr/post-mortem/cce-query-model-mismatch.md +0 -0
  93. {conexus-4.2.2 → conexus-4.3.0}/docs/rdr/rdr-001-rdr-process-validation.md +0 -0
  94. {conexus-4.2.2 → conexus-4.3.0}/docs/rdr/rdr-002-t2-status-synchronization.md +0 -0
  95. {conexus-4.2.2 → conexus-4.3.0}/docs/rdr/rdr-004-four-store-architecture.md +0 -0
  96. {conexus-4.2.2 → conexus-4.3.0}/docs/rdr/rdr-005-chromadb-cloud-quota-enforcement.md +0 -0
  97. {conexus-4.2.2 → conexus-4.3.0}/docs/rdr/rdr-006-chunk-size-configuration.md +0 -0
  98. {conexus-4.2.2 → conexus-4.3.0}/docs/rdr/rdr-007-claude-adoption-session-context-and-search-guidance.md +0 -0
  99. {conexus-4.2.2 → conexus-4.3.0}/docs/rdr/rdr-008-nx-workflow-integration.md +0 -0
  100. {conexus-4.2.2 → conexus-4.3.0}/docs/rdr/rdr-009-remove-agentic-and-answer-flags.md +0 -0
  101. {conexus-4.2.2 → conexus-4.3.0}/docs/rdr/rdr-010-t1-scratch-persistent-bounded-store.md +0 -0
  102. {conexus-4.2.2 → conexus-4.3.0}/docs/rdr/rdr-011-pdf-ingest-test-coverage.md +0 -0
  103. {conexus-4.2.2 → conexus-4.3.0}/docs/rdr/rdr-012-pdfplumber-extraction-tier.md +0 -0
  104. {conexus-4.2.2 → conexus-4.3.0}/docs/rdr/rdr-013-remove-nx-pm-layer.md +0 -0
  105. {conexus-4.2.2 → conexus-4.3.0}/docs/rdr/rdr-014-knowledge-base-retrieval-quality.md +0 -0
  106. {conexus-4.2.2 → conexus-4.3.0}/docs/rdr/rdr-015-indexing-pipeline-rethink.md +0 -0
  107. {conexus-4.2.2 → conexus-4.3.0}/docs/rdr/rdr-016-ast-chunk-line-range-bug.md +0 -0
  108. {conexus-4.2.2 → conexus-4.3.0}/docs/rdr/rdr-017-indexing-progress-reporting.md +0 -0
  109. {conexus-4.2.2 → conexus-4.3.0}/docs/rdr/rdr-018-replace-serve-with-git-hooks.md +0 -0
  110. {conexus-4.2.2 → conexus-4.3.0}/docs/rdr/rdr-019-chromadb-transient-retry.md +0 -0
  111. {conexus-4.2.2 → conexus-4.3.0}/docs/rdr/rdr-020-voyage-chromadb-read-timeout.md +0 -0
  112. {conexus-4.2.2 → conexus-4.3.0}/docs/rdr/rdr-021-docling-pdf-extraction.md +0 -0
  113. {conexus-4.2.2 → conexus-4.3.0}/docs/rdr/rdr-022-memory-delete-command.md +0 -0
  114. {conexus-4.2.2 → conexus-4.3.0}/docs/rdr/rdr-023-agent-tool-permissions-audit.md +0 -0
  115. {conexus-4.2.2 → conexus-4.3.0}/docs/rdr/rdr-024-rdr-process-guardrails.md +0 -0
  116. {conexus-4.2.2 → conexus-4.3.0}/docs/rdr/rdr-025-language-agnostic-agents.md +0 -0
  117. {conexus-4.2.2 → conexus-4.3.0}/docs/rdr/rdr-026-hybrid-search-fusion.md +0 -0
  118. {conexus-4.2.2 → conexus-4.3.0}/docs/rdr/rdr-027-search-results-ux.md +0 -0
  119. {conexus-4.2.2 → conexus-4.3.0}/docs/rdr/rdr-028-code-search-recall.md +0 -0
  120. {conexus-4.2.2 → conexus-4.3.0}/docs/rdr/rdr-029-pipeline-versioning.md +0 -0
  121. {conexus-4.2.2 → conexus-4.3.0}/docs/rdr/rdr-030-reliability-hardening.md +0 -0
  122. {conexus-4.2.2 → conexus-4.3.0}/docs/rdr/rdr-031-collection-portability.md +0 -0
  123. {conexus-4.2.2 → conexus-4.3.0}/docs/rdr/rdr-032-indexer-decomposition.md +0 -0
  124. {conexus-4.2.2 → conexus-4.3.0}/docs/rdr/rdr-033-pdf-agent-nx-index-alignment.md +0 -0
  125. {conexus-4.2.2 → conexus-4.3.0}/docs/rdr/rdr-034-mcp-server-agent-storage.md +0 -0
  126. {conexus-4.2.2 → conexus-4.3.0}/docs/rdr/rdr-035-plugin-agent-mcp-tool-access.md +0 -0
  127. {conexus-4.2.2 → conexus-4.3.0}/docs/rdr/rdr-036-post-accept-planning-workflow.md +0 -0
  128. {conexus-4.2.2 → conexus-4.3.0}/docs/rdr/rdr-037-t3-database-consolidation.md +0 -0
  129. {conexus-4.2.2 → conexus-4.3.0}/docs/rdr/rdr-038-local-t3-backend.md +0 -0
  130. {conexus-4.2.2 → conexus-4.3.0}/docs/rdr/rdr-039-claude-code-framework-alignment.md +0 -0
  131. {conexus-4.2.2 → conexus-4.3.0}/docs/rdr/rdr-040-cce-postmortem-gaps-mcp-enhancement.md +0 -0
  132. {conexus-4.2.2 → conexus-4.3.0}/docs/rdr/rdr-040-developer-agent-circuit-breaker.md +0 -0
  133. {conexus-4.2.2 → conexus-4.3.0}/docs/rdr/rdr-041-t1-scratch-inter-agent-context.md +0 -0
  134. {conexus-4.2.2 → conexus-4.3.0}/docs/rdr/rdr-042-agenticscholar-enhancements.md +0 -0
  135. {conexus-4.2.2 → conexus-4.3.0}/docs/rdr/rdr-043-plan-enricher-scope.md +0 -0
  136. {conexus-4.2.2 → conexus-4.3.0}/docs/rdr/rdr-044-math-aware-pdf-extraction.md +0 -0
  137. {conexus-4.2.2 → conexus-4.3.0}/docs/rdr/rdr-045-post-implementation-verification.md +0 -0
  138. {conexus-4.2.2 → conexus-4.3.0}/docs/rdr/rdr-046-mineru-server-backed-extraction.md +0 -0
  139. {conexus-4.2.2 → conexus-4.3.0}/docs/rdr/rdr-047-large-pdf-extraction-resilience.md +0 -0
  140. {conexus-4.2.2 → conexus-4.3.0}/docs/rdr/rdr-048-streaming-pdf-pipeline.md +0 -0
  141. {conexus-4.2.2 → conexus-4.3.0}/docs/rdr/rdr-049-consolidation-plan.md +0 -0
  142. {conexus-4.2.2 → conexus-4.3.0}/docs/rdr/rdr-049-git-backed-catalog.md +0 -0
  143. {conexus-4.2.2 → conexus-4.3.0}/docs/rdr/rdr-050-knowledge-graph-query-planning.md +0 -0
  144. {conexus-4.2.2 → conexus-4.3.0}/docs/rdr/rdr-051-link-lifecycle.md +0 -0
  145. {conexus-4.2.2 → conexus-4.3.0}/docs/rdr/rdr-052-catalog-first-query-routing.md +0 -0
  146. {conexus-4.2.2 → conexus-4.3.0}/docs/rdr/rdr-053-xanadu-fidelity.md +0 -0
  147. {conexus-4.2.2 → conexus-4.3.0}/docs/rdr/rdr-054-chunk-boundary-equation-splitting.md +0 -0
  148. {conexus-4.2.2 → conexus-4.3.0}/docs/rdr/rdr-055-section-type-metadata-quality-scoring.md +0 -0
  149. {conexus-4.2.2 → conexus-4.3.0}/docs/rdr/rdr-056-search-robustness-result-clustering.md +0 -0
  150. {conexus-4.2.2 → conexus-4.3.0}/docs/rdr/rdr-057-progressive-formalization-memory-tiers.md +0 -0
  151. {conexus-4.2.2 → conexus-4.3.0}/docs/rdr/rdr-058-pipeline-orchestration-plan-reuse.md +0 -0
  152. {conexus-4.2.2 → conexus-4.3.0}/docs/rdr/rdr-059-code-search-embedding-mismatch.md +0 -0
  153. {conexus-4.2.2 → conexus-4.3.0}/docs/rdr/rdr-060-catalog-path-rationalization-link-usability.md +0 -0
  154. {conexus-4.2.2 → conexus-4.3.0}/docs/rdr/rdr-061-literature-grounded-search-knowledge-enhancement.md +0 -0
  155. {conexus-4.2.2 → conexus-4.3.0}/docs/rdr/rdr-062-mcp-interface-tiering.md +0 -0
  156. {conexus-4.2.2 → conexus-4.3.0}/docs/rdr/rdr-063-t2-domain-split.md +0 -0
  157. {conexus-4.2.2 → conexus-4.3.0}/docs/rdr/rdr-064-nx-console-embedded-web-ui.md +0 -0
  158. {conexus-4.2.2 → conexus-4.3.0}/docs/rdr/rdr-065-close-time-funnel-hardening.md +0 -0
  159. {conexus-4.2.2 → conexus-4.3.0}/docs/rdr/rdr-066-composition-smoke-probe-at-coordinator-beads.md +0 -0
  160. {conexus-4.2.2 → conexus-4.3.0}/docs/rdr/rdr-067-cross-project-rdr-audit-loop.md +0 -0
  161. {conexus-4.2.2 → conexus-4.3.0}/docs/rdr/rdr-068-dimensional-contracts-at-enrichment.md +0 -0
  162. {conexus-4.2.2 → conexus-4.3.0}/docs/rdr/rdr-069-automatic-substantive-critic-at-close.md +0 -0
  163. {conexus-4.2.2 → conexus-4.3.0}/docs/rdr/rdr-070-incremental-taxonomy-clustered-search.md +0 -0
  164. {conexus-4.2.2 → conexus-4.3.0}/docs/rdr/rdr-071-query-sanitizer-permanence-mode.md +0 -0
  165. {conexus-4.2.2 → conexus-4.3.0}/docs/rdr/rdr-072-progressive-context-loading.md +0 -0
  166. {conexus-4.2.2 → conexus-4.3.0}/docs/rdr/rdr-073-temporal-entity-knowledge-graph.md +0 -0
  167. {conexus-4.2.2 → conexus-4.3.0}/docs/rdr/rdr-074-permanence-mode.md +0 -0
  168. {conexus-4.2.2 → conexus-4.3.0}/docs/rdr/rdr-075-cross-collection-topic-projection.md +0 -0
  169. {conexus-4.2.2 → conexus-4.3.0}/docs/rdr/rdr-076-idempotent-upgrade-mechanism.md +0 -0
  170. {conexus-4.2.2 → conexus-4.3.0}/docs/rdr-nexus-integration.md +0 -0
  171. {conexus-4.2.2 → conexus-4.3.0}/docs/rdr-overview.md +0 -0
  172. {conexus-4.2.2 → conexus-4.3.0}/docs/rdr-templates.md +0 -0
  173. {conexus-4.2.2 → conexus-4.3.0}/docs/rdr-workflow.md +0 -0
  174. {conexus-4.2.2 → conexus-4.3.0}/docs/repo-indexing.md +0 -0
  175. {conexus-4.2.2 → conexus-4.3.0}/docs/xanadu-in-nexus.md +0 -0
  176. {conexus-4.2.2 → conexus-4.3.0}/nx/.mcp.json +0 -0
  177. {conexus-4.2.2 → conexus-4.3.0}/nx/README.md +0 -0
  178. {conexus-4.2.2 → conexus-4.3.0}/nx/agents/_shared/CONTEXT_PROTOCOL.md +0 -0
  179. {conexus-4.2.2 → conexus-4.3.0}/nx/agents/_shared/ERROR_HANDLING.md +0 -0
  180. {conexus-4.2.2 → conexus-4.3.0}/nx/agents/_shared/MAINTENANCE.md +0 -0
  181. {conexus-4.2.2 → conexus-4.3.0}/nx/agents/_shared/README.md +0 -0
  182. {conexus-4.2.2 → conexus-4.3.0}/nx/agents/_shared/RELAY_TEMPLATE.md +0 -0
  183. {conexus-4.2.2 → conexus-4.3.0}/nx/agents/analytical-operator.md +0 -0
  184. {conexus-4.2.2 → conexus-4.3.0}/nx/agents/architect-planner.md +0 -0
  185. {conexus-4.2.2 → conexus-4.3.0}/nx/agents/code-review-expert.md +0 -0
  186. {conexus-4.2.2 → conexus-4.3.0}/nx/agents/codebase-deep-analyzer.md +0 -0
  187. {conexus-4.2.2 → conexus-4.3.0}/nx/agents/debugger.md +0 -0
  188. {conexus-4.2.2 → conexus-4.3.0}/nx/agents/deep-analyst.md +0 -0
  189. {conexus-4.2.2 → conexus-4.3.0}/nx/agents/deep-research-synthesizer.md +0 -0
  190. {conexus-4.2.2 → conexus-4.3.0}/nx/agents/developer.md +0 -0
  191. {conexus-4.2.2 → conexus-4.3.0}/nx/agents/knowledge-tidier.md +0 -0
  192. {conexus-4.2.2 → conexus-4.3.0}/nx/agents/pdf-chromadb-processor.md +0 -0
  193. {conexus-4.2.2 → conexus-4.3.0}/nx/agents/plan-auditor.md +0 -0
  194. {conexus-4.2.2 → conexus-4.3.0}/nx/agents/plan-enricher.md +0 -0
  195. {conexus-4.2.2 → conexus-4.3.0}/nx/agents/query-planner.md +0 -0
  196. {conexus-4.2.2 → conexus-4.3.0}/nx/agents/strategic-planner.md +0 -0
  197. {conexus-4.2.2 → conexus-4.3.0}/nx/agents/substantive-critic.md +0 -0
  198. {conexus-4.2.2 → conexus-4.3.0}/nx/agents/test-validator.md +0 -0
  199. {conexus-4.2.2 → conexus-4.3.0}/nx/commands/analyze-code.md +0 -0
  200. {conexus-4.2.2 → conexus-4.3.0}/nx/commands/architecture.md +0 -0
  201. {conexus-4.2.2 → conexus-4.3.0}/nx/commands/create-plan.md +0 -0
  202. {conexus-4.2.2 → conexus-4.3.0}/nx/commands/debug.md +0 -0
  203. {conexus-4.2.2 → conexus-4.3.0}/nx/commands/deep-analysis.md +0 -0
  204. {conexus-4.2.2 → conexus-4.3.0}/nx/commands/enrich-plan.md +0 -0
  205. {conexus-4.2.2 → conexus-4.3.0}/nx/commands/implement.md +0 -0
  206. {conexus-4.2.2 → conexus-4.3.0}/nx/commands/knowledge-tidy.md +0 -0
  207. {conexus-4.2.2 → conexus-4.3.0}/nx/commands/nx-preflight.md +0 -0
  208. {conexus-4.2.2 → conexus-4.3.0}/nx/commands/pdf-process.md +0 -0
  209. {conexus-4.2.2 → conexus-4.3.0}/nx/commands/plan-audit.md +0 -0
  210. {conexus-4.2.2 → conexus-4.3.0}/nx/commands/rdr-accept.md +0 -0
  211. {conexus-4.2.2 → conexus-4.3.0}/nx/commands/rdr-audit.md +0 -0
  212. {conexus-4.2.2 → conexus-4.3.0}/nx/commands/rdr-close.md +0 -0
  213. {conexus-4.2.2 → conexus-4.3.0}/nx/commands/rdr-create.md +0 -0
  214. {conexus-4.2.2 → conexus-4.3.0}/nx/commands/rdr-gate.md +0 -0
  215. {conexus-4.2.2 → conexus-4.3.0}/nx/commands/rdr-list.md +0 -0
  216. {conexus-4.2.2 → conexus-4.3.0}/nx/commands/rdr-research.md +0 -0
  217. {conexus-4.2.2 → conexus-4.3.0}/nx/commands/rdr-show.md +0 -0
  218. {conexus-4.2.2 → conexus-4.3.0}/nx/commands/research.md +0 -0
  219. {conexus-4.2.2 → conexus-4.3.0}/nx/commands/review-code.md +0 -0
  220. {conexus-4.2.2 → conexus-4.3.0}/nx/commands/substantive-critique.md +0 -0
  221. {conexus-4.2.2 → conexus-4.3.0}/nx/commands/test-validate.md +0 -0
  222. {conexus-4.2.2 → conexus-4.3.0}/nx/hooks/hooks.json +0 -0
  223. {conexus-4.2.2 → conexus-4.3.0}/nx/hooks/scripts/auto-approve-nx-mcp.sh +0 -0
  224. {conexus-4.2.2 → conexus-4.3.0}/nx/hooks/scripts/divergence-language-guard.sh +0 -0
  225. {conexus-4.2.2 → conexus-4.3.0}/nx/hooks/scripts/post_compact_hook.sh +0 -0
  226. {conexus-4.2.2 → conexus-4.3.0}/nx/hooks/scripts/pre_close_verification_hook.sh +0 -0
  227. {conexus-4.2.2 → conexus-4.3.0}/nx/hooks/scripts/rdr_hook.py +0 -0
  228. {conexus-4.2.2 → conexus-4.3.0}/nx/hooks/scripts/read_verification_config.py +0 -0
  229. {conexus-4.2.2 → conexus-4.3.0}/nx/hooks/scripts/session_start_hook.py +0 -0
  230. {conexus-4.2.2 → conexus-4.3.0}/nx/hooks/scripts/stop_failure_hook.py +0 -0
  231. {conexus-4.2.2 → conexus-4.3.0}/nx/hooks/scripts/stop_verification_hook.sh +0 -0
  232. {conexus-4.2.2 → conexus-4.3.0}/nx/hooks/scripts/subagent-start.sh +0 -0
  233. {conexus-4.2.2 → conexus-4.3.0}/nx/hooks/scripts/t2_prefix_scan.py +0 -0
  234. {conexus-4.2.2 → conexus-4.3.0}/nx/registry.yaml +0 -0
  235. {conexus-4.2.2 → conexus-4.3.0}/nx/resources/rdr/README-TEMPLATE.md +0 -0
  236. {conexus-4.2.2 → conexus-4.3.0}/nx/resources/rdr/TEMPLATE.md +0 -0
  237. {conexus-4.2.2 → conexus-4.3.0}/nx/resources/rdr/post-mortem/TEMPLATE.md +0 -0
  238. {conexus-4.2.2 → conexus-4.3.0}/nx/resources/rdr_process/INCIDENT-TEMPLATE.md +0 -0
  239. {conexus-4.2.2 → conexus-4.3.0}/nx/skills/architecture/SKILL.md +0 -0
  240. {conexus-4.2.2 → conexus-4.3.0}/nx/skills/brainstorming-gate/SKILL.md +0 -0
  241. {conexus-4.2.2 → conexus-4.3.0}/nx/skills/catalog/SKILL.md +0 -0
  242. {conexus-4.2.2 → conexus-4.3.0}/nx/skills/cli-controller/SKILL.md +0 -0
  243. {conexus-4.2.2 → conexus-4.3.0}/nx/skills/code-review/SKILL.md +0 -0
  244. {conexus-4.2.2 → conexus-4.3.0}/nx/skills/codebase-analysis/SKILL.md +0 -0
  245. {conexus-4.2.2 → conexus-4.3.0}/nx/skills/composition-probe/SKILL.md +0 -0
  246. {conexus-4.2.2 → conexus-4.3.0}/nx/skills/debugging/SKILL.md +0 -0
  247. {conexus-4.2.2 → conexus-4.3.0}/nx/skills/deep-analysis/SKILL.md +0 -0
  248. {conexus-4.2.2 → conexus-4.3.0}/nx/skills/development/SKILL.md +0 -0
  249. {conexus-4.2.2 → conexus-4.3.0}/nx/skills/enrich-plan/SKILL.md +0 -0
  250. {conexus-4.2.2 → conexus-4.3.0}/nx/skills/finishing-branch/SKILL.md +0 -0
  251. {conexus-4.2.2 → conexus-4.3.0}/nx/skills/git-worktrees/SKILL.md +0 -0
  252. {conexus-4.2.2 → conexus-4.3.0}/nx/skills/knowledge-tidying/SKILL.md +0 -0
  253. {conexus-4.2.2 → conexus-4.3.0}/nx/skills/nexus/SKILL.md +0 -0
  254. {conexus-4.2.2 → conexus-4.3.0}/nx/skills/nexus/reference.md +0 -0
  255. {conexus-4.2.2 → conexus-4.3.0}/nx/skills/orchestration/SKILL.md +0 -0
  256. {conexus-4.2.2 → conexus-4.3.0}/nx/skills/orchestration/reference.md +0 -0
  257. {conexus-4.2.2 → conexus-4.3.0}/nx/skills/pdf-processing/SKILL.md +0 -0
  258. {conexus-4.2.2 → conexus-4.3.0}/nx/skills/plan-validation/SKILL.md +0 -0
  259. {conexus-4.2.2 → conexus-4.3.0}/nx/skills/query/SKILL.md +0 -0
  260. {conexus-4.2.2 → conexus-4.3.0}/nx/skills/rdr-accept/SKILL.md +0 -0
  261. {conexus-4.2.2 → conexus-4.3.0}/nx/skills/rdr-audit/SKILL.md +0 -0
  262. {conexus-4.2.2 → conexus-4.3.0}/nx/skills/rdr-close/SKILL.md +0 -0
  263. {conexus-4.2.2 → conexus-4.3.0}/nx/skills/rdr-create/SKILL.md +0 -0
  264. {conexus-4.2.2 → conexus-4.3.0}/nx/skills/rdr-gate/SKILL.md +0 -0
  265. {conexus-4.2.2 → conexus-4.3.0}/nx/skills/rdr-list/SKILL.md +0 -0
  266. {conexus-4.2.2 → conexus-4.3.0}/nx/skills/rdr-research/SKILL.md +0 -0
  267. {conexus-4.2.2 → conexus-4.3.0}/nx/skills/rdr-show/SKILL.md +0 -0
  268. {conexus-4.2.2 → conexus-4.3.0}/nx/skills/receiving-review/SKILL.md +0 -0
  269. {conexus-4.2.2 → conexus-4.3.0}/nx/skills/research-synthesis/SKILL.md +0 -0
  270. {conexus-4.2.2 → conexus-4.3.0}/nx/skills/serena-code-nav/SKILL.md +0 -0
  271. {conexus-4.2.2 → conexus-4.3.0}/nx/skills/strategic-planning/SKILL.md +0 -0
  272. {conexus-4.2.2 → conexus-4.3.0}/nx/skills/substantive-critique/SKILL.md +0 -0
  273. {conexus-4.2.2 → conexus-4.3.0}/nx/skills/test-validation/SKILL.md +0 -0
  274. {conexus-4.2.2 → conexus-4.3.0}/nx/skills/using-nx-skills/SKILL.md +0 -0
  275. {conexus-4.2.2 → conexus-4.3.0}/nx/skills/writing-nx-skills/SKILL.md +0 -0
  276. {conexus-4.2.2 → conexus-4.3.0}/scripts/batch-label-taxonomy.py +0 -0
  277. {conexus-4.2.2 → conexus-4.3.0}/scripts/cron/README.md +0 -0
  278. {conexus-4.2.2 → conexus-4.3.0}/scripts/cron/rdr-audit.crontab +0 -0
  279. {conexus-4.2.2 → conexus-4.3.0}/scripts/cron-rdr-audit.sh +0 -0
  280. {conexus-4.2.2 → conexus-4.3.0}/scripts/launchd/README.md +0 -0
  281. {conexus-4.2.2 → conexus-4.3.0}/scripts/launchd/com.nexus.rdr-audit.PROJECT.plist +0 -0
  282. {conexus-4.2.2 → conexus-4.3.0}/scripts/reinstall-tool.sh +0 -0
  283. {conexus-4.2.2 → conexus-4.3.0}/scripts/smoke-test-taxonomy.py +0 -0
  284. {conexus-4.2.2 → conexus-4.3.0}/sn/.mcp.json +0 -0
  285. {conexus-4.2.2 → conexus-4.3.0}/sn/README.md +0 -0
  286. {conexus-4.2.2 → conexus-4.3.0}/sn/hooks/hooks.json +0 -0
  287. {conexus-4.2.2 → conexus-4.3.0}/sn/hooks/scripts/auto-approve-sn-mcp.sh +0 -0
  288. {conexus-4.2.2 → conexus-4.3.0}/sn/hooks/scripts/mcp-inject.sh +0 -0
  289. {conexus-4.2.2 → conexus-4.3.0}/sn/hooks/scripts/session-start.sh +0 -0
  290. {conexus-4.2.2 → conexus-4.3.0}/src/nexus/__init__.py +0 -0
  291. {conexus-4.2.2 → conexus-4.3.0}/src/nexus/bib_enricher.py +0 -0
  292. {conexus-4.2.2 → conexus-4.3.0}/src/nexus/catalog/__init__.py +0 -0
  293. {conexus-4.2.2 → conexus-4.3.0}/src/nexus/catalog/auto_linker.py +0 -0
  294. {conexus-4.2.2 → conexus-4.3.0}/src/nexus/catalog/catalog.py +0 -0
  295. {conexus-4.2.2 → conexus-4.3.0}/src/nexus/catalog/catalog_db.py +0 -0
  296. {conexus-4.2.2 → conexus-4.3.0}/src/nexus/catalog/consolidation.py +0 -0
  297. {conexus-4.2.2 → conexus-4.3.0}/src/nexus/catalog/link_generator.py +0 -0
  298. {conexus-4.2.2 → conexus-4.3.0}/src/nexus/catalog/tumbler.py +0 -0
  299. {conexus-4.2.2 → conexus-4.3.0}/src/nexus/checkpoint.py +0 -0
  300. {conexus-4.2.2 → conexus-4.3.0}/src/nexus/chunker.py +0 -0
  301. {conexus-4.2.2 → conexus-4.3.0}/src/nexus/classifier.py +0 -0
  302. {conexus-4.2.2 → conexus-4.3.0}/src/nexus/cli.py +0 -0
  303. {conexus-4.2.2 → conexus-4.3.0}/src/nexus/code_indexer.py +0 -0
  304. {conexus-4.2.2 → conexus-4.3.0}/src/nexus/commands/__init__.py +0 -0
  305. {conexus-4.2.2 → conexus-4.3.0}/src/nexus/commands/_helpers.py +0 -0
  306. {conexus-4.2.2 → conexus-4.3.0}/src/nexus/commands/_provision.py +0 -0
  307. {conexus-4.2.2 → conexus-4.3.0}/src/nexus/commands/catalog.py +0 -0
  308. {conexus-4.2.2 → conexus-4.3.0}/src/nexus/commands/collection.py +0 -0
  309. {conexus-4.2.2 → conexus-4.3.0}/src/nexus/commands/config_cmd.py +0 -0
  310. {conexus-4.2.2 → conexus-4.3.0}/src/nexus/commands/console.py +0 -0
  311. {conexus-4.2.2 → conexus-4.3.0}/src/nexus/commands/context_cmd.py +0 -0
  312. {conexus-4.2.2 → conexus-4.3.0}/src/nexus/commands/doctor.py +0 -0
  313. {conexus-4.2.2 → conexus-4.3.0}/src/nexus/commands/enrich.py +0 -0
  314. {conexus-4.2.2 → conexus-4.3.0}/src/nexus/commands/hook.py +0 -0
  315. {conexus-4.2.2 → conexus-4.3.0}/src/nexus/commands/hooks.py +0 -0
  316. {conexus-4.2.2 → conexus-4.3.0}/src/nexus/commands/index.py +0 -0
  317. {conexus-4.2.2 → conexus-4.3.0}/src/nexus/commands/memory.py +0 -0
  318. {conexus-4.2.2 → conexus-4.3.0}/src/nexus/commands/mineru.py +0 -0
  319. {conexus-4.2.2 → conexus-4.3.0}/src/nexus/commands/scratch.py +0 -0
  320. {conexus-4.2.2 → conexus-4.3.0}/src/nexus/commands/search_cmd.py +0 -0
  321. {conexus-4.2.2 → conexus-4.3.0}/src/nexus/commands/store.py +0 -0
  322. {conexus-4.2.2 → conexus-4.3.0}/src/nexus/commands/upgrade.py +0 -0
  323. {conexus-4.2.2 → conexus-4.3.0}/src/nexus/config.py +0 -0
  324. {conexus-4.2.2 → conexus-4.3.0}/src/nexus/console/__init__.py +0 -0
  325. {conexus-4.2.2 → conexus-4.3.0}/src/nexus/console/app.py +0 -0
  326. {conexus-4.2.2 → conexus-4.3.0}/src/nexus/console/config.py +0 -0
  327. {conexus-4.2.2 → conexus-4.3.0}/src/nexus/console/routes/__init__.py +0 -0
  328. {conexus-4.2.2 → conexus-4.3.0}/src/nexus/console/routes/activity.py +0 -0
  329. {conexus-4.2.2 → conexus-4.3.0}/src/nexus/console/routes/campaigns.py +0 -0
  330. {conexus-4.2.2 → conexus-4.3.0}/src/nexus/console/routes/health.py +0 -0
  331. {conexus-4.2.2 → conexus-4.3.0}/src/nexus/console/routes/partials.py +0 -0
  332. {conexus-4.2.2 → conexus-4.3.0}/src/nexus/console/static/alpine.min.js +0 -0
  333. {conexus-4.2.2 → conexus-4.3.0}/src/nexus/console/static/console.css +0 -0
  334. {conexus-4.2.2 → conexus-4.3.0}/src/nexus/console/static/htmx.min.js +0 -0
  335. {conexus-4.2.2 → conexus-4.3.0}/src/nexus/console/static/pico.min.css +0 -0
  336. {conexus-4.2.2 → conexus-4.3.0}/src/nexus/console/templates/activity/_detail.html +0 -0
  337. {conexus-4.2.2 → conexus-4.3.0}/src/nexus/console/templates/activity/_stream.html +0 -0
  338. {conexus-4.2.2 → conexus-4.3.0}/src/nexus/console/templates/activity/index.html +0 -0
  339. {conexus-4.2.2 → conexus-4.3.0}/src/nexus/console/templates/base.html +0 -0
  340. {conexus-4.2.2 → conexus-4.3.0}/src/nexus/console/templates/campaigns/detail.html +0 -0
  341. {conexus-4.2.2 → conexus-4.3.0}/src/nexus/console/templates/campaigns/index.html +0 -0
  342. {conexus-4.2.2 → conexus-4.3.0}/src/nexus/console/templates/health/_cards.html +0 -0
  343. {conexus-4.2.2 → conexus-4.3.0}/src/nexus/console/templates/health/index.html +0 -0
  344. {conexus-4.2.2 → conexus-4.3.0}/src/nexus/console/watchers.py +0 -0
  345. {conexus-4.2.2 → conexus-4.3.0}/src/nexus/context.py +0 -0
  346. {conexus-4.2.2 → conexus-4.3.0}/src/nexus/db/__init__.py +0 -0
  347. {conexus-4.2.2 → conexus-4.3.0}/src/nexus/db/chroma_quotas.py +0 -0
  348. {conexus-4.2.2 → conexus-4.3.0}/src/nexus/db/local_ef.py +0 -0
  349. {conexus-4.2.2 → conexus-4.3.0}/src/nexus/db/t1.py +0 -0
  350. {conexus-4.2.2 → conexus-4.3.0}/src/nexus/db/t2/__init__.py +0 -0
  351. {conexus-4.2.2 → conexus-4.3.0}/src/nexus/db/t2/memory_store.py +0 -0
  352. {conexus-4.2.2 → conexus-4.3.0}/src/nexus/db/t2/plan_library.py +0 -0
  353. {conexus-4.2.2 → conexus-4.3.0}/src/nexus/db/t2/telemetry.py +0 -0
  354. {conexus-4.2.2 → conexus-4.3.0}/src/nexus/db/t3.py +0 -0
  355. {conexus-4.2.2 → conexus-4.3.0}/src/nexus/doc_indexer.py +0 -0
  356. {conexus-4.2.2 → conexus-4.3.0}/src/nexus/errors.py +0 -0
  357. {conexus-4.2.2 → conexus-4.3.0}/src/nexus/exporter.py +0 -0
  358. {conexus-4.2.2 → conexus-4.3.0}/src/nexus/filters.py +0 -0
  359. {conexus-4.2.2 → conexus-4.3.0}/src/nexus/formatters.py +0 -0
  360. {conexus-4.2.2 → conexus-4.3.0}/src/nexus/frecency.py +0 -0
  361. {conexus-4.2.2 → conexus-4.3.0}/src/nexus/health.py +0 -0
  362. {conexus-4.2.2 → conexus-4.3.0}/src/nexus/hooks.py +0 -0
  363. {conexus-4.2.2 → conexus-4.3.0}/src/nexus/index_context.py +0 -0
  364. {conexus-4.2.2 → conexus-4.3.0}/src/nexus/indexer.py +0 -0
  365. {conexus-4.2.2 → conexus-4.3.0}/src/nexus/indexer_utils.py +0 -0
  366. {conexus-4.2.2 → conexus-4.3.0}/src/nexus/languages.py +0 -0
  367. {conexus-4.2.2 → conexus-4.3.0}/src/nexus/logging_setup.py +0 -0
  368. {conexus-4.2.2 → conexus-4.3.0}/src/nexus/mcp/__init__.py +0 -0
  369. {conexus-4.2.2 → conexus-4.3.0}/src/nexus/mcp/catalog.py +0 -0
  370. {conexus-4.2.2 → conexus-4.3.0}/src/nexus/mcp/core.py +0 -0
  371. {conexus-4.2.2 → conexus-4.3.0}/src/nexus/mcp_server.py +0 -0
  372. {conexus-4.2.2 → conexus-4.3.0}/src/nexus/md_chunker.py +0 -0
  373. {conexus-4.2.2 → conexus-4.3.0}/src/nexus/pdf_chunker.py +0 -0
  374. {conexus-4.2.2 → conexus-4.3.0}/src/nexus/pdf_extractor.py +0 -0
  375. {conexus-4.2.2 → conexus-4.3.0}/src/nexus/pipeline_buffer.py +0 -0
  376. {conexus-4.2.2 → conexus-4.3.0}/src/nexus/pipeline_stages.py +0 -0
  377. {conexus-4.2.2 → conexus-4.3.0}/src/nexus/prose_indexer.py +0 -0
  378. {conexus-4.2.2 → conexus-4.3.0}/src/nexus/registry.py +0 -0
  379. {conexus-4.2.2 → conexus-4.3.0}/src/nexus/retry.py +0 -0
  380. {conexus-4.2.2 → conexus-4.3.0}/src/nexus/ripgrep_cache.py +0 -0
  381. {conexus-4.2.2 → conexus-4.3.0}/src/nexus/scoring.py +0 -0
  382. {conexus-4.2.2 → conexus-4.3.0}/src/nexus/search_clusterer.py +0 -0
  383. {conexus-4.2.2 → conexus-4.3.0}/src/nexus/search_engine.py +0 -0
  384. {conexus-4.2.2 → conexus-4.3.0}/src/nexus/session.py +0 -0
  385. {conexus-4.2.2 → conexus-4.3.0}/src/nexus/taxonomy.py +0 -0
  386. {conexus-4.2.2 → conexus-4.3.0}/src/nexus/ttl.py +0 -0
  387. {conexus-4.2.2 → conexus-4.3.0}/src/nexus/types.py +0 -0
  388. {conexus-4.2.2 → conexus-4.3.0}/tests/__init__.py +0 -0
  389. {conexus-4.2.2 → conexus-4.3.0}/tests/__snapshots__/test_search_cmd.ambr +0 -0
  390. {conexus-4.2.2 → conexus-4.3.0}/tests/benchmarks/__init__.py +0 -0
  391. {conexus-4.2.2 → conexus-4.3.0}/tests/benchmarks/corpus.json +0 -0
  392. {conexus-4.2.2 → conexus-4.3.0}/tests/benchmarks/queries.json +0 -0
  393. {conexus-4.2.2 → conexus-4.3.0}/tests/benchmarks/test_retrieval_ndcg.py +0 -0
  394. {conexus-4.2.2 → conexus-4.3.0}/tests/conftest.py +0 -0
  395. {conexus-4.2.2 → conexus-4.3.0}/tests/e2e/auth-login.sh +0 -0
  396. {conexus-4.2.2 → conexus-4.3.0}/tests/e2e/lib.sh +0 -0
  397. {conexus-4.2.2 → conexus-4.3.0}/tests/e2e/run.sh +0 -0
  398. {conexus-4.2.2 → conexus-4.3.0}/tests/e2e/sandbox.sh +0 -0
  399. {conexus-4.2.2 → conexus-4.3.0}/tests/e2e/scenarios/00_debug_load.sh +0 -0
  400. {conexus-4.2.2 → conexus-4.3.0}/tests/e2e/scenarios/01_smoke.sh +0 -0
  401. {conexus-4.2.2 → conexus-4.3.0}/tests/e2e/scenarios/02_sequential_thinking.sh +0 -0
  402. {conexus-4.2.2 → conexus-4.3.0}/tests/e2e/scenarios/03_skills.sh +0 -0
  403. {conexus-4.2.2 → conexus-4.3.0}/tests/hooks/__init__.py +0 -0
  404. {conexus-4.2.2 → conexus-4.3.0}/tests/hooks/test_permission_request_hooks.py +0 -0
  405. {conexus-4.2.2 → conexus-4.3.0}/tests/hooks/test_post_compact_hook.py +0 -0
  406. {conexus-4.2.2 → conexus-4.3.0}/tests/hooks/test_pre_close_verification_hook.py +0 -0
  407. {conexus-4.2.2 → conexus-4.3.0}/tests/hooks/test_read_verification_config.py +0 -0
  408. {conexus-4.2.2 → conexus-4.3.0}/tests/hooks/test_stop_failure_hook.py +0 -0
  409. {conexus-4.2.2 → conexus-4.3.0}/tests/hooks/test_stop_verification_hook.py +0 -0
  410. {conexus-4.2.2 → conexus-4.3.0}/tests/hooks/test_verification_integration.py +0 -0
  411. {conexus-4.2.2 → conexus-4.3.0}/tests/test_activity_stream.py +0 -0
  412. {conexus-4.2.2 → conexus-4.3.0}/tests/test_ast_languages.py +0 -0
  413. {conexus-4.2.2 → conexus-4.3.0}/tests/test_auto_linker.py +0 -0
  414. {conexus-4.2.2 → conexus-4.3.0}/tests/test_backfill_hash.py +0 -0
  415. {conexus-4.2.2 → conexus-4.3.0}/tests/test_bib_enricher.py +0 -0
  416. {conexus-4.2.2 → conexus-4.3.0}/tests/test_campaigns_panel.py +0 -0
  417. {conexus-4.2.2 → conexus-4.3.0}/tests/test_catalog.py +0 -0
  418. {conexus-4.2.2 → conexus-4.3.0}/tests/test_catalog_backfill.py +0 -0
  419. {conexus-4.2.2 → conexus-4.3.0}/tests/test_catalog_cli.py +0 -0
  420. {conexus-4.2.2 → conexus-4.3.0}/tests/test_catalog_consolidation.py +0 -0
  421. {conexus-4.2.2 → conexus-4.3.0}/tests/test_catalog_db.py +0 -0
  422. {conexus-4.2.2 → conexus-4.3.0}/tests/test_catalog_e2e.py +0 -0
  423. {conexus-4.2.2 → conexus-4.3.0}/tests/test_catalog_git.py +0 -0
  424. {conexus-4.2.2 → conexus-4.3.0}/tests/test_catalog_indexer_hook.py +0 -0
  425. {conexus-4.2.2 → conexus-4.3.0}/tests/test_catalog_jsonl.py +0 -0
  426. {conexus-4.2.2 → conexus-4.3.0}/tests/test_catalog_knowledge_hook.py +0 -0
  427. {conexus-4.2.2 → conexus-4.3.0}/tests/test_catalog_link_generation.py +0 -0
  428. {conexus-4.2.2 → conexus-4.3.0}/tests/test_catalog_links.py +0 -0
  429. {conexus-4.2.2 → conexus-4.3.0}/tests/test_catalog_mcp.py +0 -0
  430. {conexus-4.2.2 → conexus-4.3.0}/tests/test_catalog_path.py +0 -0
  431. {conexus-4.2.2 → conexus-4.3.0}/tests/test_catalog_pdf_hook.py +0 -0
  432. {conexus-4.2.2 → conexus-4.3.0}/tests/test_catalog_prefilter.py +0 -0
  433. {conexus-4.2.2 → conexus-4.3.0}/tests/test_checkpoint.py +0 -0
  434. {conexus-4.2.2 → conexus-4.3.0}/tests/test_chroma_quotas.py +0 -0
  435. {conexus-4.2.2 → conexus-4.3.0}/tests/test_chroma_retry.py +0 -0
  436. {conexus-4.2.2 → conexus-4.3.0}/tests/test_chunker.py +0 -0
  437. {conexus-4.2.2 → conexus-4.3.0}/tests/test_chunker_ast_languages.py +0 -0
  438. {conexus-4.2.2 → conexus-4.3.0}/tests/test_classifier.py +0 -0
  439. {conexus-4.2.2 → conexus-4.3.0}/tests/test_cli_registration.py +0 -0
  440. {conexus-4.2.2 → conexus-4.3.0}/tests/test_collection_cmd.py +0 -0
  441. {conexus-4.2.2 → conexus-4.3.0}/tests/test_config.py +0 -0
  442. {conexus-4.2.2 → conexus-4.3.0}/tests/test_config_cmd.py +0 -0
  443. {conexus-4.2.2 → conexus-4.3.0}/tests/test_console_app.py +0 -0
  444. {conexus-4.2.2 → conexus-4.3.0}/tests/test_console_deps.py +0 -0
  445. {conexus-4.2.2 → conexus-4.3.0}/tests/test_context.py +0 -0
  446. {conexus-4.2.2 → conexus-4.3.0}/tests/test_contradiction_flag.py +0 -0
  447. {conexus-4.2.2 → conexus-4.3.0}/tests/test_corpus.py +0 -0
  448. {conexus-4.2.2 → conexus-4.3.0}/tests/test_distance_thresholds.py +0 -0
  449. {conexus-4.2.2 → conexus-4.3.0}/tests/test_doc_indexer.py +0 -0
  450. {conexus-4.2.2 → conexus-4.3.0}/tests/test_doc_indexer_hash_sync.py +0 -0
  451. {conexus-4.2.2 → conexus-4.3.0}/tests/test_doc_indexer_pagination.py +0 -0
  452. {conexus-4.2.2 → conexus-4.3.0}/tests/test_doctor_cmd.py +0 -0
  453. {conexus-4.2.2 → conexus-4.3.0}/tests/test_doctor_integrity.py +0 -0
  454. {conexus-4.2.2 → conexus-4.3.0}/tests/test_e2e.py +0 -0
  455. {conexus-4.2.2 → conexus-4.3.0}/tests/test_enrich_command.py +0 -0
  456. {conexus-4.2.2 → conexus-4.3.0}/tests/test_exporter.py +0 -0
  457. {conexus-4.2.2 → conexus-4.3.0}/tests/test_formatters.py +0 -0
  458. {conexus-4.2.2 → conexus-4.3.0}/tests/test_frecency.py +0 -0
  459. {conexus-4.2.2 → conexus-4.3.0}/tests/test_git_hooks.py +0 -0
  460. {conexus-4.2.2 → conexus-4.3.0}/tests/test_health.py +0 -0
  461. {conexus-4.2.2 → conexus-4.3.0}/tests/test_health_panel.py +0 -0
  462. {conexus-4.2.2 → conexus-4.3.0}/tests/test_hooks.py +0 -0
  463. {conexus-4.2.2 → conexus-4.3.0}/tests/test_hybrid_boost.py +0 -0
  464. {conexus-4.2.2 → conexus-4.3.0}/tests/test_index_cmd.py +0 -0
  465. {conexus-4.2.2 → conexus-4.3.0}/tests/test_index_lock.py +0 -0
  466. {conexus-4.2.2 → conexus-4.3.0}/tests/test_index_pdf_batch.py +0 -0
  467. {conexus-4.2.2 → conexus-4.3.0}/tests/test_index_rdr_cmd.py +0 -0
  468. {conexus-4.2.2 → conexus-4.3.0}/tests/test_index_reminder.py +0 -0
  469. {conexus-4.2.2 → conexus-4.3.0}/tests/test_index_taxonomy.py +0 -0
  470. {conexus-4.2.2 → conexus-4.3.0}/tests/test_indexer.py +0 -0
  471. {conexus-4.2.2 → conexus-4.3.0}/tests/test_indexer_chunk_flow.py +0 -0
  472. {conexus-4.2.2 → conexus-4.3.0}/tests/test_indexer_e2e.py +0 -0
  473. {conexus-4.2.2 → conexus-4.3.0}/tests/test_indexer_modules.py +0 -0
  474. {conexus-4.2.2 → conexus-4.3.0}/tests/test_indexer_utils_repo.py +0 -0
  475. {conexus-4.2.2 → conexus-4.3.0}/tests/test_integration.py +0 -0
  476. {conexus-4.2.2 → conexus-4.3.0}/tests/test_jsonl.py +0 -0
  477. {conexus-4.2.2 → conexus-4.3.0}/tests/test_languages.py +0 -0
  478. {conexus-4.2.2 → conexus-4.3.0}/tests/test_link_generator.py +0 -0
  479. {conexus-4.2.2 → conexus-4.3.0}/tests/test_local_mode.py +0 -0
  480. {conexus-4.2.2 → conexus-4.3.0}/tests/test_logging_setup.py +0 -0
  481. {conexus-4.2.2 → conexus-4.3.0}/tests/test_mcp_concurrency.py +0 -0
  482. {conexus-4.2.2 → conexus-4.3.0}/tests/test_mcp_package.py +0 -0
  483. {conexus-4.2.2 → conexus-4.3.0}/tests/test_mcp_server.py +0 -0
  484. {conexus-4.2.2 → conexus-4.3.0}/tests/test_md_chunker.py +0 -0
  485. {conexus-4.2.2 → conexus-4.3.0}/tests/test_md_chunker_semantic_integrity.py +0 -0
  486. {conexus-4.2.2 → conexus-4.3.0}/tests/test_md_preservation.py +0 -0
  487. {conexus-4.2.2 → conexus-4.3.0}/tests/test_memory.py +0 -0
  488. {conexus-4.2.2 → conexus-4.3.0}/tests/test_memory_consolidation.py +0 -0
  489. {conexus-4.2.2 → conexus-4.3.0}/tests/test_mineru_cmd.py +0 -0
  490. {conexus-4.2.2 → conexus-4.3.0}/tests/test_mineru_extractor.py +0 -0
  491. {conexus-4.2.2 → conexus-4.3.0}/tests/test_minified_chunking.py +0 -0
  492. {conexus-4.2.2 → conexus-4.3.0}/tests/test_overfetch_pipeline.py +0 -0
  493. {conexus-4.2.2 → conexus-4.3.0}/tests/test_p0_regressions.py +0 -0
  494. {conexus-4.2.2 → conexus-4.3.0}/tests/test_pdf_chunker.py +0 -0
  495. {conexus-4.2.2 → conexus-4.3.0}/tests/test_pdf_chunker_integration.py +0 -0
  496. {conexus-4.2.2 → conexus-4.3.0}/tests/test_pdf_e2e.py +0 -0
  497. {conexus-4.2.2 → conexus-4.3.0}/tests/test_pdf_extractor.py +0 -0
  498. {conexus-4.2.2 → conexus-4.3.0}/tests/test_pdf_extractor_integration.py +0 -0
  499. {conexus-4.2.2 → conexus-4.3.0}/tests/test_pdf_extractor_normalization.py +0 -0
  500. {conexus-4.2.2 → conexus-4.3.0}/tests/test_pdf_extractor_server.py +0 -0
  501. {conexus-4.2.2 → conexus-4.3.0}/tests/test_pdf_subsystem.py +0 -0
  502. {conexus-4.2.2 → conexus-4.3.0}/tests/test_pipeline_buffer.py +0 -0
  503. {conexus-4.2.2 → conexus-4.3.0}/tests/test_pipeline_stages.py +0 -0
  504. {conexus-4.2.2 → conexus-4.3.0}/tests/test_pipeline_version.py +0 -0
  505. {conexus-4.2.2 → conexus-4.3.0}/tests/test_plan_library.py +0 -0
  506. {conexus-4.2.2 → conexus-4.3.0}/tests/test_plugin.py +0 -0
  507. {conexus-4.2.2 → conexus-4.3.0}/tests/test_plugin_install.py +0 -0
  508. {conexus-4.2.2 → conexus-4.3.0}/tests/test_plugin_structure.py +0 -0
  509. {conexus-4.2.2 → conexus-4.3.0}/tests/test_post_store_hook.py +0 -0
  510. {conexus-4.2.2 → conexus-4.3.0}/tests/test_ppid_chain_hypothesis.py +0 -0
  511. {conexus-4.2.2 → conexus-4.3.0}/tests/test_provision.py +0 -0
  512. {conexus-4.2.2 → conexus-4.3.0}/tests/test_quality_score.py +0 -0
  513. {conexus-4.2.2 → conexus-4.3.0}/tests/test_query_sanitizer.py +0 -0
  514. {conexus-4.2.2 → conexus-4.3.0}/tests/test_rdr052_verification.py +0 -0
  515. {conexus-4.2.2 → conexus-4.3.0}/tests/test_rdr053_verification.py +0 -0
  516. {conexus-4.2.2 → conexus-4.3.0}/tests/test_rdr_audit_incident_template.py +0 -0
  517. {conexus-4.2.2 → conexus-4.3.0}/tests/test_rdr_audit_scheduling.py +0 -0
  518. {conexus-4.2.2 → conexus-4.3.0}/tests/test_rdr_audit_skill.py +0 -0
  519. {conexus-4.2.2 → conexus-4.3.0}/tests/test_rdr_close_gate.py +0 -0
  520. {conexus-4.2.2 → conexus-4.3.0}/tests/test_registry.py +0 -0
  521. {conexus-4.2.2 → conexus-4.3.0}/tests/test_relevance_log.py +0 -0
  522. {conexus-4.2.2 → conexus-4.3.0}/tests/test_ripgrep_cache.py +0 -0
  523. {conexus-4.2.2 → conexus-4.3.0}/tests/test_schema.py +0 -0
  524. {conexus-4.2.2 → conexus-4.3.0}/tests/test_scoring.py +0 -0
  525. {conexus-4.2.2 → conexus-4.3.0}/tests/test_scratch.py +0 -0
  526. {conexus-4.2.2 → conexus-4.3.0}/tests/test_scratch_cmd.py +0 -0
  527. {conexus-4.2.2 → conexus-4.3.0}/tests/test_search_clusterer.py +0 -0
  528. {conexus-4.2.2 → conexus-4.3.0}/tests/test_search_clustering_integration.py +0 -0
  529. {conexus-4.2.2 → conexus-4.3.0}/tests/test_search_cmd.py +0 -0
  530. {conexus-4.2.2 → conexus-4.3.0}/tests/test_search_engine.py +0 -0
  531. {conexus-4.2.2 → conexus-4.3.0}/tests/test_session.py +0 -0
  532. {conexus-4.2.2 → conexus-4.3.0}/tests/test_session_propagation_hypotheses.py +0 -0
  533. {conexus-4.2.2 → conexus-4.3.0}/tests/test_silent_error_logging.py +0 -0
  534. {conexus-4.2.2 → conexus-4.3.0}/tests/test_sn_plugin.py +0 -0
  535. {conexus-4.2.2 → conexus-4.3.0}/tests/test_store_cmd.py +0 -0
  536. {conexus-4.2.2 → conexus-4.3.0}/tests/test_structlog_events.py +0 -0
  537. {conexus-4.2.2 → conexus-4.3.0}/tests/test_t1.py +0 -0
  538. {conexus-4.2.2 → conexus-4.3.0}/tests/test_t2.py +0 -0
  539. {conexus-4.2.2 → conexus-4.3.0}/tests/test_t2_concurrency.py +0 -0
  540. {conexus-4.2.2 → conexus-4.3.0}/tests/test_t2_prefix_scan.py +0 -0
  541. {conexus-4.2.2 → conexus-4.3.0}/tests/test_t3.py +0 -0
  542. {conexus-4.2.2 → conexus-4.3.0}/tests/test_t3_hnsw_ef.py +0 -0
  543. {conexus-4.2.2 → conexus-4.3.0}/tests/test_t3_quota_enforcement.py +0 -0
  544. {conexus-4.2.2 → conexus-4.3.0}/tests/test_table_extraction.py +0 -0
  545. {conexus-4.2.2 → conexus-4.3.0}/tests/test_ttl.py +0 -0
  546. {conexus-4.2.2 → conexus-4.3.0}/tests/test_tumbler.py +0 -0
  547. {conexus-4.2.2 → conexus-4.3.0}/tests/test_tuning_config.py +0 -0
  548. {conexus-4.2.2 → conexus-4.3.0}/tests/test_upgrade_cmd.py +0 -0
  549. {conexus-4.2.2 → conexus-4.3.0}/tests/test_verify_multiprobe.py +0 -0
  550. {conexus-4.2.2 → conexus-4.3.0}/tests/test_voyage_retry.py +0 -0
@@ -175,3 +175,68 @@
175
175
  {"id":"int-3ea012d6","kind":"field_change","created_at":"2026-04-13T18:47:31.162195Z","actor":"Hellblazer","issue_id":"nexus-gvk","extra":{"field":"status","new_value":"closed","old_value":"open","reason":"RDR-072 complete. All 9 beads closed. L1 context cache: generate, CLI, discover hook, index hook, SessionStart injection."}}
176
176
  {"id":"int-1403eab5","kind":"field_change","created_at":"2026-04-13T19:18:57.70793Z","actor":"Hellblazer","issue_id":"nexus-fbv","extra":{"field":"status","new_value":"closed","old_value":"open","reason":"Dogfood complete: 2095 topics discovered, 121 cloud collections tested, live search with boost+grouping validated, smoke test 29/29 pass, all labels applied."}}
177
177
  {"id":"int-c657f531","kind":"field_change","created_at":"2026-04-13T19:18:58.337987Z","actor":"Hellblazer","issue_id":"nexus-98h","extra":{"field":"status","new_value":"closed","old_value":"open","reason":"RDR-070 implemented and released (v4.0.0-4.0.3). All phases complete, all review gates passed."}}
178
+ {"id":"int-00e41d01","kind":"field_change","created_at":"2026-04-14T00:29:08.429827Z","actor":"Hellblazer","issue_id":"nexus-h74","extra":{"field":"status","new_value":"closed","old_value":"in_progress","reason":"Fixed --dir PDF batch staleness, repo detection, ignore filtering, and path normalization across all indexing entry points"}}
179
+ {"id":"int-55d2a538","kind":"field_change","created_at":"2026-04-14T00:48:35.382924Z","actor":"Hellblazer","issue_id":"nexus-bsg","extra":{"field":"status","new_value":"closed","old_value":"in_progress","reason":"Wired assign_batch into all 6 CLI indexing upsert paths (code_indexer, prose_indexer, doc_indexer x3, pipeline_stages). No-op when centroids dont exist."}}
180
+ {"id":"int-bad8ba79","kind":"field_change","created_at":"2026-04-14T10:03:56.30509Z","actor":"Hellblazer","issue_id":"nexus-you","extra":{"field":"status","new_value":"closed","old_value":"in_progress","reason":"Closed"}}
181
+ {"id":"int-d82cb25d","kind":"field_change","created_at":"2026-04-14T10:03:56.524528Z","actor":"Hellblazer","issue_id":"nexus-6cn","extra":{"field":"status","new_value":"closed","old_value":"in_progress","reason":"Closed"}}
182
+ {"id":"int-c0526ad2","kind":"field_change","created_at":"2026-04-14T10:04:19.98815Z","actor":"Hellblazer","issue_id":"nexus-8fq","extra":{"field":"status","new_value":"in_progress","old_value":"open"}}
183
+ {"id":"int-0372907d","kind":"field_change","created_at":"2026-04-14T10:05:54.310521Z","actor":"Hellblazer","issue_id":"nexus-sbf","extra":{"field":"status","new_value":"closed","old_value":"open","reason":"Closed"}}
184
+ {"id":"int-828d0732","kind":"field_change","created_at":"2026-04-14T10:05:54.534467Z","actor":"Hellblazer","issue_id":"nexus-8fq","extra":{"field":"status","new_value":"closed","old_value":"in_progress","reason":"Closed"}}
185
+ {"id":"int-10bfd6fb","kind":"field_change","created_at":"2026-04-14T10:06:14.489844Z","actor":"Hellblazer","issue_id":"nexus-mrq","extra":{"field":"status","new_value":"closed","old_value":"open","reason":"Code review completed in Phase 1 review agent, all findings addressed"}}
186
+ {"id":"int-57234af7","kind":"field_change","created_at":"2026-04-14T10:06:30.222729Z","actor":"Hellblazer","issue_id":"nexus-wzn","extra":{"field":"status","new_value":"in_progress","old_value":"open"}}
187
+ {"id":"int-3decf04d","kind":"field_change","created_at":"2026-04-14T10:07:23.884392Z","actor":"Hellblazer","issue_id":"nexus-tov","extra":{"field":"status","new_value":"in_progress","old_value":"open"}}
188
+ {"id":"int-197e9107","kind":"field_change","created_at":"2026-04-14T10:08:33.890211Z","actor":"Hellblazer","issue_id":"nexus-wzn","extra":{"field":"status","new_value":"closed","old_value":"in_progress","reason":"Closed"}}
189
+ {"id":"int-fa4fcd0a","kind":"field_change","created_at":"2026-04-14T10:08:34.164106Z","actor":"Hellblazer","issue_id":"nexus-tov","extra":{"field":"status","new_value":"closed","old_value":"in_progress","reason":"Closed"}}
190
+ {"id":"int-dfa52e33","kind":"field_change","created_at":"2026-04-14T10:08:45.212087Z","actor":"Hellblazer","issue_id":"nexus-2cx","extra":{"field":"status","new_value":"closed","old_value":"open","reason":"Review inline, all checks pass"}}
191
+ {"id":"int-40b5b8fa","kind":"field_change","created_at":"2026-04-14T10:08:58.780285Z","actor":"Hellblazer","issue_id":"nexus-ak6","extra":{"field":"status","new_value":"in_progress","old_value":"open"}}
192
+ {"id":"int-1a33cbdd","kind":"field_change","created_at":"2026-04-14T10:10:48.732582Z","actor":"Hellblazer","issue_id":"nexus-ak6","extra":{"field":"status","new_value":"closed","old_value":"in_progress","reason":"Implemented and tests pass"}}
193
+ {"id":"int-04e3d80d","kind":"field_change","created_at":"2026-04-14T10:10:49.00147Z","actor":"Hellblazer","issue_id":"nexus-jda","extra":{"field":"status","new_value":"closed","old_value":"open","reason":"Implemented and tests pass"}}
194
+ {"id":"int-447cc563","kind":"field_change","created_at":"2026-04-14T10:10:49.282894Z","actor":"Hellblazer","issue_id":"nexus-gp5","extra":{"field":"status","new_value":"closed","old_value":"open","reason":"Implemented and tests pass"}}
195
+ {"id":"int-ebad1d37","kind":"field_change","created_at":"2026-04-14T10:11:05.875122Z","actor":"Hellblazer","issue_id":"nexus-ard","extra":{"field":"status","new_value":"in_progress","old_value":"open"}}
196
+ {"id":"int-9805d16a","kind":"field_change","created_at":"2026-04-14T10:11:06.380468Z","actor":"Hellblazer","issue_id":"nexus-sui","extra":{"field":"status","new_value":"in_progress","old_value":"open"}}
197
+ {"id":"int-fce4981d","kind":"field_change","created_at":"2026-04-14T10:14:10.979745Z","actor":"Hellblazer","issue_id":"nexus-ard","extra":{"field":"status","new_value":"closed","old_value":"in_progress","reason":"Implemented and tests pass"}}
198
+ {"id":"int-75a21aae","kind":"field_change","created_at":"2026-04-14T10:14:11.261517Z","actor":"Hellblazer","issue_id":"nexus-sui","extra":{"field":"status","new_value":"closed","old_value":"in_progress","reason":"Implemented and tests pass"}}
199
+ {"id":"int-54c8c3af","kind":"field_change","created_at":"2026-04-14T10:14:11.549361Z","actor":"Hellblazer","issue_id":"nexus-0yq","extra":{"field":"status","new_value":"closed","old_value":"open","reason":"Implemented and tests pass"}}
200
+ {"id":"int-9c0c69f6","kind":"field_change","created_at":"2026-04-14T10:14:20.646892Z","actor":"Hellblazer","issue_id":"nexus-biw","extra":{"field":"status","new_value":"in_progress","old_value":"open"}}
201
+ {"id":"int-df7839d9","kind":"field_change","created_at":"2026-04-14T10:15:47.675623Z","actor":"Hellblazer","issue_id":"nexus-biw","extra":{"field":"status","new_value":"closed","old_value":"in_progress","reason":"All SC verified, 288 tests pass"}}
202
+ {"id":"int-d38561f7","kind":"field_change","created_at":"2026-04-14T10:15:47.954448Z","actor":"Hellblazer","issue_id":"nexus-ebz","extra":{"field":"status","new_value":"closed","old_value":"open","reason":"All SC verified, 288 tests pass"}}
203
+ {"id":"int-b5760d5d","kind":"field_change","created_at":"2026-04-14T10:15:56.860531Z","actor":"Hellblazer","issue_id":"nexus-1hh","extra":{"field":"status","new_value":"closed","old_value":"open","reason":"RDR-076 fully implemented: migration registry, domain delegation, T2Database integration, nx upgrade CLI, hooks.json, MCP version check, doctor --check-schema. 288 tests pass."}}
204
+ {"id":"int-d551081d","kind":"field_change","created_at":"2026-04-14T11:23:09.921459Z","actor":"Hellblazer","issue_id":"nexus-bbt","extra":{"field":"status","new_value":"in_progress","old_value":"open"}}
205
+ {"id":"int-e42ac532","kind":"field_change","created_at":"2026-04-14T11:26:55.072036Z","actor":"Hellblazer","issue_id":"nexus-bbt","extra":{"field":"status","new_value":"closed","old_value":"in_progress","reason":"Heading normalization implemented and tested"}}
206
+ {"id":"int-12e35bab","kind":"field_change","created_at":"2026-04-14T11:26:55.342943Z","actor":"Hellblazer","issue_id":"nexus-oyu","extra":{"field":"status","new_value":"closed","old_value":"open","reason":"Heading normalization implemented and tested"}}
207
+ {"id":"int-e32206f0","kind":"field_change","created_at":"2026-04-14T11:26:55.620441Z","actor":"Hellblazer","issue_id":"nexus-40b","extra":{"field":"status","new_value":"closed","old_value":"open","reason":"Heading normalization implemented and tested"}}
208
+ {"id":"int-fc75b39b","kind":"field_change","created_at":"2026-04-14T11:26:55.902207Z","actor":"Hellblazer","issue_id":"nexus-j4o","extra":{"field":"status","new_value":"closed","old_value":"open","reason":"Heading normalization implemented and tested"}}
209
+ {"id":"int-fbfd8948","kind":"field_change","created_at":"2026-04-14T12:49:09.751488Z","actor":"Hellblazer","issue_id":"nexus-eds","extra":{"field":"status","new_value":"in_progress","old_value":"open"}}
210
+ {"id":"int-ab16a999","kind":"field_change","created_at":"2026-04-14T12:52:28.034736Z","actor":"Hellblazer","issue_id":"nexus-eds","extra":{"field":"status","new_value":"closed","old_value":"in_progress","reason":"Implemented and tested"}}
211
+ {"id":"int-37c31500","kind":"field_change","created_at":"2026-04-14T13:01:26.635285Z","actor":"Hellblazer","issue_id":"nexus-smx","extra":{"field":"status","new_value":"in_progress","old_value":"open"}}
212
+ {"id":"int-469c2f64","kind":"field_change","created_at":"2026-04-14T13:03:47.028461Z","actor":"Hellblazer","issue_id":"nexus-smx","extra":{"field":"status","new_value":"closed","old_value":"in_progress","reason":"Implemented and tested"}}
213
+ {"id":"int-8d07f701","kind":"field_change","created_at":"2026-04-14T13:07:02.323796Z","actor":"Hellblazer","issue_id":"nexus-jjm","extra":{"field":"status","new_value":"in_progress","old_value":"open"}}
214
+ {"id":"int-b096ec87","kind":"field_change","created_at":"2026-04-14T13:11:17.958313Z","actor":"Hellblazer","issue_id":"nexus-jjm","extra":{"field":"status","new_value":"closed","old_value":"in_progress","reason":"Implemented and tested"}}
215
+ {"id":"int-f54cff1b","kind":"field_change","created_at":"2026-04-14T13:28:58.24738Z","actor":"Hellblazer","issue_id":"nexus-20w","extra":{"field":"status","new_value":"closed","old_value":"open","reason":"Review findings remediated"}}
216
+ {"id":"int-12d7fa12","kind":"field_change","created_at":"2026-04-14T13:30:05.629118Z","actor":"Hellblazer","issue_id":"nexus-d1q","extra":{"field":"status","new_value":"in_progress","old_value":"open"}}
217
+ {"id":"int-9d1b9b3e","kind":"field_change","created_at":"2026-04-14T13:32:24.155963Z","actor":"Hellblazer","issue_id":"nexus-d1q","extra":{"field":"status","new_value":"closed","old_value":"in_progress","reason":"Implemented and tested"}}
218
+ {"id":"int-a6fce836","kind":"field_change","created_at":"2026-04-14T13:32:44.311999Z","actor":"Hellblazer","issue_id":"nexus-bo4","extra":{"field":"status","new_value":"in_progress","old_value":"open"}}
219
+ {"id":"int-d2978cd5","kind":"field_change","created_at":"2026-04-14T13:34:29.044777Z","actor":"Hellblazer","issue_id":"nexus-bo4","extra":{"field":"status","new_value":"closed","old_value":"in_progress","reason":"Implemented and tested"}}
220
+ {"id":"int-bc251fec","kind":"field_change","created_at":"2026-04-14T13:34:44.521433Z","actor":"Hellblazer","issue_id":"nexus-1sb","extra":{"field":"status","new_value":"in_progress","old_value":"open"}}
221
+ {"id":"int-3168bba8","kind":"field_change","created_at":"2026-04-14T13:36:04.286769Z","actor":"Hellblazer","issue_id":"nexus-1sb","extra":{"field":"status","new_value":"closed","old_value":"in_progress","reason":"Implemented"}}
222
+ {"id":"int-aec0b9e5","kind":"field_change","created_at":"2026-04-14T13:37:14.934244Z","actor":"Hellblazer","issue_id":"nexus-88e","extra":{"field":"status","new_value":"in_progress","old_value":"open"}}
223
+ {"id":"int-4aaec341","kind":"field_change","created_at":"2026-04-14T13:43:05.43679Z","actor":"Hellblazer","issue_id":"nexus-88e","extra":{"field":"status","new_value":"closed","old_value":"in_progress","reason":"Review findings remediated"}}
224
+ {"id":"int-8c5f1356","kind":"field_change","created_at":"2026-04-14T13:43:39.209646Z","actor":"Hellblazer","issue_id":"nexus-70u","extra":{"field":"status","new_value":"in_progress","old_value":"open"}}
225
+ {"id":"int-e2106dd4","kind":"field_change","created_at":"2026-04-14T13:45:50.725253Z","actor":"Hellblazer","issue_id":"nexus-70u","extra":{"field":"status","new_value":"closed","old_value":"in_progress","reason":"Implemented and tested"}}
226
+ {"id":"int-be4c854b","kind":"field_change","created_at":"2026-04-14T13:45:54.157801Z","actor":"Hellblazer","issue_id":"nexus-jq7","extra":{"field":"status","new_value":"closed","old_value":"open","reason":"Implemented and tested"}}
227
+ {"id":"int-c8fccff7","kind":"field_change","created_at":"2026-04-14T13:46:12.387934Z","actor":"Hellblazer","issue_id":"nexus-rw6","extra":{"field":"status","new_value":"in_progress","old_value":"open"}}
228
+ {"id":"int-37c81faa","kind":"field_change","created_at":"2026-04-14T13:47:49.924893Z","actor":"Hellblazer","issue_id":"nexus-rw6","extra":{"field":"status","new_value":"closed","old_value":"in_progress","reason":"Implemented and tested"}}
229
+ {"id":"int-7e132ad1","kind":"field_change","created_at":"2026-04-14T13:48:10.890872Z","actor":"Hellblazer","issue_id":"nexus-cjf","extra":{"field":"status","new_value":"in_progress","old_value":"open"}}
230
+ {"id":"int-168bf68c","kind":"field_change","created_at":"2026-04-14T13:49:35.273351Z","actor":"Hellblazer","issue_id":"nexus-cjf","extra":{"field":"status","new_value":"closed","old_value":"in_progress","reason":"All 3 deliverables implemented"}}
231
+ {"id":"int-56a4424c","kind":"field_change","created_at":"2026-04-14T13:49:52.67817Z","actor":"Hellblazer","issue_id":"nexus-ek8","extra":{"field":"status","new_value":"in_progress","old_value":"open"}}
232
+ {"id":"int-8d30e013","kind":"field_change","created_at":"2026-04-14T13:50:46.231963Z","actor":"Hellblazer","issue_id":"nexus-ek8","extra":{"field":"status","new_value":"closed","old_value":"in_progress","reason":"Implemented; threshold validation deferred to dogfood"}}
233
+ {"id":"int-76f62eaa","kind":"field_change","created_at":"2026-04-14T13:50:50.404783Z","actor":"Hellblazer","issue_id":"nexus-13u","extra":{"field":"status","new_value":"closed","old_value":"open","reason":"Implemented; threshold validation deferred to dogfood"}}
234
+ {"id":"int-045c9e19","kind":"field_change","created_at":"2026-04-14T13:50:54.251782Z","actor":"Hellblazer","issue_id":"nexus-78i","extra":{"field":"status","new_value":"closed","old_value":"open","reason":"Implemented; threshold validation deferred to dogfood"}}
235
+ {"id":"int-f9d6652c","kind":"field_change","created_at":"2026-04-14T20:23:11.76496Z","actor":"Hellblazer","issue_id":"nexus-nsh","extra":{"field":"status","new_value":"closed","old_value":"in_progress","reason":"Phase 1 complete: migration _add_projection_quality_columns at 4.3.0, 7 new tests + existing suites green (196 passed). Live DB verified (nx upgrade + nx doctor --check-schema both PASS)."}}
236
+ {"id":"int-f4d0972b","kind":"field_change","created_at":"2026-04-14T21:24:59.6062Z","actor":"Hellblazer","issue_id":"nexus-uti","extra":{"field":"status","new_value":"closed","old_value":"in_progress","reason":"Phase 2 complete: 6 write sites migrated atomically — AssignResult NamedTuple, 3-tuple chunk_assignments, prefer-higher UPSERT with COALESCE(-1.0), similarity+source_collection propagated through assign_batch(cross=True), backfill_projection, _persist_assignments (both paths), _run_taxonomy_assign. 9 new tests + full regression (224 passed). Commit 39d5fa1."}}
237
+ {"id":"int-05f7904b","kind":"field_change","created_at":"2026-04-14T21:34:14.629249Z","actor":"Hellblazer","issue_id":"nexus-qab","extra":{"field":"status","new_value":"closed","old_value":"in_progress","reason":"Phase 3 complete: compute_icf_map + log2 scalar registered in CatalogTaxonomy.__init__ (Option A per S-2); per-instance cache with opt-in use_cache; 7 new ICF tests; 231 regression sweep passing. Commit a3bffc4."}}
238
+ {"id":"int-68469808","kind":"field_change","created_at":"2026-04-14T21:40:57.284029Z","actor":"Hellblazer","issue_id":"nexus-jt1","extra":{"field":"status","new_value":"closed","old_value":"in_progress","reason":"Phase 4a complete: --use-icf flag, icf_map parameter on project_against (filter+rank only, raw cosine stored), per-corpus-type thresholds (code__* 0.70, knowledge__* 0.50, docs__*/rdr__* 0.55). 11 new tests + 198 regression passing. Commit 4146118."}}
239
+ {"id":"int-24f3bcf0","kind":"field_change","created_at":"2026-04-14T21:43:09.379866Z","actor":"Hellblazer","issue_id":"nexus-z2k","extra":{"field":"status","new_value":"closed","old_value":"in_progress","reason":"Phase 4b complete: docs/taxonomy-projection-tuning.md authored; architecture.md cross-links added. CLI help already references it (Phase 4a). 143 regression tests passing. Commit f04ab7c."}}
240
+ {"id":"int-5d3ca38a","kind":"field_change","created_at":"2026-04-14T21:50:15.895577Z","actor":"Hellblazer","issue_id":"nexus-84v","extra":{"field":"status","new_value":"closed","old_value":"in_progress","reason":"Phase 5 complete: detect_hubs() + HubRow + DEFAULT_HUB_STOPWORDS + nx taxonomy hubs CLI. C-2 MAX(last_discover_at) aggregation across source collections; O-3 NULL/missing-row handling. 8 new tests + 156 regression passing. Commit 7c8b6e8."}}
241
+ {"id":"int-704746ac","kind":"field_change","created_at":"2026-04-14T21:54:38.538122Z","actor":"Hellblazer","issue_id":"nexus-w4k","extra":{"field":"status","new_value":"closed","old_value":"in_progress","reason":"Phase 6 complete: audit_collection() + AuditReport/AuditHub + nx taxonomy audit CLI. Python-side nearest-rank p10/p50/p90, per-corpus default threshold resolution, pattern-pollution flags share Phase 5 stopwords. 8 new tests + 232 regression passing. Commit 0c650c2."}}
242
+ {"id":"int-79c0dd1b","kind":"field_change","created_at":"2026-04-14T22:13:26.707158Z","actor":"Hellblazer","issue_id":"nexus-e94","extra":{"field":"status","new_value":"closed","old_value":"in_progress","reason":"Phase 7 review gate PASSED. Code-review-expert: PASS on C-1/C-2/S-2/O-2/O-3 + all 4 invariants; O-1 was reviewer misread (centroid path intentionally keeps NULL similarity — matches plan criterion + assign_topic contract); S-3 real gap remediated via new fixture_icf_ranking (12 collections). Test-validator: PASS across all 8 success criteria (SC-1..SC-8) with named tests. Full suite: 3960 passed, 14 skipped pre-remediation; 896 targeted regression tests green post-remediation. Ready to merge. Commits: 71ec85b (P1) → 39d5fa1 (P2) → a3bffc4 (P3) → 4146118 (P4a) → f04ab7c (P4b) → a083862 (docs) → 7c8b6e8 (P5) → 0c650c2 (P6) → 38a5843 (gate prep) → f834c60 (S-3)."}}
@@ -9,13 +9,13 @@
9
9
  "name": "nx",
10
10
  "source": "./nx",
11
11
  "description": "Self-hosted three-tier knowledge management with 16 specialized agents, analytical query pipelines, semantic search, and RDR decision tracking for Claude Code.",
12
- "version": "4.2.2"
12
+ "version": "4.3.0"
13
13
  },
14
14
  {
15
15
  "name": "sn",
16
16
  "source": "./sn",
17
17
  "description": "Injects Serena and Context7 MCP tool usage guidance into subagents via SubagentStart hook.",
18
- "version": "4.2.2"
18
+ "version": "4.3.0"
19
19
  }
20
20
  ]
21
21
  }
@@ -30,4 +30,6 @@ tests/fixtures/*.pdf
30
30
  .beads/.beads-credential-key
31
31
  .beads/backup/
32
32
  .claude/continuation-*
33
+ .claude/scratch/
34
+ .claude/scheduled_tasks.lock
33
35
  .serena/
@@ -6,6 +6,36 @@ Versioning follows [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
6
6
 
7
7
  ## [Unreleased]
8
8
 
9
+ ## [4.3.0] - 2026-04-14
10
+
11
+ ### Added
12
+
13
+ - **Projection quality (RDR-077)**: cross-collection projection now records raw cosine similarity, timestamp, and source collection for every projection assignment. Three new nullable columns on `topic_assignments`: `similarity` (REAL), `assigned_at` (TEXT, ISO-8601), `source_collection` (TEXT). Composite index `idx_topic_assignments_source` supports ICF aggregation and Phase 5/6 hub / audit queries. Migration is idempotent and applied by `nx upgrade` under the existing RDR-076 registry.
14
+ - **`nx taxonomy project --use-icf`**: Inverse Collection Frequency weighting. Suppresses hub topics (generic labels that span nearly every source corpus) before the threshold filter and top-K ranking. Stored similarity remains raw cosine — ICF is applied only at query time, never persisted (RDR-077 RF-8 invariant).
15
+ - **Per-corpus-type default thresholds** on `nx taxonomy project`: omitting `--threshold` now applies `code__*` 0.70, `knowledge__*` 0.50, `docs__*`/`rdr__*` 0.55. Explicit `--threshold` always wins. Exposed as `nexus.corpus.default_projection_threshold`.
16
+ - **`CatalogTaxonomy.compute_icf_map()`**: returns `{topic_id: icf}` where `icf = log2(N_effective / DF)`. Guards: `N_effective < 2` returns `{}`; `DF = N_effective` yields `0.0` (intentional hub suppression); legacy NULL-`source_collection` rows excluded from both numerator and denominator. Per-instance cache via `use_cache=True` + `clear_icf_cache()`. `log2` registered as a deterministic, null-safe SQLite scalar in `CatalogTaxonomy.__init__`.
17
+ - **`AssignResult` NamedTuple**: `assign_single()` now returns `AssignResult(topic_id, similarity)` instead of a bare `int`. Callers that only need the topic id use `.topic_id`. Distance → similarity inversion (`1.0 - distance`) happens inside the method.
18
+ - **Prefer-higher UPSERT for projection rows**: `assign_topic(assigned_by='projection', ...)` uses `INSERT … ON CONFLICT DO UPDATE SET similarity = MAX(COALESCE(-1.0), excluded)` so re-projection with a lower similarity never overwrites a higher one, and `assigned_at` / `source_collection` refresh only when the incoming match wins. HDBSCAN / centroid / manual rows keep `INSERT OR IGNORE`.
19
+ - **`docs/taxonomy-projection-tuning.md`**: operator guide — similarity semantics, ICF rationale, per-corpus-type defaults, calibration loop for new corpora, upsert semantics, staleness detection, troubleshooting.
20
+ - **`nx taxonomy hubs`**: generic-pattern hub detector. Flags topics whose projection assignments span `--min-collections N` or more source corpora with ICF `<= --max-icf` and/or labels containing bundled stopword tokens (`assert`, `junit`, `builder`, `class`, `import`, `exception`, `getter`, `setter`, `variable`, `declaration`, `operator`). Output sorted by `chunks × (1 - ICF)` descending. `--warn-stale` compares `MAX(taxonomy_meta.last_discover_at)` across contributing source collections against the hub's latest `assigned_at`; `--explain` shows DF / ICF / matched stopword tokens per row. Advisory — users decide.
21
+ - **`detect_hubs()`** on `CatalogTaxonomy` returning `list[HubRow]` with per-row staleness fields (`max_last_discover_at`, `never_discovered_count`, `is_stale`). Never-discovered source collections count as stale (O-3). `DEFAULT_HUB_STOPWORDS` constant exposes the bundled token list.
22
+ - **`nx taxonomy audit --collection NAME`**: projection-quality report per collection. Output: total projection assignments originating from the collection, p10 / p50 / p90 of raw cosine similarity (Python-side nearest-rank — SQLite has no `percentile_cont`), count below threshold (re-projection candidates), top receiving topics with ICF, pattern-pollution flags. `--threshold` defaults to the per-corpus-type value from `default_projection_threshold`; `--top-n` caps the receiving-topic list (default 5). Empty-projection case returns a clean "no projection data" message, no stack trace.
23
+ - **`audit_collection()`** on `CatalogTaxonomy` returning `AuditReport(collection, total_assignments, p10, p50, p90, below_threshold_count, threshold, top_receiving_hubs, pattern_pollution)`. Helper NamedTuple `AuditHub` carries per-row chunk_count, icf, and matched_stopwords.
24
+
25
+ ### Changed
26
+
27
+ - `nx taxonomy project --threshold` is now optional (was `0.85`). Omitting it triggers the per-corpus-type default cascade.
28
+ - `project_against()` accepts optional `icf_map: dict[int, float] | None`. When supplied, adjusted scores (`sim * icf`) drive both the threshold filter and the top-K ranking; raw cosine is still what lands in `chunk_assignments`.
29
+ - `assign_batch(cross_collection=True)` now propagates per-row similarity and `source_collection` into `topic_assignments` (previously the distance was discarded — RDR-077 C-1 audit finding).
30
+ - `backfill_projection` (T3 upgrade step) unpacks the new 3-tuple `chunk_assignments` and passes `similarity` + `source_collection=src` through to `assign_topic`.
31
+
32
+ ### Documentation
33
+
34
+ - `docs/taxonomy.md` — new cross-collection projection section, `project` subcommand added to command table, ICF summary, per-corpus threshold table.
35
+ - `docs/cli-reference.md` — `--use-icf` example, `project` row updated with per-corpus defaults + tuning-doc link.
36
+ - `docs/storage-tiers.md` — `topic_assignments` row now documents all post-RDR-077 columns and upsert semantics.
37
+ - `docs/architecture.md` — Projection quality subsection under Taxonomy linking to the tuning guide; `project` subcommand listed in the `nx taxonomy` CLI table.
38
+
9
39
  ## [4.2.2] - 2026-04-14
10
40
 
11
41
  (Note: v4.2.1 was tagged but never published due to a test failure. v4.2.2 supersedes it and includes all 4.2.1 changes plus the ChromaDB Cloud quota audit and observability improvements found during a live shakeout.)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: conexus
3
- Version: 4.2.2
3
+ Version: 4.3.0
4
4
  Summary: Self-hosted semantic search and knowledge management for LLM-driven development
5
5
  Project-URL: Homepage, https://github.com/Hellblazer/nexus
6
6
  Project-URL: Repository, https://github.com/Hellblazer/nexus
@@ -169,6 +169,14 @@ Manual labels survive rebuild via `_merge_labels`.
169
169
  | `merge` | Merge two topics into one |
170
170
  | `split` | Split a topic on a keyword pivot |
171
171
  | `links` | Compute and persist inter-topic links from catalog |
172
+ | `project` | Cross-collection projection with `--use-icf` hub suppression (RDR-077) |
173
+
174
+ ### Projection quality (RDR-077)
175
+
176
+ `topic_assignments` also carries `similarity` (raw cosine), `assigned_at`,
177
+ and `source_collection` for projection rows. Operator guide:
178
+ [docs/taxonomy-projection-tuning.md](taxonomy-projection-tuning.md) —
179
+ threshold calibration, ICF rationale, upsert semantics, troubleshooting.
172
180
 
173
181
  ### Config (`taxonomy` section in `.nexus.yml`)
174
182
 
@@ -327,7 +327,10 @@ nx taxonomy links # show inter-topic relationships
327
327
  nx taxonomy rebuild -c docs__nexus # full rebuild
328
328
  nx taxonomy project code__nexus # project against sibling collections
329
329
  nx taxonomy project code__nexus --against knowledge__art # explicit targets
330
+ nx taxonomy project code__nexus --use-icf --persist # suppress hub topics (RDR-077)
330
331
  nx taxonomy project --backfill --persist # project all collections
332
+ nx taxonomy hubs --min-collections 5 --max-icf 1.2 --explain # hub detector (RDR-077)
333
+ nx taxonomy audit --collection code__nexus # projection quality audit (RDR-077)
331
334
  ```
332
335
 
333
336
  | Subcommand | Description |
@@ -344,7 +347,9 @@ nx taxonomy project --backfill --persist # project all collections
344
347
  | `split LABEL --k N` | Split into N sub-topics via KMeans. `-c NAME` scopes label lookup |
345
348
  | `links` | Inter-topic link counts from catalog graph. `-c NAME` filters by collection |
346
349
  | `rebuild` | Full re-cluster (alias for `discover --force`). `-c NAME` required |
347
- | `project SOURCE` | Cross-collection projection: match chunks against other collections' centroids. `--against TARGETS` for explicit targets (default: sibling collections). `--threshold N` (default 0.85). `--persist` to write assignments. `--backfill` to project all collections against each other |
350
+ | `project SOURCE` | Cross-collection projection: match chunks against other collections' centroids. `--against TARGETS` for explicit targets (default: sibling collections). `--threshold N` (optional; when omitted uses per-corpus defaults: `code__*` 0.70, `knowledge__*` 0.50, `docs__*`/`rdr__*` 0.55 — see [taxonomy-projection-tuning.md](taxonomy-projection-tuning.md)). `--use-icf` suppresses hub topics via Inverse Collection Frequency weighting (RDR-077). `--persist` to write assignments. `--backfill` to project all collections against each other |
351
+ | `hubs` | List generic-pattern hub topics (RDR-077 Phase 5). `--min-collections N` (default 2), `--max-icf F` filter, `--warn-stale` flags hubs whose latest assignment post-dates the newest `last_discover_at` across contributing source collections, `--explain` shows DF / ICF / matched stopword tokens per row. |
352
+ | `audit --collection NAME` | Per-collection projection-quality report (RDR-077 Phase 6): total assignments, p10/p50/p90 of raw cosine, count below threshold (re-projection candidates), top receiving topics with ICF, pattern-pollution flags. `--threshold F` overrides the per-corpus default; `--top-n N` caps the receiving-topic list. |
348
353
 
349
354
  **Configuration** (in `.nexus.yml`):
350
355
 
@@ -98,6 +98,8 @@ An RDR (Research-Design-Review) is a short document that records a technical dec
98
98
  | [RDR-074](rdr-074-permanence-mode.md) | Permanence Mode | Feature | Deferred | 2026-04-13 |
99
99
  | [RDR-075](rdr-075-cross-collection-topic-projection.md) | Cross-Collection Topic Projection | Feature | Closed (implemented) | 2026-04-13 |
100
100
  | [RDR-076](rdr-076-idempotent-upgrade-mechanism.md) | Idempotent Upgrade Mechanism | Architecture | Closed (implemented) | 2026-04-13 |
101
+ | [RDR-077](rdr-077-projection-quality-similarity-icf.md) | Projection Quality — Similarity Scores and ICF Hub Detection | Feature | Accepted | 2026-04-14 |
102
+ | [RDR-078](rdr-078-unified-context-graph-and-retrieval.md) | Plan-Centric Retrieval — Semantic Plan Matching, Dual-Taxonomy Planning, Scenario Plans | Feature | Draft | 2026-04-14 |
101
103
 
102
104
  ---
103
105
 
@@ -0,0 +1,367 @@
1
+ ---
2
+ title: "RDR-077: Projection Quality — Similarity Scores and ICF Hub Detection"
3
+ status: accepted
4
+ type: feature
5
+ priority: P2
6
+ created: 2026-04-14
7
+ accepted_date: 2026-04-14
8
+ github_issue: 161
9
+ related: [RDR-075, RDR-076]
10
+ reviewed-by: self
11
+ ---
12
+
13
+ # RDR-077: Projection Quality — Similarity Scores and ICF Hub Detection
14
+
15
+ Follow-up to RDR-075 surfaced during the v4.2.2 live shakeout. Cross-collection projection now runs across 93 collections with 689,710 assignments at 92.2% chunk coverage, but the projection graph has two correctable quality problems: we throw away the similarity score that drove each assignment, and generic-pattern hub topics dominate the graph and drown out domain-meaningful signals.
16
+
17
+ ## Problem
18
+
19
+ ### Problem 1: Similarity score is not persisted
20
+
21
+ `topic_assignments` stores `(doc_id, topic_id, assigned_by)` and nothing else. The cosine similarity that produced each projection (already computed in memory by `project_against`) is discarded on write. Downstream this means:
22
+
23
+ - No confidence filtering at query time — we cannot rank projected assignments or filter low-confidence matches without re-running the full matrix multiply.
24
+ - No auditability — we cannot inspect which assignments were borderline vs. high-confidence.
25
+ - No drift detection — we cannot observe whether re-projections move chunks toward or away from their current topics.
26
+ - No temporal queries — `assigned_at` is also missing, so "what did the last backfill add?" is unanswerable.
27
+
28
+ The data to fix this exists; the schema doesn't.
29
+
30
+ ### Problem 2: Generic-pattern hubs dominate projection
31
+
32
+ Top 10 cross-collection hub topics by chunk count after backfill (threshold 0.50):
33
+
34
+ | Topic | Cross-coll chunks | Source collections | Domain meaningful? |
35
+ |---|---:|---:|:---:|
36
+ | Unit Testing and Assertions (Luciferase) | 21,307 | 7 | No — generic |
37
+ | Unit Test Assertions Mocking (workspace) | 13,884 | 9 | No — generic |
38
+ | Java Class and Interface Implementation (Delos) | 13,701 | 7 | No — language pattern |
39
+ | Binary Operator Expression Parsing (Kramer) | 13,374 | 6 | No — generic |
40
+ | Builder Pattern Implementation (Luciferase) | 11,047 | 6 | No — design pattern |
41
+ | JUnit Test Class Structure (Delos) | 10,984 | 7 | No — generic |
42
+ | Member Proposal Consensus Import (Luciferase) | 10,151 | 3 | **Yes — Stereotomy/consensus** |
43
+ | Variable Declaration and Types (ART) | 9,517 | 7 | No — language pattern |
44
+ | GPU Vendor Configuration (Luciferase) | 8,710 | 5 | Possibly |
45
+ | Exception Handling in Tests (Luciferase) | 8,219 | 7 | No — generic |
46
+
47
+ 9 of the top 10 hubs are **language / framework boilerplate**. They appear in nearly every Java codebase and project on everything because Java syntax tokens dominate code-corpus centroids. The one genuinely meaningful hub (Member Proposal Consensus, Stereotomy-specific) is buried.
48
+
49
+ This is the TF-IDF stopword problem applied to topics: high document frequency is a weak discriminator. Users exploring the graph get led to "Unit Testing and Assertions" instead of to Stereotomy, because similarity alone doesn't discount ubiquity.
50
+
51
+ ### Root Cause
52
+
53
+ 1. `project_against` computes similarity in memory then calls `assign_topic(doc_id, topic_id, assigned_by='projection')` — the similarity value has no column to land in.
54
+ 2. `project_against` filters by raw cosine similarity against a single threshold (default 0.85; 0.50 in the backfill). A language-pattern centroid clears that bar for code chunks in any Java corpus.
55
+
56
+ ## Proposed Design
57
+
58
+ ### Phase 1: Schema migration — similarity + assigned_at + source_collection
59
+
60
+ ```sql
61
+ ALTER TABLE topic_assignments ADD COLUMN similarity REAL;
62
+ ALTER TABLE topic_assignments ADD COLUMN assigned_at TEXT;
63
+ ALTER TABLE topic_assignments ADD COLUMN source_collection TEXT;
64
+ CREATE INDEX IF NOT EXISTS idx_topic_assignments_source
65
+ ON topic_assignments(source_collection, assigned_by);
66
+ ```
67
+
68
+ All nullable. `similarity` populated by `project --persist` and the `taxonomy_assign_hook` post-store projection path. NULL for legacy HDBSCAN assignments — cluster membership is not a centroid distance and conflating the two would mislead downstream consumers.
69
+
70
+ `assigned_at` stamped at insert time (`datetime('now')`); NULL for rows predating the migration.
71
+
72
+ `source_collection` is **required for ICF computation** (RF-5) — without it, `DF(topic) = COUNT(DISTINCT source_collection)` is unanswerable from T2 because `doc_id` hashes the collection in an unrecoverable way. Populated at insert time by every `assigned_by='projection'` write path.
73
+
74
+ One-line registration in `nexus.db.migrations.MIGRATIONS` per RDR-076 pattern:
75
+
76
+ ```python
77
+ Migration(introduced="4.3.0", name="add_projection_quality_columns", fn=_add_projection_quality_columns),
78
+ ```
79
+
80
+ The migration adds columns + index only; no data backfill. Pre-existing projection rows (from v4.2.x) keep NULL similarity/source_collection and are excluded from ICF/audit outputs until a `nx taxonomy project --backfill` reruns them.
81
+
82
+ ### Phase 2: Populate similarity + source_collection on the write path
83
+
84
+ `taxonomy.assign_topic()` grows two optional parameters:
85
+
86
+ ```python
87
+ def assign_topic(
88
+ self,
89
+ doc_id: str,
90
+ topic_id: int,
91
+ *,
92
+ assigned_by: str = "hdbscan",
93
+ similarity: float | None = None,
94
+ source_collection: str | None = None,
95
+ ) -> None:
96
+ ```
97
+
98
+ **Upsert semantics split by `assigned_by` (RF-8; resolves PQ-6 → prefer-higher)**:
99
+
100
+ - Projection rows use a portable UPSERT that does not depend on SQLite 3.38+ `ON CONFLICT ... WHERE`:
101
+
102
+ ```sql
103
+ INSERT INTO topic_assignments
104
+ (doc_id, topic_id, assigned_by, similarity, assigned_at, source_collection)
105
+ VALUES (?, ?, 'projection', ?, ?, ?)
106
+ ON CONFLICT(doc_id, topic_id) DO UPDATE SET
107
+ similarity = MAX(topic_assignments.similarity, excluded.similarity),
108
+ assigned_at = CASE
109
+ WHEN excluded.similarity > COALESCE(topic_assignments.similarity, -1.0)
110
+ THEN excluded.assigned_at
111
+ ELSE topic_assignments.assigned_at
112
+ END,
113
+ source_collection = CASE
114
+ WHEN excluded.similarity > COALESCE(topic_assignments.similarity, -1.0)
115
+ THEN excluded.source_collection
116
+ ELSE topic_assignments.source_collection
117
+ END;
118
+ ```
119
+
120
+ The `MAX()` + `CASE` pattern is valid on all SQLite versions that support `ON CONFLICT DO UPDATE` (3.24+, Python 3.12 ships 3.39+). No `WHERE` clause on the `DO UPDATE` target, which would require 3.38+.
121
+
122
+ **NULL-existing guard**: `COALESCE(topic_assignments.similarity, -1.0)` inside the `CASE` predicate handles pre-migration legacy rows (where `similarity IS NULL`). Without it, `excluded.similarity > NULL` evaluates to NULL (falsy) and the provenance columns (`assigned_at`, `source_collection`) would silently *not* refresh even when `MAX()` promotes `similarity` from NULL to the new value — leaving the row internally inconsistent and invisible to ICF / hub queries that filter on `source_collection IS NOT NULL`. Since cosine similarity is in [0, 1], `-1.0` is safely below any real value.
123
+
124
+ **Prefer-higher semantics**: re-projection with a better score refreshes the row and its timestamp; a worse score leaves the stored value untouched (`MAX` preserves it). Rationale: centroid drift is slow, spurious small-delta regressions are common (different sibling set + order-of-assign causes ±0.02 noise), stable-under-re-runs is the desired property.
125
+
126
+ - HDBSCAN rows keep `INSERT OR IGNORE` — cluster membership is deterministic per discover run.
127
+
128
+ **Stored vs. adjusted similarity (resolves Observation from Gate 2)**: the `similarity` column always stores the **raw cosine** value. ICF weighting (Phase 4) is applied at *query/ranking/filter* time, not at write time. This keeps the column audit-friendly (Phase 6), prevents re-projection oscillation when the ICF denominator changes as the corpus grows, and means hub-suppressed assignments are simply not written (the threshold filter in Phase 4 applies to the adjusted score; below-threshold rows never call `assign_topic`).
129
+
130
+ Five write-path updates (all must land in the same commit to keep the tree buildable):
131
+
132
+ 1. **`project_against` (catalog_taxonomy.py:1501)**: change `chunk_assignments.append((doc_id, tid))` to `chunk_assignments.append((doc_id, tid, float(sim[i, idx])))`. The per-chunk similarity is already in memory at line 1497 — the tuple shape change is the whole fix. The `result['chunk_similarities']` key claimed in the v0 draft **does not exist** (RF-2); no code relies on it.
133
+
134
+ 2. **`_persist_assignments` (taxonomy_cmd.py:1121)**: unpack the 3-tuple and pass `similarity=sim, source_collection=source` to `assign_topic`.
135
+
136
+ 2a. **`backfill_projection` (db/migrations.py:352-353)** — **already-executing production code, not a stub**: currently reads `for doc_id, topic_id in assignments:` and calls `taxonomy.assign_topic(doc_id, topic_id, assigned_by='projection')`. Must change to 3-tuple unpack + pass `similarity` and `source_collection` in the same Phase 2 commit, otherwise `nx upgrade` crashes with `ValueError: too many values to unpack` on any deployment re-running the RDR-075 T3UpgradeStep. SC-8 must include a regression test that exercises `backfill_projection` against the Phase-1 schema.
137
+
138
+ 3. **`taxonomy_assign_hook` (mcp_infra.py:321)**: `assign_single` already receives a ChromaDB `results` dict that includes `distances` but discards it at line 1299. Change `assign_single` return type from `int | None` to `AssignResult | None` (NamedTuple with `topic_id: int` + `similarity: float`). **This is a breaking API change.** All call sites must migrate atomically in the same commit:
139
+ - `mcp_infra.py:316` — `topic_id = taxonomy.assign_single(...)` → `result = taxonomy.assign_single(...); topic_id = result.topic_id if result else None`
140
+ - `mcp_infra.py:321` — same pattern; similarity passed to the cross-collection `assign_topic` call at line 325
141
+ - Any internal helpers in `catalog_taxonomy.py` that call `assign_single`
142
+
143
+ Using a NamedTuple (not bare tuple) means `if topic_id is not None` on the old scalar path fails-loud at type-check, not silent-true on a non-None tuple. Add explicit mypy/ruff check in the migration commit.
144
+
145
+ **Exact distance extraction**: ChromaDB returns `distances` as list-of-lists (`[[d1, d2, ...]]`) even for `n_results=1`. The correct capture is `similarity = 1.0 - float(results["distances"][0][0])` (ChromaDB returns cosine *distance*, not similarity — invert). Add SC-8 test for this extraction shape to guard against `IndexError` on the wrong axis.
146
+
147
+ 4. **`assign_batch(..., cross_collection=True)` (catalog_taxonomy.py:1357/1363)**: same tuple-shape change as `project_against`.
148
+
149
+ HDBSCAN path (`assign_batch` from `discover()`) continues to pass `similarity=None, source_collection=None` — NULL is semantically correct for cluster membership.
150
+
151
+ ### Phase 3: ICF computation
152
+
153
+ **Inverse Collection Frequency** for a topic, using **log base 2** (conventional for IDF variants; predictable numeric scale for threshold calibration):
154
+
155
+ ```
156
+ ICF(topic) = log2(N_effective / DF(topic))
157
+ ```
158
+
159
+ Where:
160
+
161
+ - `N_effective` = number of distinct `source_collection` values appearing in `topic_assignments` with `assigned_by='projection'` and `source_collection IS NOT NULL`. Pre-migration rows (NULL `source_collection`) are excluded from both numerator and denominator — they carry no collection signal and their inclusion would bias results toward spurious hubs.
162
+ - `DF(topic)` = number of distinct `source_collection` values in projection rows for that topic.
163
+
164
+ **Guards**:
165
+ - `DF = 0` is impossible by construction — if a topic has no projection assignments, it does not appear in the aggregation and has no ICF. Audit and hubs commands only query over joined projection rows.
166
+ - `DF = N_effective` yields `ICF = log2(1) = 0`. This is the intended behavior for ubiquitous hub topics — similarity contributes nothing after weighting.
167
+ - `N_effective < 2` (e.g. a single-collection corpus) disables ICF entirely — return raw similarity. See PQ-1.
168
+
169
+ **Authoritative SQL** (no placeholder — uses the new `source_collection` column from Phase 1):
170
+
171
+ ```sql
172
+ WITH n_eff AS (
173
+ SELECT COUNT(DISTINCT source_collection) AS n
174
+ FROM topic_assignments
175
+ WHERE assigned_by = 'projection' AND source_collection IS NOT NULL
176
+ )
177
+ SELECT
178
+ ta.topic_id,
179
+ COUNT(DISTINCT ta.source_collection) AS df,
180
+ LOG2(CAST((SELECT n FROM n_eff) AS REAL)
181
+ / COUNT(DISTINCT ta.source_collection)) AS icf
182
+ FROM topic_assignments ta
183
+ WHERE ta.assigned_by = 'projection' AND ta.source_collection IS NOT NULL
184
+ GROUP BY ta.topic_id
185
+ HAVING COUNT(DISTINCT ta.source_collection) > 0;
186
+ ```
187
+
188
+ SQLite has no native `LOG2`; use `LOG(x) / LOG(2)` or register a Python scalar function at connection init (simpler, deterministic across SQLite versions).
189
+
190
+ **Caching**:
191
+ - `taxonomy_assign_hook` path (single-doc, real-time): **no cache**. ICF for one topic is a single index-scan and recomputing per assignment avoids stale-cache hazards from concurrent MCP writes.
192
+ - `nx taxonomy project --persist` path (bulk): compute full ICF map once at the start of the command run, hold it for the duration. The corpus is effectively frozen during a single bulk run (MCP writes during the run are rare and their absence from this run's ICF is acceptable — next `--persist` picks them up). Cache lives on the local `CatalogTaxonomy` call object and is garbage-collected when the command returns.
193
+ - `nx taxonomy hubs` / `nx taxonomy audit`: per-invocation compute; no cross-invocation cache.
194
+
195
+ ### Phase 4: ICF-weighted projection
196
+
197
+ New option on `nx taxonomy project` and on `taxonomy_assign_hook`:
198
+
199
+ ```bash
200
+ nx taxonomy project SRC --use-icf --threshold 0.50 --persist
201
+ ```
202
+
203
+ At assignment time:
204
+ ```
205
+ adjusted_similarity = raw_cosine * ICF(target_topic)
206
+ ```
207
+ Hub topics (DF→N) have ICF→0 and get suppressed. Domain-specific topics (DF=1..3) retain most of their similarity.
208
+
209
+ Per-corpus-type default thresholds (applied when `--threshold` not explicit):
210
+
211
+ | Source prefix | Default threshold | Rationale |
212
+ |---|---:|---|
213
+ | `code__*` | 0.70 | Java/Python syntax inflates raw cosine; stricter cut-off filters pattern noise |
214
+ | `knowledge__*` | 0.50 | Dense prose, semantically rich — threshold validated in backfill |
215
+ | `docs__*` | 0.55 | Mixed prose + code snippets |
216
+ | `rdr__*` | 0.55 | Same as docs |
217
+
218
+ Threshold calibration process documented in `docs/taxonomy-projection-tuning.md` (new).
219
+
220
+ ### Phase 5: `nx taxonomy hubs` — generic-pattern detector
221
+
222
+ ```bash
223
+ nx taxonomy hubs --min-collections 5 --max-icf 1.2
224
+ ```
225
+
226
+ Lists topics flagged as likely generic hubs: high cross-collection DF, low ICF, label contains stopword-like tokens (configurable list: `assert`, `junit`, `builder`, `class`, `import`, `exception`, `getter`, `setter`, `variable`, `declaration`, `operator`). Output sorted by `chunks × (1 - ICF)` to surface the worst offenders first.
227
+
228
+ **Staleness warning (related to PQ-7)**: `hubs` output accuracy degrades after `discover --rebuild` — stored `similarity` values and `assigned_at` timestamps were stamped against pre-rebuild centroids. Add `--warn-stale` flag that compares `max(assigned_at)` for each contributing collection against the most recent `discover --rebuild` timestamp (tracked in `taxonomy_meta.last_discover_at`) and prints a warning when hub evidence is older than the last rebuild. Implementation note: `taxonomy_meta.last_discover_at` already exists from RDR-075 infrastructure.
229
+
230
+ ### Phase 6: `nx taxonomy audit`
231
+
232
+ ```bash
233
+ nx taxonomy audit --collection docs__nexus
234
+ ```
235
+
236
+ Distribution of similarities for the collection's projected assignments: quantiles (p10/p50/p90), count below threshold (for re-projection detection), top hub topics receiving this collection's chunks, likely pattern-pollution flags.
237
+
238
+ ## Success Criteria
239
+
240
+ - **SC-1**: `topic_assignments` has `similarity REAL NULL`, `assigned_at TEXT NULL`, and `source_collection TEXT NULL` columns after the 4.3.0 migration, plus the `(source_collection, assigned_by)` index.
241
+ - **SC-2**: `project --persist` and `taxonomy_assign_hook` populate `similarity` and `source_collection` for every projection assignment; HDBSCAN assignments keep NULL for both. Re-projection uses **prefer-higher upsert**. Three-case test: (a) re-project with `similarity=0.9` then `similarity=0.7` — stored row reads `0.9`; (b) re-project with `0.7` then `0.9` — stored row reads `0.9` with refreshed `assigned_at` and `source_collection`; (c) re-project a legacy row (pre-migration, `similarity=NULL`, `assigned_at=NULL`, `source_collection=NULL`) with `similarity=0.6` — all three columns populated with the new values (verifies the `COALESCE(-1.0)` NULL guard).
242
+ - **SC-3**: `nx taxonomy project --use-icf` applies ICF weighting and produces a measurably reordered top-K ranking vs. default on a test fixture of ≥10 collections. **The ≥10 is a calibration choice** (ensures ICF scores have enough spread to reorder the top-K), not a guard threshold — ICF is only disabled when `N_effective < 2` per PQ-1. A 3-collection fixture would still exercise ICF correctly but might not produce a visible ranking change.
243
+ - **SC-4**: `nx taxonomy hubs` detects synthetic pattern-pollution hubs in the test fixture. Fixture construction: 5 fake collections × 100 docs each, half of them assigned to a single "stopword-labeled" topic (label contains `assert` or `junit`), the other half spread across distinct domain topics. The detector must surface the stopword-labeled topic as a hub and exclude single-collection domain topics. Live-corpus validation (real top-10 hubs) is an observational acceptance signal but **not** the SC — it cannot be made reproducible without bundling the live DB.
244
+ - **SC-5**: Per-corpus-type default thresholds applied when `--threshold` not specified; documented in CLI help and in `docs/taxonomy-projection-tuning.md`.
245
+ - **SC-6**: `nx taxonomy audit` prints similarity distribution (p10/p50/p90), below-threshold count, top receiving hubs, and pattern-pollution flags for a collection.
246
+ - **SC-7**: Post-ICF backfill measurement shows domain-meaningful hubs (e.g. Member Proposal Consensus) ranked above language-pattern hubs by `chunks × ICF`.
247
+ - **SC-8**: Zero regressions on `tests/test_taxonomy.py`; new tests cover migration, similarity persistence (including prefer-higher upsert invariant and `results["distances"][0][0]` extraction shape), ICF computation (log2 base, N_effective definition, DF=N → 0, N<2 disables), hubs detection against the synthetic fixture, and a `backfill_projection` regression test that exercises the Phase-1 schema end-to-end to catch tuple-shape drift in `db/migrations.py`.
248
+
249
+ ## Research Findings
250
+
251
+ ### RF-1: Schema claim confirmed; no similarity, assigned_at, or source_collection
252
+
253
+ `src/nexus/db/t2/catalog_taxonomy.py:80-85`:
254
+
255
+ ```sql
256
+ CREATE TABLE IF NOT EXISTS topic_assignments (
257
+ doc_id TEXT NOT NULL,
258
+ topic_id INTEGER NOT NULL REFERENCES topics(id),
259
+ assigned_by TEXT NOT NULL DEFAULT 'hdbscan',
260
+ PRIMARY KEY (doc_id, topic_id)
261
+ );
262
+ ```
263
+
264
+ Three inline migrations on `_init_schema` (lines 181–213: `migrate_topics`, `migrate_assigned_by`, `migrate_review_columns`) — none add the missing columns. `src/nexus/db/migrations.py` has zero hits for `similarity` or `assigned_at`.
265
+
266
+ Seven INSERT sites total, all three-column: `assign_topic()` at line 250 plus inline copies at lines 469, 745, 1026, 1771, 1807, 1821. Every write path has to grow to accept similarity; can't leave legacy paths writing the narrower tuple because `INSERT OR IGNORE` (see RF-8) will silently win over later updates.
267
+
268
+ ### RF-2: Similarity drop site — RDR's key name was wrong
269
+
270
+ In `project_against` (`catalog_taxonomy.py:1370`):
271
+
272
+ - Matrix multiply at line 1481: `sim = src_norm @ ctr_norm.T`
273
+ - Per-centroid value read at line 1497: `float(sim[i, idx])` — accumulated into `topic_stats[tid]["total_similarity"]`
274
+ - `chunk_assignments` built at line 1501: `chunk_assignments.append((doc_id, tid))` — bare `(str, int)` tuple. **Similarity dropped here.**
275
+
276
+ Return dict (lines 1536–1542): `matched_topics`, `novel_chunks`, `chunk_assignments`, `total_chunks`, `total_centroids`. **No `chunk_similarities` key — the earlier design note was wrong.** `matched_topics[].avg_similarity` is a per-topic aggregate, not per-chunk. The fix is to change `chunk_assignments` to `list[tuple[str, int, float]]` — the data is already in memory at line 1497.
277
+
278
+ ### RF-3: assign_topic signature and call sites
279
+
280
+ `assign_topic(doc_id, topic_id, *, assigned_by='hdbscan')` — line 244, no similarity param. Four call sites pass `assigned_by='projection'`, all must migrate atomically in the Phase 2 commit:
281
+
282
+ - `mcp_infra.py:325` — `_run_taxonomy_assign` cross-collection branch
283
+ - `taxonomy_cmd.py:1121` — `_persist_assignments()` (backfill and project commands)
284
+ - `db/migrations.py:353` — T3 upgrade step backfill (RDR-075)
285
+ - `catalog_taxonomy.py:1357/1363` — `assign_batch` with `cross_collection=True` (both branches of the batch call site count as one migration target)
286
+
287
+ Additional inline INSERT sites in `catalog_taxonomy.py` not passing `assigned_by='projection'` (lines 469, 745, 1026, 1771, 1807, 1821) also need tuple-shape audit — `INSERT OR REPLACE` at 1807/1821 already partially implements upsert for manual-assignment paths and is compatible with the new column list.
288
+
289
+ ### RF-4: taxonomy_assign_hook — similarity available at zero cost
290
+
291
+ `_run_taxonomy_assign` (`mcp_infra.py:284-325`) calls `assign_single` (line 321), which queries `taxonomy__centroids` at line 1292 and returns only `int(results["metadatas"][0][0]["topic_id"])` at line 1299. **`results["distances"]` is returned by ChromaDB but never read.** Capturing it is a one-line change in `assign_single`; no extra query, no extra cost.
292
+
293
+ ### RF-5: ICF data path requires a source_collection column — PQ-5 is mandatory
294
+
295
+ No direct collection lookup from `doc_id` exists:
296
+
297
+ - `topic_assignments` has only `(doc_id, topic_id, assigned_by)`.
298
+ - `topics.collection` is the **target** topic's collection, not the source.
299
+ - `doc_id` for T3 chunks is `sha256("{collection}:{title}")[:16]` (`db/t3.py:380`) — collection hashed in, not recoverable.
300
+ - No `chunk_metadata` table exists.
301
+
302
+ **PQ-5 graduates from an open question to a requirement.** Without `topic_assignments.source_collection`, computing `DF(topic) = COUNT(DISTINCT source_collection)` is impossible from T2. T3 reverse-lookup is per-doc and will not scale to 689k rows.
303
+
304
+ ### RF-6: Centroid dimensionality is mode-dependent
305
+
306
+ Collection name: `taxonomy__centroids`. Comment at `catalog_taxonomy.py:882`: *"Uses embedding_function=None (pre-computed MiniLM 384d vectors)"*. In cloud mode, `_run_taxonomy_assign` fetches the existing T3 Voyage embedding (`mcp_infra.py:299-304`, 1024d) before calling `assign_single`. `_check_centroid_dimension` (lines 111–134) guards against mismatch. **The RDR's "1024d voyage vectors" claim is only true in cloud mode.** All math in this RDR (similarity, ICF) is dimension-agnostic; no design change — just accuracy fix in narrative.
307
+
308
+ Fetch path in `project_against`: paginated GET at lines 1448–1452, no query embedding, raw matrix multiply.
309
+
310
+ ### RF-7: Hub SQL — current schema cannot distinguish hubs from volume
311
+
312
+ With `source_collection` column landed (from RF-5 requirement):
313
+
314
+ ```sql
315
+ SELECT
316
+ t.id, t.label, t.collection,
317
+ COUNT(*) AS total_projection_chunks,
318
+ COUNT(DISTINCT ta.source_collection) AS distinct_source_collections
319
+ FROM topic_assignments ta
320
+ JOIN topics t ON t.id = ta.topic_id
321
+ WHERE ta.assigned_by = 'projection'
322
+ GROUP BY t.id, t.label, t.collection
323
+ ORDER BY distinct_source_collections DESC, total_projection_chunks DESC
324
+ LIMIT 20;
325
+ ```
326
+
327
+ Today, the best the schema can do is rank topics by projection chunk volume — blind to whether those chunks came from one collection or twenty. **Hub detection is impossible without the schema change.** The "top-10 hubs" table in the Problem section was produced by external SQL joining against separate collection metadata (live backfill); it cannot be reproduced from T2 alone in v4.2.2.
328
+
329
+ ### RF-8: `INSERT OR IGNORE` blocks similarity refresh
330
+
331
+ `assign_topic` uses `INSERT OR IGNORE` (line 250). After the schema migration, re-projecting a doc that already has an assignment row will silently skip — the similarity column will never update. Need explicit `INSERT ... ON CONFLICT DO UPDATE SET similarity = excluded.similarity, assigned_at = excluded.assigned_at WHERE excluded.similarity > similarity` (or unconditional REPLACE for projection assignments). HDBSCAN rows stay `INSERT OR IGNORE` — cluster membership is deterministic per discover run.
332
+
333
+ ### RF-9: Re-discovery interaction with Phase-3 post-pass
334
+
335
+ `discover_topics` exits early if any topics already exist for the collection (`catalog_taxonomy.py:963-974`). Docs indexed **after** the initial discover are assigned to existing centroids that were computed without them. Projection assignments from the `taxonomy_assign_hook` path on a newly-indexed doc will use those stale centroids, and there is no mechanism to refresh projection assignments after a later `discover --rebuild`. This is an RDR-075 legacy issue but compounds here: the similarity column will be stamped with a value computed against potentially stale centroids.
336
+
337
+ **Mitigation option**: `nx taxonomy audit` (Phase 6) can surface the delta by comparing stored `similarity` against a fresh recomputation — falling similarities indicate centroid drift.
338
+
339
+ ### Design impacts from research
340
+
341
+ | Original design | Revised after research |
342
+ |---|---|
343
+ | Add `similarity` + `assigned_at` columns | Add `similarity` + `assigned_at` + **`source_collection`** (PQ-5 mandatory) |
344
+ | Carry similarity via `result['chunk_similarities']` | Change `chunk_assignments` tuple to `(doc_id, topic_id, similarity)` — key did not exist |
345
+ | "1024d voyage centroids" | Dimension-agnostic; cloud=1024d (voyage), local=384d (MiniLM) |
346
+ | `assign_topic` INSERT OR IGNORE unchanged | Split by `assigned_by`: projection needs upsert; HDBSCAN keeps ignore |
347
+ | taxonomy_assign_hook — no similarity | Similarity is already in ChromaDB response, one-line capture |
348
+
349
+ ## Proposed Questions
350
+
351
+ - **PQ-1**: Does ICF weighting over-correct for small corpora? With only 3 collections, `log(3/2) ≈ 0.4` squashes even legitimate high-similarity matches. Minimum-collection threshold below which ICF weighting is disabled?
352
+ - **PQ-2**: Config-driven per-corpus-type thresholds (`.nexus.yml`) vs. hard-coded, given users' corpora differ?
353
+ - **PQ-3**: Stopword token list for `hubs` detection — bundled defaults + user extension, or pure defaults?
354
+ - **PQ-4**: How to distinguish "generic hub" (language/framework noise) from "cross-cutting concept" (e.g. "Consensus" legitimately spanning multiple collections in a blockchain workspace)? Label-token heuristic conflates them. **Risk**: `nx taxonomy hubs` will flag legitimate cross-cutting concepts as pollution in domain-specific workspaces. Mitigation: `hubs` output is advisory (not auto-remediation); `--explain` flag shows WHY a topic was flagged so the user can accept or suppress via user-extensible stopword list (PQ-3).
355
+ - **PQ-5** (RESOLVED by RF-5 — now mandatory): Adding `source_collection` to `topic_assignments` is required, not optional. Without it, ICF is uncomputable from T2.
356
+ - **PQ-6** (RESOLVED — prefer-higher): Upsert semantics for projection rows use prefer-higher (Phase 2, lines 97–102). Rationale: centroid drift is slow, spurious small-delta regressions are common (order-of-assign noise ±0.02), stable-under-re-runs is the desired property. Always-latest rejected.
357
+ - **PQ-7** (from RF-9): Should `discover --rebuild` invalidate prior projection assignments for the rebuilt collection (to force re-projection against fresh centroids)? Or leave them and flag divergence via audit?
358
+
359
+ ## Related
360
+
361
+ - Supersedes GitHub issue **#161** (see issue for the original problem statement and concrete data).
362
+ - Builds on RDR-075 (cross-collection projection) and uses the migration registry from RDR-076.
363
+ - Tracked by bead `nexus-act`.
364
+
365
+ ### RDR-075 bookkeeping
366
+
367
+ RDR-075 closed at v4.2.2 implements the assignment *routing* (cross-collection hook fires, matches get written). The quality *metadata* (similarity, source_collection, upsert semantics) was deferred to this RDR. RDR-075 itself does not need amendment — its SCs were scoped to routing — but a close-note linking forward to RDR-077 should be added when this RDR accepts, so future readers understand the v4.2.2 baseline persists nothing about assignment confidence.