conexus 2.4.0__tar.gz → 2.4.2__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 (363) hide show
  1. {conexus-2.4.0 → conexus-2.4.2}/.claude-plugin/marketplace.json +1 -1
  2. {conexus-2.4.0 → conexus-2.4.2}/CHANGELOG.md +16 -0
  3. {conexus-2.4.0 → conexus-2.4.2}/PKG-INFO +1 -1
  4. {conexus-2.4.0 → conexus-2.4.2}/docs/getting-started.md +9 -2
  5. conexus-2.4.2/docs/postmortem/2026-03-24-pdf-index-fix-not-applied.md +142 -0
  6. {conexus-2.4.0 → conexus-2.4.2}/docs/rdr/post-mortem/cce-query-model-mismatch.md +40 -18
  7. {conexus-2.4.0 → conexus-2.4.2}/nx/CHANGELOG.md +8 -0
  8. {conexus-2.4.0 → conexus-2.4.2}/pyproject.toml +1 -1
  9. {conexus-2.4.0 → conexus-2.4.2}/src/nexus/commands/index.py +9 -1
  10. {conexus-2.4.0 → conexus-2.4.2}/src/nexus/commands/memory.py +5 -1
  11. {conexus-2.4.0 → conexus-2.4.2}/tests/test_index_cmd.py +48 -0
  12. {conexus-2.4.0 → conexus-2.4.2}/uv.lock +1 -1
  13. {conexus-2.4.0 → conexus-2.4.2}/.beads/.gitignore +0 -0
  14. {conexus-2.4.0 → conexus-2.4.2}/.beads/README.md +0 -0
  15. {conexus-2.4.0 → conexus-2.4.2}/.beads/config.yaml +0 -0
  16. {conexus-2.4.0 → conexus-2.4.2}/.beads/hooks/post-checkout +0 -0
  17. {conexus-2.4.0 → conexus-2.4.2}/.beads/hooks/post-merge +0 -0
  18. {conexus-2.4.0 → conexus-2.4.2}/.beads/hooks/pre-commit +0 -0
  19. {conexus-2.4.0 → conexus-2.4.2}/.beads/hooks/pre-push +0 -0
  20. {conexus-2.4.0 → conexus-2.4.2}/.beads/hooks/prepare-commit-msg +0 -0
  21. {conexus-2.4.0 → conexus-2.4.2}/.beads/interactions.jsonl +0 -0
  22. {conexus-2.4.0 → conexus-2.4.2}/.beads/issues.jsonl +0 -0
  23. {conexus-2.4.0 → conexus-2.4.2}/.beads/metadata.json +0 -0
  24. {conexus-2.4.0 → conexus-2.4.2}/.claude/skills/release.md +0 -0
  25. {conexus-2.4.0 → conexus-2.4.2}/.devcontainer/Dockerfile +0 -0
  26. {conexus-2.4.0 → conexus-2.4.2}/.devcontainer/devcontainer.json +0 -0
  27. {conexus-2.4.0 → conexus-2.4.2}/.dockerignore +0 -0
  28. {conexus-2.4.0 → conexus-2.4.2}/.env.example +0 -0
  29. {conexus-2.4.0 → conexus-2.4.2}/.gitattributes +0 -0
  30. {conexus-2.4.0 → conexus-2.4.2}/.github/workflows/ci.yml +0 -0
  31. {conexus-2.4.0 → conexus-2.4.2}/.github/workflows/release.yml +0 -0
  32. {conexus-2.4.0 → conexus-2.4.2}/.gitignore +0 -0
  33. {conexus-2.4.0 → conexus-2.4.2}/.markdownlint.json +0 -0
  34. {conexus-2.4.0 → conexus-2.4.2}/AGENTS.md +0 -0
  35. {conexus-2.4.0 → conexus-2.4.2}/CLAUDE.md +0 -0
  36. {conexus-2.4.0 → conexus-2.4.2}/Formula/nx.rb +0 -0
  37. {conexus-2.4.0 → conexus-2.4.2}/LICENSE +0 -0
  38. {conexus-2.4.0 → conexus-2.4.2}/README.md +0 -0
  39. {conexus-2.4.0 → conexus-2.4.2}/docs/README.md +0 -0
  40. {conexus-2.4.0 → conexus-2.4.2}/docs/architecture.md +0 -0
  41. {conexus-2.4.0 → conexus-2.4.2}/docs/cli-reference.md +0 -0
  42. {conexus-2.4.0 → conexus-2.4.2}/docs/configuration.md +0 -0
  43. {conexus-2.4.0 → conexus-2.4.2}/docs/contributing.md +0 -0
  44. {conexus-2.4.0 → conexus-2.4.2}/docs/historical/README.md +0 -0
  45. {conexus-2.4.0 → conexus-2.4.2}/docs/historical/architecture.md +0 -0
  46. {conexus-2.4.0 → conexus-2.4.2}/docs/historical/plans/2026-02-23-rdr-workflow-skills-design.md +0 -0
  47. {conexus-2.4.0 → conexus-2.4.2}/docs/historical/plans/2026-02-23-rdr-workflow-skills-impl-plan.md +0 -0
  48. {conexus-2.4.0 → conexus-2.4.2}/docs/historical/plans/2026-02-24-nx-plugin-v0.4.0.md +0 -0
  49. {conexus-2.4.0 → conexus-2.4.2}/docs/historical/plans/2026-02-24-smart-repo-indexing-design.md +0 -0
  50. {conexus-2.4.0 → conexus-2.4.2}/docs/historical/plans/2026-02-24-smart-repo-indexing-impl-plan.md +0 -0
  51. {conexus-2.4.0 → conexus-2.4.2}/docs/historical/spec.md +0 -0
  52. {conexus-2.4.0 → conexus-2.4.2}/docs/memory-and-tasks.md +0 -0
  53. {conexus-2.4.0 → conexus-2.4.2}/docs/plans/2026-02-28-rdr-004-four-store-cloud-design.md +0 -0
  54. {conexus-2.4.0 → conexus-2.4.2}/docs/plans/2026-02-28-rdr-004-four-store-cloud-impl-plan.md +0 -0
  55. {conexus-2.4.0 → conexus-2.4.2}/docs/plans/2026-03-01-dry-run-pdf-design.md +0 -0
  56. {conexus-2.4.0 → conexus-2.4.2}/docs/plans/2026-03-01-dry-run-pdf-impl-plan.md +0 -0
  57. {conexus-2.4.0 → conexus-2.4.2}/docs/plans/2026-03-01-pdfplumber-tier-design.md +0 -0
  58. {conexus-2.4.0 → conexus-2.4.2}/docs/plans/2026-03-01-rc10-1.0.0-readiness-design.md +0 -0
  59. {conexus-2.4.0 → conexus-2.4.2}/docs/plans/2026-03-01-rc10-critique-findings.md +0 -0
  60. {conexus-2.4.0 → conexus-2.4.2}/docs/plans/2026-03-02-classifier-skip-design.md +0 -0
  61. {conexus-2.4.0 → conexus-2.4.2}/docs/plans/2026-03-03-chunk-byte-cap-design.md +0 -0
  62. {conexus-2.4.0 → conexus-2.4.2}/docs/plans/2026-03-03-chunk-byte-cap-impl-plan.md +0 -0
  63. {conexus-2.4.0 → conexus-2.4.2}/docs/plans/2026-03-03-force-reindex-impl-plan.md +0 -0
  64. {conexus-2.4.0 → conexus-2.4.2}/docs/plans/2026-03-03-rdr017-phase2-cli-monitor-design.md +0 -0
  65. {conexus-2.4.0 → conexus-2.4.2}/docs/plans/2026-03-03-rdr017-phase2-cli-monitor-impl-plan.md +0 -0
  66. {conexus-2.4.0 → conexus-2.4.2}/docs/plans/2026-03-03-rdr018-git-hooks-impl-plan.md +0 -0
  67. {conexus-2.4.0 → conexus-2.4.2}/docs/plans/2026-03-04-doc-ux-polish-design.md +0 -0
  68. {conexus-2.4.0 → conexus-2.4.2}/docs/plans/2026-03-04-rdr-doc-polish-design.md +0 -0
  69. {conexus-2.4.0 → conexus-2.4.2}/docs/plans/2026-03-07-rdr-023-agent-tool-permissions-design.md +0 -0
  70. {conexus-2.4.0 → conexus-2.4.2}/docs/plans/2026-03-07-rdr-023-agent-tool-permissions-impl-plan.md +0 -0
  71. {conexus-2.4.0 → conexus-2.4.2}/docs/plans/2026-03-08-rdr-025-language-agnostic-agents-impl-plan.md +0 -0
  72. {conexus-2.4.0 → conexus-2.4.2}/docs/plans/2026-03-09-rdr-027-search-ux-impl-plan.md +0 -0
  73. {conexus-2.4.0 → conexus-2.4.2}/docs/plans/2026-03-09-rdr-028-language-registry-impl-plan.md +0 -0
  74. {conexus-2.4.0 → conexus-2.4.2}/docs/plans/2026-03-09-rdr-029-pipeline-versioning-impl-plan.md +0 -0
  75. {conexus-2.4.0 → conexus-2.4.2}/docs/plans/2026-03-09-rdr-030-reliability-hardening-impl-plan.md +0 -0
  76. {conexus-2.4.0 → conexus-2.4.2}/docs/plans/2026-03-11-rdr-034-mcp-server-impl-plan.md +0 -0
  77. {conexus-2.4.0 → conexus-2.4.2}/docs/plans/2026-03-21-rdr039-phase2-hooks-impl-plan.md +0 -0
  78. {conexus-2.4.0 → conexus-2.4.2}/docs/plans/2026-03-23-rdr-040-impl-plan.md +0 -0
  79. {conexus-2.4.0 → conexus-2.4.2}/docs/postmortem/2026-03-23-pdf-index-collection-mismatch.md +0 -0
  80. {conexus-2.4.0 → conexus-2.4.2}/docs/rdr/README.md +0 -0
  81. {conexus-2.4.0 → conexus-2.4.2}/docs/rdr/post-mortem/001-rdr-process-validation.md +0 -0
  82. {conexus-2.4.0 → conexus-2.4.2}/docs/rdr/post-mortem/002-t2-status-synchronization.md +0 -0
  83. {conexus-2.4.0 → conexus-2.4.2}/docs/rdr/post-mortem/010-t1-http-server.md +0 -0
  84. {conexus-2.4.0 → conexus-2.4.2}/docs/rdr/post-mortem/011-pdf-ingest-test-coverage.md +0 -0
  85. {conexus-2.4.0 → conexus-2.4.2}/docs/rdr/post-mortem/012-pdfplumber-extraction-tier.md +0 -0
  86. {conexus-2.4.0 → conexus-2.4.2}/docs/rdr/post-mortem/014-knowledge-base-retrieval-quality.md +0 -0
  87. {conexus-2.4.0 → conexus-2.4.2}/docs/rdr/post-mortem/015-indexing-pipeline-rethink.md +0 -0
  88. {conexus-2.4.0 → conexus-2.4.2}/docs/rdr/post-mortem/016-ast-chunk-line-range-bug.md +0 -0
  89. {conexus-2.4.0 → conexus-2.4.2}/docs/rdr/post-mortem/017-indexing-progress-reporting.md +0 -0
  90. {conexus-2.4.0 → conexus-2.4.2}/docs/rdr/post-mortem/018-replace-serve-with-git-hooks.md +0 -0
  91. {conexus-2.4.0 → conexus-2.4.2}/docs/rdr/post-mortem/023-agent-tool-permissions-audit.md +0 -0
  92. {conexus-2.4.0 → conexus-2.4.2}/docs/rdr/post-mortem/024-rdr-process-guardrails.md +0 -0
  93. {conexus-2.4.0 → conexus-2.4.2}/docs/rdr/post-mortem/028-language-registry-unification.md +0 -0
  94. {conexus-2.4.0 → conexus-2.4.2}/docs/rdr/post-mortem/029-pipeline-versioning.md +0 -0
  95. {conexus-2.4.0 → conexus-2.4.2}/docs/rdr/rdr-001-rdr-process-validation.md +0 -0
  96. {conexus-2.4.0 → conexus-2.4.2}/docs/rdr/rdr-002-t2-status-synchronization.md +0 -0
  97. {conexus-2.4.0 → conexus-2.4.2}/docs/rdr/rdr-004-four-store-architecture.md +0 -0
  98. {conexus-2.4.0 → conexus-2.4.2}/docs/rdr/rdr-005-chromadb-cloud-quota-enforcement.md +0 -0
  99. {conexus-2.4.0 → conexus-2.4.2}/docs/rdr/rdr-006-chunk-size-configuration.md +0 -0
  100. {conexus-2.4.0 → conexus-2.4.2}/docs/rdr/rdr-007-claude-adoption-session-context-and-search-guidance.md +0 -0
  101. {conexus-2.4.0 → conexus-2.4.2}/docs/rdr/rdr-008-nx-workflow-integration.md +0 -0
  102. {conexus-2.4.0 → conexus-2.4.2}/docs/rdr/rdr-009-remove-agentic-and-answer-flags.md +0 -0
  103. {conexus-2.4.0 → conexus-2.4.2}/docs/rdr/rdr-010-t1-scratch-persistent-bounded-store.md +0 -0
  104. {conexus-2.4.0 → conexus-2.4.2}/docs/rdr/rdr-011-pdf-ingest-test-coverage.md +0 -0
  105. {conexus-2.4.0 → conexus-2.4.2}/docs/rdr/rdr-012-pdfplumber-extraction-tier.md +0 -0
  106. {conexus-2.4.0 → conexus-2.4.2}/docs/rdr/rdr-013-remove-nx-pm-layer.md +0 -0
  107. {conexus-2.4.0 → conexus-2.4.2}/docs/rdr/rdr-014-knowledge-base-retrieval-quality.md +0 -0
  108. {conexus-2.4.0 → conexus-2.4.2}/docs/rdr/rdr-015-indexing-pipeline-rethink.md +0 -0
  109. {conexus-2.4.0 → conexus-2.4.2}/docs/rdr/rdr-016-ast-chunk-line-range-bug.md +0 -0
  110. {conexus-2.4.0 → conexus-2.4.2}/docs/rdr/rdr-017-indexing-progress-reporting.md +0 -0
  111. {conexus-2.4.0 → conexus-2.4.2}/docs/rdr/rdr-018-replace-serve-with-git-hooks.md +0 -0
  112. {conexus-2.4.0 → conexus-2.4.2}/docs/rdr/rdr-019-chromadb-transient-retry.md +0 -0
  113. {conexus-2.4.0 → conexus-2.4.2}/docs/rdr/rdr-020-voyage-chromadb-read-timeout.md +0 -0
  114. {conexus-2.4.0 → conexus-2.4.2}/docs/rdr/rdr-021-docling-pdf-extraction.md +0 -0
  115. {conexus-2.4.0 → conexus-2.4.2}/docs/rdr/rdr-022-memory-delete-command.md +0 -0
  116. {conexus-2.4.0 → conexus-2.4.2}/docs/rdr/rdr-023-agent-tool-permissions-audit.md +0 -0
  117. {conexus-2.4.0 → conexus-2.4.2}/docs/rdr/rdr-024-rdr-process-guardrails.md +0 -0
  118. {conexus-2.4.0 → conexus-2.4.2}/docs/rdr/rdr-025-language-agnostic-agents.md +0 -0
  119. {conexus-2.4.0 → conexus-2.4.2}/docs/rdr/rdr-026-hybrid-search-fusion.md +0 -0
  120. {conexus-2.4.0 → conexus-2.4.2}/docs/rdr/rdr-027-search-results-ux.md +0 -0
  121. {conexus-2.4.0 → conexus-2.4.2}/docs/rdr/rdr-028-code-search-recall.md +0 -0
  122. {conexus-2.4.0 → conexus-2.4.2}/docs/rdr/rdr-029-pipeline-versioning.md +0 -0
  123. {conexus-2.4.0 → conexus-2.4.2}/docs/rdr/rdr-030-reliability-hardening.md +0 -0
  124. {conexus-2.4.0 → conexus-2.4.2}/docs/rdr/rdr-031-collection-portability.md +0 -0
  125. {conexus-2.4.0 → conexus-2.4.2}/docs/rdr/rdr-032-indexer-decomposition.md +0 -0
  126. {conexus-2.4.0 → conexus-2.4.2}/docs/rdr/rdr-033-pdf-agent-nx-index-alignment.md +0 -0
  127. {conexus-2.4.0 → conexus-2.4.2}/docs/rdr/rdr-034-mcp-server-agent-storage.md +0 -0
  128. {conexus-2.4.0 → conexus-2.4.2}/docs/rdr/rdr-035-plugin-agent-mcp-tool-access.md +0 -0
  129. {conexus-2.4.0 → conexus-2.4.2}/docs/rdr/rdr-036-post-accept-planning-workflow.md +0 -0
  130. {conexus-2.4.0 → conexus-2.4.2}/docs/rdr/rdr-037-t3-database-consolidation.md +0 -0
  131. {conexus-2.4.0 → conexus-2.4.2}/docs/rdr/rdr-038-local-t3-backend.md +0 -0
  132. {conexus-2.4.0 → conexus-2.4.2}/docs/rdr/rdr-039-claude-code-framework-alignment.md +0 -0
  133. {conexus-2.4.0 → conexus-2.4.2}/docs/rdr/rdr-040-cce-postmortem-gaps-mcp-enhancement.md +0 -0
  134. {conexus-2.4.0 → conexus-2.4.2}/docs/rdr-nexus-integration.md +0 -0
  135. {conexus-2.4.0 → conexus-2.4.2}/docs/rdr-overview.md +0 -0
  136. {conexus-2.4.0 → conexus-2.4.2}/docs/rdr-templates.md +0 -0
  137. {conexus-2.4.0 → conexus-2.4.2}/docs/rdr-workflow.md +0 -0
  138. {conexus-2.4.0 → conexus-2.4.2}/docs/repo-indexing.md +0 -0
  139. {conexus-2.4.0 → conexus-2.4.2}/docs/storage-tiers.md +0 -0
  140. {conexus-2.4.0 → conexus-2.4.2}/nx/.mcp.json +0 -0
  141. {conexus-2.4.0 → conexus-2.4.2}/nx/README.md +0 -0
  142. {conexus-2.4.0 → conexus-2.4.2}/nx/agents/_shared/CONTEXT_PROTOCOL.md +0 -0
  143. {conexus-2.4.0 → conexus-2.4.2}/nx/agents/_shared/ERROR_HANDLING.md +0 -0
  144. {conexus-2.4.0 → conexus-2.4.2}/nx/agents/_shared/MAINTENANCE.md +0 -0
  145. {conexus-2.4.0 → conexus-2.4.2}/nx/agents/_shared/README.md +0 -0
  146. {conexus-2.4.0 → conexus-2.4.2}/nx/agents/_shared/RELAY_TEMPLATE.md +0 -0
  147. {conexus-2.4.0 → conexus-2.4.2}/nx/agents/architect-planner.md +0 -0
  148. {conexus-2.4.0 → conexus-2.4.2}/nx/agents/code-review-expert.md +0 -0
  149. {conexus-2.4.0 → conexus-2.4.2}/nx/agents/codebase-deep-analyzer.md +0 -0
  150. {conexus-2.4.0 → conexus-2.4.2}/nx/agents/debugger.md +0 -0
  151. {conexus-2.4.0 → conexus-2.4.2}/nx/agents/deep-analyst.md +0 -0
  152. {conexus-2.4.0 → conexus-2.4.2}/nx/agents/deep-research-synthesizer.md +0 -0
  153. {conexus-2.4.0 → conexus-2.4.2}/nx/agents/developer.md +0 -0
  154. {conexus-2.4.0 → conexus-2.4.2}/nx/agents/knowledge-tidier.md +0 -0
  155. {conexus-2.4.0 → conexus-2.4.2}/nx/agents/orchestrator.md +0 -0
  156. {conexus-2.4.0 → conexus-2.4.2}/nx/agents/pdf-chromadb-processor.md +0 -0
  157. {conexus-2.4.0 → conexus-2.4.2}/nx/agents/plan-auditor.md +0 -0
  158. {conexus-2.4.0 → conexus-2.4.2}/nx/agents/plan-enricher.md +0 -0
  159. {conexus-2.4.0 → conexus-2.4.2}/nx/agents/strategic-planner.md +0 -0
  160. {conexus-2.4.0 → conexus-2.4.2}/nx/agents/substantive-critic.md +0 -0
  161. {conexus-2.4.0 → conexus-2.4.2}/nx/agents/test-validator.md +0 -0
  162. {conexus-2.4.0 → conexus-2.4.2}/nx/commands/analyze-code.md +0 -0
  163. {conexus-2.4.0 → conexus-2.4.2}/nx/commands/architecture.md +0 -0
  164. {conexus-2.4.0 → conexus-2.4.2}/nx/commands/create-plan.md +0 -0
  165. {conexus-2.4.0 → conexus-2.4.2}/nx/commands/debug.md +0 -0
  166. {conexus-2.4.0 → conexus-2.4.2}/nx/commands/deep-analysis.md +0 -0
  167. {conexus-2.4.0 → conexus-2.4.2}/nx/commands/enrich-plan.md +0 -0
  168. {conexus-2.4.0 → conexus-2.4.2}/nx/commands/implement.md +0 -0
  169. {conexus-2.4.0 → conexus-2.4.2}/nx/commands/knowledge-tidy.md +0 -0
  170. {conexus-2.4.0 → conexus-2.4.2}/nx/commands/nx-preflight.md +0 -0
  171. {conexus-2.4.0 → conexus-2.4.2}/nx/commands/pdf-process.md +0 -0
  172. {conexus-2.4.0 → conexus-2.4.2}/nx/commands/plan-audit.md +0 -0
  173. {conexus-2.4.0 → conexus-2.4.2}/nx/commands/rdr-accept.md +0 -0
  174. {conexus-2.4.0 → conexus-2.4.2}/nx/commands/rdr-close.md +0 -0
  175. {conexus-2.4.0 → conexus-2.4.2}/nx/commands/rdr-create.md +0 -0
  176. {conexus-2.4.0 → conexus-2.4.2}/nx/commands/rdr-gate.md +0 -0
  177. {conexus-2.4.0 → conexus-2.4.2}/nx/commands/rdr-list.md +0 -0
  178. {conexus-2.4.0 → conexus-2.4.2}/nx/commands/rdr-research.md +0 -0
  179. {conexus-2.4.0 → conexus-2.4.2}/nx/commands/rdr-show.md +0 -0
  180. {conexus-2.4.0 → conexus-2.4.2}/nx/commands/research.md +0 -0
  181. {conexus-2.4.0 → conexus-2.4.2}/nx/commands/review-code.md +0 -0
  182. {conexus-2.4.0 → conexus-2.4.2}/nx/commands/substantive-critique.md +0 -0
  183. {conexus-2.4.0 → conexus-2.4.2}/nx/commands/test-validate.md +0 -0
  184. {conexus-2.4.0 → conexus-2.4.2}/nx/hooks/hooks.json +0 -0
  185. {conexus-2.4.0 → conexus-2.4.2}/nx/hooks/scripts/post_compact_hook.sh +0 -0
  186. {conexus-2.4.0 → conexus-2.4.2}/nx/hooks/scripts/rdr_hook.py +0 -0
  187. {conexus-2.4.0 → conexus-2.4.2}/nx/hooks/scripts/session_start_hook.py +0 -0
  188. {conexus-2.4.0 → conexus-2.4.2}/nx/hooks/scripts/stop_failure_hook.py +0 -0
  189. {conexus-2.4.0 → conexus-2.4.2}/nx/hooks/scripts/subagent-start.sh +0 -0
  190. {conexus-2.4.0 → conexus-2.4.2}/nx/hooks/scripts/t2_prefix_scan.py +0 -0
  191. {conexus-2.4.0 → conexus-2.4.2}/nx/registry.yaml +0 -0
  192. {conexus-2.4.0 → conexus-2.4.2}/nx/resources/rdr/README-TEMPLATE.md +0 -0
  193. {conexus-2.4.0 → conexus-2.4.2}/nx/resources/rdr/TEMPLATE.md +0 -0
  194. {conexus-2.4.0 → conexus-2.4.2}/nx/resources/rdr/post-mortem/TEMPLATE.md +0 -0
  195. {conexus-2.4.0 → conexus-2.4.2}/nx/skills/architecture/SKILL.md +0 -0
  196. {conexus-2.4.0 → conexus-2.4.2}/nx/skills/brainstorming-gate/SKILL.md +0 -0
  197. {conexus-2.4.0 → conexus-2.4.2}/nx/skills/cli-controller/SKILL.md +0 -0
  198. {conexus-2.4.0 → conexus-2.4.2}/nx/skills/code-review/SKILL.md +0 -0
  199. {conexus-2.4.0 → conexus-2.4.2}/nx/skills/codebase-analysis/SKILL.md +0 -0
  200. {conexus-2.4.0 → conexus-2.4.2}/nx/skills/debugging/SKILL.md +0 -0
  201. {conexus-2.4.0 → conexus-2.4.2}/nx/skills/deep-analysis/SKILL.md +0 -0
  202. {conexus-2.4.0 → conexus-2.4.2}/nx/skills/development/SKILL.md +0 -0
  203. {conexus-2.4.0 → conexus-2.4.2}/nx/skills/enrich-plan/SKILL.md +0 -0
  204. {conexus-2.4.0 → conexus-2.4.2}/nx/skills/knowledge-tidying/SKILL.md +0 -0
  205. {conexus-2.4.0 → conexus-2.4.2}/nx/skills/nexus/SKILL.md +0 -0
  206. {conexus-2.4.0 → conexus-2.4.2}/nx/skills/nexus/reference.md +0 -0
  207. {conexus-2.4.0 → conexus-2.4.2}/nx/skills/orchestration/SKILL.md +0 -0
  208. {conexus-2.4.0 → conexus-2.4.2}/nx/skills/pdf-processing/SKILL.md +0 -0
  209. {conexus-2.4.0 → conexus-2.4.2}/nx/skills/plan-validation/SKILL.md +0 -0
  210. {conexus-2.4.0 → conexus-2.4.2}/nx/skills/rdr-accept/SKILL.md +0 -0
  211. {conexus-2.4.0 → conexus-2.4.2}/nx/skills/rdr-close/SKILL.md +0 -0
  212. {conexus-2.4.0 → conexus-2.4.2}/nx/skills/rdr-create/SKILL.md +0 -0
  213. {conexus-2.4.0 → conexus-2.4.2}/nx/skills/rdr-gate/SKILL.md +0 -0
  214. {conexus-2.4.0 → conexus-2.4.2}/nx/skills/rdr-list/SKILL.md +0 -0
  215. {conexus-2.4.0 → conexus-2.4.2}/nx/skills/rdr-research/SKILL.md +0 -0
  216. {conexus-2.4.0 → conexus-2.4.2}/nx/skills/rdr-show/SKILL.md +0 -0
  217. {conexus-2.4.0 → conexus-2.4.2}/nx/skills/research-synthesis/SKILL.md +0 -0
  218. {conexus-2.4.0 → conexus-2.4.2}/nx/skills/serena-code-nav/SKILL.md +0 -0
  219. {conexus-2.4.0 → conexus-2.4.2}/nx/skills/strategic-planning/SKILL.md +0 -0
  220. {conexus-2.4.0 → conexus-2.4.2}/nx/skills/substantive-critique/SKILL.md +0 -0
  221. {conexus-2.4.0 → conexus-2.4.2}/nx/skills/test-validation/SKILL.md +0 -0
  222. {conexus-2.4.0 → conexus-2.4.2}/nx/skills/using-nx-skills/SKILL.md +0 -0
  223. {conexus-2.4.0 → conexus-2.4.2}/nx/skills/writing-nx-skills/SKILL.md +0 -0
  224. {conexus-2.4.0 → conexus-2.4.2}/src/nexus/__init__.py +0 -0
  225. {conexus-2.4.0 → conexus-2.4.2}/src/nexus/chunker.py +0 -0
  226. {conexus-2.4.0 → conexus-2.4.2}/src/nexus/classifier.py +0 -0
  227. {conexus-2.4.0 → conexus-2.4.2}/src/nexus/cli.py +0 -0
  228. {conexus-2.4.0 → conexus-2.4.2}/src/nexus/code_indexer.py +0 -0
  229. {conexus-2.4.0 → conexus-2.4.2}/src/nexus/commands/__init__.py +0 -0
  230. {conexus-2.4.0 → conexus-2.4.2}/src/nexus/commands/_helpers.py +0 -0
  231. {conexus-2.4.0 → conexus-2.4.2}/src/nexus/commands/_provision.py +0 -0
  232. {conexus-2.4.0 → conexus-2.4.2}/src/nexus/commands/collection.py +0 -0
  233. {conexus-2.4.0 → conexus-2.4.2}/src/nexus/commands/config_cmd.py +0 -0
  234. {conexus-2.4.0 → conexus-2.4.2}/src/nexus/commands/doctor.py +0 -0
  235. {conexus-2.4.0 → conexus-2.4.2}/src/nexus/commands/hook.py +0 -0
  236. {conexus-2.4.0 → conexus-2.4.2}/src/nexus/commands/hooks.py +0 -0
  237. {conexus-2.4.0 → conexus-2.4.2}/src/nexus/commands/scratch.py +0 -0
  238. {conexus-2.4.0 → conexus-2.4.2}/src/nexus/commands/search_cmd.py +0 -0
  239. {conexus-2.4.0 → conexus-2.4.2}/src/nexus/commands/store.py +0 -0
  240. {conexus-2.4.0 → conexus-2.4.2}/src/nexus/config.py +0 -0
  241. {conexus-2.4.0 → conexus-2.4.2}/src/nexus/corpus.py +0 -0
  242. {conexus-2.4.0 → conexus-2.4.2}/src/nexus/db/__init__.py +0 -0
  243. {conexus-2.4.0 → conexus-2.4.2}/src/nexus/db/chroma_quotas.py +0 -0
  244. {conexus-2.4.0 → conexus-2.4.2}/src/nexus/db/local_ef.py +0 -0
  245. {conexus-2.4.0 → conexus-2.4.2}/src/nexus/db/t1.py +0 -0
  246. {conexus-2.4.0 → conexus-2.4.2}/src/nexus/db/t2.py +0 -0
  247. {conexus-2.4.0 → conexus-2.4.2}/src/nexus/db/t3.py +0 -0
  248. {conexus-2.4.0 → conexus-2.4.2}/src/nexus/doc_indexer.py +0 -0
  249. {conexus-2.4.0 → conexus-2.4.2}/src/nexus/errors.py +0 -0
  250. {conexus-2.4.0 → conexus-2.4.2}/src/nexus/exporter.py +0 -0
  251. {conexus-2.4.0 → conexus-2.4.2}/src/nexus/formatters.py +0 -0
  252. {conexus-2.4.0 → conexus-2.4.2}/src/nexus/frecency.py +0 -0
  253. {conexus-2.4.0 → conexus-2.4.2}/src/nexus/hooks.py +0 -0
  254. {conexus-2.4.0 → conexus-2.4.2}/src/nexus/index_context.py +0 -0
  255. {conexus-2.4.0 → conexus-2.4.2}/src/nexus/indexer.py +0 -0
  256. {conexus-2.4.0 → conexus-2.4.2}/src/nexus/indexer_utils.py +0 -0
  257. {conexus-2.4.0 → conexus-2.4.2}/src/nexus/languages.py +0 -0
  258. {conexus-2.4.0 → conexus-2.4.2}/src/nexus/mcp_server.py +0 -0
  259. {conexus-2.4.0 → conexus-2.4.2}/src/nexus/md_chunker.py +0 -0
  260. {conexus-2.4.0 → conexus-2.4.2}/src/nexus/pdf_chunker.py +0 -0
  261. {conexus-2.4.0 → conexus-2.4.2}/src/nexus/pdf_extractor.py +0 -0
  262. {conexus-2.4.0 → conexus-2.4.2}/src/nexus/prose_indexer.py +0 -0
  263. {conexus-2.4.0 → conexus-2.4.2}/src/nexus/registry.py +0 -0
  264. {conexus-2.4.0 → conexus-2.4.2}/src/nexus/retry.py +0 -0
  265. {conexus-2.4.0 → conexus-2.4.2}/src/nexus/ripgrep_cache.py +0 -0
  266. {conexus-2.4.0 → conexus-2.4.2}/src/nexus/scoring.py +0 -0
  267. {conexus-2.4.0 → conexus-2.4.2}/src/nexus/search_engine.py +0 -0
  268. {conexus-2.4.0 → conexus-2.4.2}/src/nexus/session.py +0 -0
  269. {conexus-2.4.0 → conexus-2.4.2}/src/nexus/ttl.py +0 -0
  270. {conexus-2.4.0 → conexus-2.4.2}/src/nexus/types.py +0 -0
  271. {conexus-2.4.0 → conexus-2.4.2}/tests/__init__.py +0 -0
  272. {conexus-2.4.0 → conexus-2.4.2}/tests/__snapshots__/test_search_snapshot.ambr +0 -0
  273. {conexus-2.4.0 → conexus-2.4.2}/tests/conftest.py +0 -0
  274. {conexus-2.4.0 → conexus-2.4.2}/tests/e2e/auth-login.sh +0 -0
  275. {conexus-2.4.0 → conexus-2.4.2}/tests/e2e/lib.sh +0 -0
  276. {conexus-2.4.0 → conexus-2.4.2}/tests/e2e/run.sh +0 -0
  277. {conexus-2.4.0 → conexus-2.4.2}/tests/e2e/sandbox.sh +0 -0
  278. {conexus-2.4.0 → conexus-2.4.2}/tests/e2e/scenarios/00_debug_load.sh +0 -0
  279. {conexus-2.4.0 → conexus-2.4.2}/tests/e2e/scenarios/01_smoke.sh +0 -0
  280. {conexus-2.4.0 → conexus-2.4.2}/tests/e2e/scenarios/02_sequential_thinking.sh +0 -0
  281. {conexus-2.4.0 → conexus-2.4.2}/tests/e2e/scenarios/03_skills.sh +0 -0
  282. {conexus-2.4.0 → conexus-2.4.2}/tests/hooks/__init__.py +0 -0
  283. {conexus-2.4.0 → conexus-2.4.2}/tests/hooks/test_post_compact_hook.py +0 -0
  284. {conexus-2.4.0 → conexus-2.4.2}/tests/hooks/test_stop_failure_hook.py +0 -0
  285. {conexus-2.4.0 → conexus-2.4.2}/tests/test_ast_languages.py +0 -0
  286. {conexus-2.4.0 → conexus-2.4.2}/tests/test_chroma_quotas.py +0 -0
  287. {conexus-2.4.0 → conexus-2.4.2}/tests/test_chroma_retry.py +0 -0
  288. {conexus-2.4.0 → conexus-2.4.2}/tests/test_chunker.py +0 -0
  289. {conexus-2.4.0 → conexus-2.4.2}/tests/test_chunker_ast_languages.py +0 -0
  290. {conexus-2.4.0 → conexus-2.4.2}/tests/test_classifier.py +0 -0
  291. {conexus-2.4.0 → conexus-2.4.2}/tests/test_collection_cmd.py +0 -0
  292. {conexus-2.4.0 → conexus-2.4.2}/tests/test_config.py +0 -0
  293. {conexus-2.4.0 → conexus-2.4.2}/tests/test_config_cmd.py +0 -0
  294. {conexus-2.4.0 → conexus-2.4.2}/tests/test_corpus.py +0 -0
  295. {conexus-2.4.0 → conexus-2.4.2}/tests/test_doc_indexer.py +0 -0
  296. {conexus-2.4.0 → conexus-2.4.2}/tests/test_doc_indexer_hash_sync.py +0 -0
  297. {conexus-2.4.0 → conexus-2.4.2}/tests/test_doc_indexer_pagination.py +0 -0
  298. {conexus-2.4.0 → conexus-2.4.2}/tests/test_doctor_cmd.py +0 -0
  299. {conexus-2.4.0 → conexus-2.4.2}/tests/test_doctor_integrity.py +0 -0
  300. {conexus-2.4.0 → conexus-2.4.2}/tests/test_e2e.py +0 -0
  301. {conexus-2.4.0 → conexus-2.4.2}/tests/test_exporter.py +0 -0
  302. {conexus-2.4.0 → conexus-2.4.2}/tests/test_formatters.py +0 -0
  303. {conexus-2.4.0 → conexus-2.4.2}/tests/test_frecency.py +0 -0
  304. {conexus-2.4.0 → conexus-2.4.2}/tests/test_git_hooks.py +0 -0
  305. {conexus-2.4.0 → conexus-2.4.2}/tests/test_hooks.py +0 -0
  306. {conexus-2.4.0 → conexus-2.4.2}/tests/test_hybrid_boost.py +0 -0
  307. {conexus-2.4.0 → conexus-2.4.2}/tests/test_index_lock.py +0 -0
  308. {conexus-2.4.0 → conexus-2.4.2}/tests/test_index_rdr_cmd.py +0 -0
  309. {conexus-2.4.0 → conexus-2.4.2}/tests/test_index_reminder.py +0 -0
  310. {conexus-2.4.0 → conexus-2.4.2}/tests/test_indexer.py +0 -0
  311. {conexus-2.4.0 → conexus-2.4.2}/tests/test_indexer_chunk_flow.py +0 -0
  312. {conexus-2.4.0 → conexus-2.4.2}/tests/test_indexer_e2e.py +0 -0
  313. {conexus-2.4.0 → conexus-2.4.2}/tests/test_indexer_modules.py +0 -0
  314. {conexus-2.4.0 → conexus-2.4.2}/tests/test_integration.py +0 -0
  315. {conexus-2.4.0 → conexus-2.4.2}/tests/test_languages.py +0 -0
  316. {conexus-2.4.0 → conexus-2.4.2}/tests/test_local_mode.py +0 -0
  317. {conexus-2.4.0 → conexus-2.4.2}/tests/test_mcp_concurrency.py +0 -0
  318. {conexus-2.4.0 → conexus-2.4.2}/tests/test_mcp_integration.py +0 -0
  319. {conexus-2.4.0 → conexus-2.4.2}/tests/test_mcp_server.py +0 -0
  320. {conexus-2.4.0 → conexus-2.4.2}/tests/test_mcp_session.py +0 -0
  321. {conexus-2.4.0 → conexus-2.4.2}/tests/test_md_chunker.py +0 -0
  322. {conexus-2.4.0 → conexus-2.4.2}/tests/test_md_chunker_semantic_integrity.py +0 -0
  323. {conexus-2.4.0 → conexus-2.4.2}/tests/test_md_preservation.py +0 -0
  324. {conexus-2.4.0 → conexus-2.4.2}/tests/test_memory.py +0 -0
  325. {conexus-2.4.0 → conexus-2.4.2}/tests/test_minified_chunking.py +0 -0
  326. {conexus-2.4.0 → conexus-2.4.2}/tests/test_p0_regressions.py +0 -0
  327. {conexus-2.4.0 → conexus-2.4.2}/tests/test_pdf_chunker.py +0 -0
  328. {conexus-2.4.0 → conexus-2.4.2}/tests/test_pdf_chunker_integration.py +0 -0
  329. {conexus-2.4.0 → conexus-2.4.2}/tests/test_pdf_e2e.py +0 -0
  330. {conexus-2.4.0 → conexus-2.4.2}/tests/test_pdf_extractor.py +0 -0
  331. {conexus-2.4.0 → conexus-2.4.2}/tests/test_pdf_extractor_integration.py +0 -0
  332. {conexus-2.4.0 → conexus-2.4.2}/tests/test_pdf_extractor_normalization.py +0 -0
  333. {conexus-2.4.0 → conexus-2.4.2}/tests/test_pdf_normalization.py +0 -0
  334. {conexus-2.4.0 → conexus-2.4.2}/tests/test_pdf_subsystem.py +0 -0
  335. {conexus-2.4.0 → conexus-2.4.2}/tests/test_pipeline_version.py +0 -0
  336. {conexus-2.4.0 → conexus-2.4.2}/tests/test_plugin.py +0 -0
  337. {conexus-2.4.0 → conexus-2.4.2}/tests/test_plugin_install.py +0 -0
  338. {conexus-2.4.0 → conexus-2.4.2}/tests/test_plugin_structure.py +0 -0
  339. {conexus-2.4.0 → conexus-2.4.2}/tests/test_ppid_chain_hypothesis.py +0 -0
  340. {conexus-2.4.0 → conexus-2.4.2}/tests/test_provision.py +0 -0
  341. {conexus-2.4.0 → conexus-2.4.2}/tests/test_registry.py +0 -0
  342. {conexus-2.4.0 → conexus-2.4.2}/tests/test_ripgrep_cache.py +0 -0
  343. {conexus-2.4.0 → conexus-2.4.2}/tests/test_schema.py +0 -0
  344. {conexus-2.4.0 → conexus-2.4.2}/tests/test_scoring.py +0 -0
  345. {conexus-2.4.0 → conexus-2.4.2}/tests/test_scratch.py +0 -0
  346. {conexus-2.4.0 → conexus-2.4.2}/tests/test_scratch_cmd.py +0 -0
  347. {conexus-2.4.0 → conexus-2.4.2}/tests/test_search_cmd.py +0 -0
  348. {conexus-2.4.0 → conexus-2.4.2}/tests/test_search_engine.py +0 -0
  349. {conexus-2.4.0 → conexus-2.4.2}/tests/test_search_modules.py +0 -0
  350. {conexus-2.4.0 → conexus-2.4.2}/tests/test_search_snapshot.py +0 -0
  351. {conexus-2.4.0 → conexus-2.4.2}/tests/test_session.py +0 -0
  352. {conexus-2.4.0 → conexus-2.4.2}/tests/test_session_propagation_hypotheses.py +0 -0
  353. {conexus-2.4.0 → conexus-2.4.2}/tests/test_silent_error_logging.py +0 -0
  354. {conexus-2.4.0 → conexus-2.4.2}/tests/test_store_cmd.py +0 -0
  355. {conexus-2.4.0 → conexus-2.4.2}/tests/test_t1.py +0 -0
  356. {conexus-2.4.0 → conexus-2.4.2}/tests/test_t2.py +0 -0
  357. {conexus-2.4.0 → conexus-2.4.2}/tests/test_t2_prefix_scan.py +0 -0
  358. {conexus-2.4.0 → conexus-2.4.2}/tests/test_t3.py +0 -0
  359. {conexus-2.4.0 → conexus-2.4.2}/tests/test_t3_quota_enforcement.py +0 -0
  360. {conexus-2.4.0 → conexus-2.4.2}/tests/test_ttl.py +0 -0
  361. {conexus-2.4.0 → conexus-2.4.2}/tests/test_tuning_config.py +0 -0
  362. {conexus-2.4.0 → conexus-2.4.2}/tests/test_types_and_errors.py +0 -0
  363. {conexus-2.4.0 → conexus-2.4.2}/tests/test_voyage_retry.py +0 -0
@@ -9,7 +9,7 @@
9
9
  "name": "nx",
10
10
  "source": "./nx",
11
11
  "description": "Self-hosted three-tier knowledge management with 15 specialized agents, semantic search, and RDR decision tracking for Claude Code.",
12
- "version": "2.4.0"
12
+ "version": "2.4.2"
13
13
  }
14
14
  ]
15
15
  }
@@ -6,6 +6,22 @@ Versioning follows [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
6
6
 
7
7
  ## [Unreleased]
8
8
 
9
+ ## [2.4.2] - 2026-03-25
10
+
11
+ ### Docs
12
+ - **Python 3.14 troubleshooting** — `uv tool update` reuses the existing
13
+ environment's Python, so upgrading under 3.14 doesn't auto-switch to 3.13
14
+ despite the `requires-python` cap. Documented `--force --python 3.13` as
15
+ the fix. Added `head -1 $(which nx)` diagnostic.
16
+
17
+ ## [2.4.1] - 2026-03-24
18
+
19
+ ### Fixed
20
+ - **`--collection` flag bypass of `t3_collection_name()`** — `nx index pdf --collection knowledge` now correctly normalizes to `knowledge__knowledge`, matching search conventions. Previously created bare collections invisible to `nx search` with wrong embedding model.
21
+ - **`memory promote --collection` same bug** — bare collection names in `nx memory promote` now normalized via `t3_collection_name()`.
22
+ - **Updated `--collection` help text** — no longer says "Fully-qualified" since bare names are now accepted and auto-normalized.
23
+ - **Updated CCE post-mortem** — linked RDR-040 resolution and documented the `--collection` naming variant.
24
+
9
25
  ## [2.4.0] - 2026-03-24
10
26
 
11
27
  ### Added
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: conexus
3
- Version: 2.4.0
3
+ Version: 2.4.2
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
@@ -143,7 +143,14 @@ To force local mode even when cloud credentials exist: `NX_LOCAL=1`.
143
143
 
144
144
  **`nx` command not found** — Make sure `~/.local/bin` is on your PATH. Run `uv tool install conexus` again and check the output for the install location.
145
145
 
146
- **Crash on startup (Python 3.14)** — Nexus requires Python 3.12–3.13. If `python3 --version` shows 3.14, install 3.13: `uv python install 3.13`, then reinstall: `uv tool install conexus --force`.
146
+ **Crash on startup (Python 3.14)** — Nexus requires Python 3.12–3.13. Check your nx install's Python with: `head -1 $(which nx)`. If it shows `python3.14`, the tool was installed under the wrong Python. Fix:
147
+
148
+ ```bash
149
+ uv python install 3.13
150
+ uv tool install conexus --force --python 3.13
151
+ ```
152
+
153
+ Note: `uv tool update` reuses the existing environment's Python — it won't switch from 3.14 to 3.13 automatically. You must use `--force --python 3.13` to rebuild the environment.
147
154
 
148
155
  **`nx doctor` reports credentials not set** — Expected for local mode. Only needed if you want cloud embeddings — run `nx config init`.
149
156
 
@@ -151,7 +158,7 @@ To force local mode even when cloud credentials exist: `NX_LOCAL=1`.
151
158
 
152
159
  **`nx index repo .` fails with "credentials not set"** — In cloud mode, indexing requires T3 credentials. Run `nx config init` first, or use local mode (no credentials needed).
153
160
 
154
- **`import voyageai` error** — Reinstall: `uv tool install conexus --force`. If on Python 3.14, downgrade to 3.13: `uv python install 3.13` then reinstall.
161
+ **`import voyageai` or Pydantic v1 error** — The tool is running under Python 3.14. Fix: `uv tool install conexus --force --python 3.13` (install 3.13 first with `uv python install 3.13` if needed).
155
162
 
156
163
  **First index is slow or hits a rate limit** — Large repos may take a few minutes. Add `--monitor` for per-file progress. Re-running is safe — unchanged files are skipped.
157
164
 
@@ -0,0 +1,142 @@
1
+ # Postmortem: nx index pdf fix not applied in v2.4.0
2
+
3
+ **Date**: 2026-03-24
4
+ **Severity**: High — believed-fixed bug still present in installed version
5
+ **Related**: [2026-03-23 original postmortem](2026-03-23-pdf-index-collection-mismatch.md)
6
+ **Impact**: Round-trip test after "fix" confirmed the bug persists in nx 2.4.0
7
+
8
+ ## Summary
9
+
10
+ After the 2026-03-23 incident (10,036 chunks indexed to wrong collection with wrong embedding model), a fix was reported as applied to the nx codebase. However, a round-trip verification test on 2026-03-24 confirmed the fix is **NOT present** in the installed `nx` version 2.4.0. The bug remains: `nx index pdf --collection knowledge` still creates a bare `"knowledge"` collection with `voyage-4` embeddings instead of `"knowledge__knowledge"` with `voyage-context-3`.
11
+
12
+ ## Reproduction Steps
13
+
14
+ ### Prerequisites
15
+ - nx version 2.4.0 installed (`nx --version`)
16
+ - Chroma Cloud configured (`~/.config/nexus/config.yml` has `chroma_api_key`)
17
+ - A test PDF file (any small PDF will do)
18
+
19
+ ### Step 1: Confirm baseline state
20
+ ```bash
21
+ # Check current knowledge collection
22
+ nx collection info knowledge__knowledge
23
+ # Expected: Documents: N, Index model: voyage-context-3
24
+ ```
25
+
26
+ ### Step 2: Index a test PDF
27
+ ```bash
28
+ nx index pdf /path/to/test.pdf --collection knowledge
29
+ # Output: "Indexed N chunk(s)." — appears successful
30
+ ```
31
+
32
+ ### Step 3: Check if chunks landed in the right collection
33
+ ```bash
34
+ nx collection info knowledge__knowledge
35
+ # EXPECTED (if fixed): Documents: N + chunks
36
+ # ACTUAL (bug): Documents: N (unchanged — chunks went elsewhere)
37
+ ```
38
+
39
+ ### Step 4: Check where chunks actually went
40
+ ```bash
41
+ nx collection info knowledge
42
+ # ACTUAL: Documents: chunks, Index model: voyage-4
43
+ # This bare "knowledge" collection should NOT exist
44
+ ```
45
+
46
+ ### Step 5: Verify search cannot find indexed content
47
+ ```bash
48
+ # Search for distinctive text from the indexed PDF
49
+ nx search "some unique phrase from the PDF" --corpus knowledge
50
+ # ACTUAL: Returns only pre-existing manual T3 entries, NOT the PDF chunks
51
+ ```
52
+
53
+ ## Root Cause (unchanged from original postmortem)
54
+
55
+ In `nexus/commands/index.py`, the `index_pdf_cmd` function passes the `--collection` argument directly to `doc_indexer.index_pdf()` without calling `t3_collection_name()`:
56
+
57
+ ```python
58
+ # Line ~249 in commands/index.py (v2.4.0)
59
+ n = index_pdf(path, corpus=corpus, collection_name=collection, force=force)
60
+ ```
61
+
62
+ The `collection` variable is the raw user input `"knowledge"`. It should be transformed via:
63
+
64
+ ```python
65
+ from nexus.corpus import t3_collection_name
66
+ collection = t3_collection_name(collection) # "knowledge" → "knowledge__knowledge"
67
+ ```
68
+
69
+ This same transformation is performed by `store put` (via `commands/store.py`) and `search` (via `corpus.py:resolve_corpus()`), but NOT by `index pdf`.
70
+
71
+ ## Two Bugs From One Missing Call
72
+
73
+ ### Bug 1: Wrong collection name
74
+ - `"knowledge"` is created instead of `"knowledge__knowledge"`
75
+ - `nx search --corpus knowledge` resolves to `knowledge__*` prefix → finds `knowledge__knowledge` → never sees bare `knowledge`
76
+
77
+ ### Bug 2: Wrong embedding model
78
+ - `index_model_for_collection("knowledge")` returns `voyage-4` (default for unknown prefixes)
79
+ - `index_model_for_collection("knowledge__knowledge")` returns `voyage-context-3` (correct for `knowledge__*`)
80
+ - Chunks embedded with `voyage-4` cannot be meaningfully searched with `voyage-context-3` queries
81
+
82
+ ## Required Fix
83
+
84
+ In `nexus/commands/index.py`, function `index_pdf_cmd`, add before any use of `collection`:
85
+
86
+ ```python
87
+ if collection is not None:
88
+ from nexus.corpus import t3_collection_name
89
+ collection = t3_collection_name(collection)
90
+ ```
91
+
92
+ This must be applied in THREE code paths within `index_pdf_cmd`:
93
+ 1. Line ~197 (dry-run path): `index_pdf(path, corpus=corpus, t3=local_t3, collection_name=collection, ...)`
94
+ 2. Line ~235 (monitor path): `index_pdf(path, corpus=corpus, collection_name=collection, force=force, ...)`
95
+ 3. Line ~249 (normal path): `index_pdf(path, corpus=corpus, collection_name=collection, force=force)`
96
+
97
+ The simplest fix: add the transformation immediately after `path = path.resolve()` (line 181), before any branch:
98
+
99
+ ```python
100
+ path = path.resolve()
101
+
102
+ # Normalize collection name to T3 convention (e.g. "knowledge" → "knowledge__knowledge")
103
+ if collection is not None:
104
+ from nexus.corpus import t3_collection_name
105
+ collection = t3_collection_name(collection)
106
+ ```
107
+
108
+ Similarly check `index md` command (line ~254+) for the same bug.
109
+
110
+ ## Verification After Fix
111
+
112
+ After applying the fix, re-run the reproduction steps above. Expected results:
113
+
114
+ 1. `nx index pdf test.pdf --collection knowledge` should report "Indexed N chunk(s)."
115
+ 2. `nx collection info knowledge__knowledge` should show increased document count
116
+ 3. `nx collection info knowledge` should return "not found" or 0 documents
117
+ 4. `nx search "phrase from PDF" --corpus knowledge` should return the indexed chunks
118
+ 5. The returned chunks should show `embedding_model: voyage-context-3`
119
+
120
+ ## Cleanup Required
121
+
122
+ After confirming the fix works:
123
+
124
+ 1. Delete the orphaned bare `"knowledge"` collection (18 chunks from failed test):
125
+ ```python
126
+ from nexus.db import make_t3
127
+ t3 = make_t3()
128
+ t3.delete_collection('knowledge')
129
+ ```
130
+
131
+ 2. Re-index all ART papers (~68 PDFs + CMRB 771 pages) with `--collection knowledge`
132
+
133
+ 3. Verify round-trip search for each major paper
134
+
135
+ ## Workaround (Until Fix Is Applied)
136
+
137
+ Use the fully-qualified collection name:
138
+ ```bash
139
+ nx index pdf /path/to/paper.pdf --collection knowledge__knowledge
140
+ ```
141
+
142
+ This bypasses `t3_collection_name()` entirely (the `__` check in the function returns the input as-is). Both the collection name and embedding model will be correct.
@@ -140,28 +140,50 @@ correct; they were mixed with noise from the other corpora.
140
140
 
141
141
  ---
142
142
 
143
- ## Fix (Pending)
143
+ ## Fix (Resolved)
144
144
 
145
- Two coordinated changes to `src/nexus/`:
145
+ The original CCE query path fix was deployed in PR #33. RDR-040 (v2.4.0, PR #118)
146
+ then closed the systemic gaps that allowed the bug to ship undetected:
146
147
 
147
- **`corpus.py`** `embedding_model_for_collection()` returns `"voyage-context-3"`
148
- for `docs__`, `knowledge__`, and `rdr__` collections. `index_model_for_collection()`
149
- likewise corrected for the same three prefixes.
148
+ **Original fix (PR #33):**
150
149
 
151
- **`db/t3.py`**Two changes:
150
+ - `corpus.py``embedding_model_for_collection()` returns `"voyage-context-3"` for CCE collections
151
+ - `db/t3.py` — `search()` and `put()` bypass VoyageAIEmbeddingFunction, call `contextualized_embed()` directly
152
152
 
153
- 1. `T3Database.search()` detects CCE collections by checking
154
- `index_model_for_collection()` and bypasses `VoyageAIEmbeddingFunction`, calling
155
- `vo.contextualized_embed([[query]], model="voyage-context-3", input_type="query")`
156
- directly before calling `col.query(query_embeddings=[...])`.
153
+ **RDR-040 gap closure (PR #118, v2.4.0):**
157
154
 
158
- 2. `T3Database.put()` also bypasses the voyage-4 EF for CCE collections when
159
- `voyage_api_key` is set, calling `_cce_embed(content)` and passing
160
- `embeddings=[vec]` to `col.upsert()`. This ensures single-entry knowledge
161
- entries stored via `nx store put` are in the same CCE vector space as
162
- multi-chunk doc_indexer entries and are findable by search.
155
+ - **C1**: Single-chunk CCE documents now use `contextualized_embed()` the `len(chunks) < 2` fallback to voyage-4 was a recurrence of this exact bug class
156
+ - **C4**: Partial CCE batch failure re-embeds entire document consistently — prevents mixed-model vectors
157
+ - **C2/C3**: Paginated all unbounded `col.get()` calls (ChromaDB 300-record hard cap)
158
+ - **C5**: MCP collection cache race eliminated
159
+ - **A1**: Retrieval quality tests assert semantic rank ordering, not just row count
160
+ - **A2**: `verify --deep` uses known-document probe with distance reporting
161
+ - **A3**: Cross-model invariant regression test — fails if CCE index/query models diverge
162
+ - **A4**: `nx collection reindex` command for recovery
163
+ - **B1–B4**: MCP server enhanced with multi-corpus search + collection management tools
163
164
 
164
- All CCE-indexed collections will need re-indexing after the fix is deployed, as the
165
- existing embeddings are correct — only the query path needs repair.
165
+ ## Additional Bug Discovered During Validation
166
166
 
167
- See fix PR (pending).
167
+ A round-trip test of the v2.4.0 release reproduced the *collection naming* variant of
168
+ this failure:
169
+
170
+ `nx index pdf --collection knowledge` passed the bare name `"knowledge"` directly to
171
+ ChromaDB (bypassing `t3_collection_name()`), creating a collection that `nx search`
172
+ could not find (search uses `resolve_corpus()` which matches `knowledge__*`). Worse,
173
+ `index_model_for_collection("knowledge")` returns `voyage-4` (not CCE), so all chunks
174
+ were embedded with the wrong model — the same cascading failure as the original bug.
175
+
176
+ **Fix**: PR #119 normalizes `--collection` through `t3_collection_name()` so bare names
177
+ like `"knowledge"` become `"knowledge__knowledge"`.
178
+
179
+ **Cascading failure chain** (identical pattern to the original):
180
+ ```
181
+ --collection knowledge (user input)
182
+ → Missing t3_collection_name() call
183
+ → Collection "knowledge" created (wrong name)
184
+ → index_model_for_collection("knowledge") = voyage-4 (wrong model)
185
+ → Chunks embedded with voyage-4 (wrong space)
186
+ → Chunks invisible to search (wrong collection name)
187
+ ```
188
+
189
+ See: `docs/postmortem/2026-03-23-pdf-index-collection-mismatch.md`
@@ -6,6 +6,14 @@ Versioning follows [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
6
6
 
7
7
  ## [Unreleased]
8
8
 
9
+ ## [2.4.2] - 2026-03-25
10
+
11
+ Plugin version aligned with Nexus CLI 2.4.2. No plugin-level functional changes.
12
+
13
+ ## [2.4.1] - 2026-03-24
14
+
15
+ Plugin version aligned with Nexus CLI 2.4.1. No plugin-level functional changes.
16
+
9
17
  ## [2.4.0] - 2026-03-24
10
18
 
11
19
  ### Bug Fixes (Track C)
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "conexus"
7
- version = "2.4.0"
7
+ version = "2.4.2"
8
8
  description = "Self-hosted semantic search and knowledge management for LLM-driven development"
9
9
  readme = { file = "README.md", content-type = "text/markdown" }
10
10
  requires-python = ">=3.12,<3.14"
@@ -150,7 +150,8 @@ def index_repo_cmd(path: Path, frecency_only: bool, force: bool, monitor: bool,
150
150
  "--collection",
151
151
  default=None,
152
152
  help=(
153
- "Fully-qualified T3 collection name (e.g. knowledge__delos). "
153
+ "T3 collection name. Bare names (e.g. 'knowledge') are auto-normalized "
154
+ "to knowledge__<name>; qualified names (e.g. knowledge__delos) pass through. "
154
155
  "Overrides --corpus when set."
155
156
  ),
156
157
  )
@@ -173,11 +174,18 @@ def index_repo_cmd(path: Path, frecency_only: bool, force: bool, monitor: bool,
173
174
  help="Print chunking metadata after indexing. Auto-enabled when stdout is not a TTY.")
174
175
  def index_pdf_cmd(path: Path, corpus: str, collection: str | None, dry_run: bool, force: bool, monitor: bool) -> None:
175
176
  """Extract and index a PDF document into T3 docs__CORPUS (or --collection)."""
177
+ from nexus.corpus import t3_collection_name
176
178
  from nexus.doc_indexer import index_pdf
177
179
 
178
180
  if force and dry_run:
179
181
  raise click.UsageError("--force and --dry-run are mutually exclusive.")
180
182
 
183
+ # Normalize --collection through t3_collection_name() so bare names like
184
+ # "knowledge" become "knowledge__knowledge", matching search conventions.
185
+ # Without this, chunks end up in unsearchable bare collections.
186
+ if collection is not None:
187
+ collection = t3_collection_name(collection)
188
+
181
189
  path = path.resolve()
182
190
 
183
191
  if dry_run:
@@ -152,11 +152,15 @@ def expire_cmd() -> None:
152
152
 
153
153
  @memory.command("promote")
154
154
  @click.argument("entry_id", metavar="ID", type=int)
155
- @click.option("--collection", required=True, help="Target T3 collection name (e.g. knowledge__myproject)")
155
+ @click.option("--collection", required=True, help="T3 collection name (e.g. 'knowledge' or 'knowledge__myproject')")
156
156
  @click.option("--tags", default="", help="Comma-separated tags (overrides T2 tags when provided)")
157
157
  @click.option("--remove", is_flag=True, default=False, help="Delete the entry from T2 after promoting.")
158
158
  def promote_cmd(entry_id: int, collection: str, tags: str, remove: bool) -> None:
159
159
  """Promote a T2 memory entry to T3 ChromaDB permanent storage."""
160
+ from nexus.corpus import t3_collection_name
161
+
162
+ collection = t3_collection_name(collection)
163
+
160
164
  with T2Database(_default_db_path()) as db:
161
165
  entry = db.get(id=entry_id)
162
166
  if entry is None:
@@ -468,3 +468,51 @@ def test_md_monitor_return_metadata(runner: CliRunner, index_home: Path) -> None
468
468
  assert kwargs.get("return_metadata") is True
469
469
  assert "Chunks: 2" in result.output
470
470
  assert "Sections: 1" in result.output
471
+
472
+
473
+ # ── --collection flag normalization ───────────────────────────────────────────
474
+
475
+ def test_pdf_collection_flag_normalized_via_t3_collection_name(
476
+ runner: CliRunner, index_home: Path
477
+ ) -> None:
478
+ """--collection knowledge becomes knowledge__knowledge via t3_collection_name().
479
+
480
+ Regression guard: bare collection names like "knowledge" must be normalized
481
+ to "knowledge__knowledge" so search (which uses resolve_corpus with __
482
+ prefix matching) can find the indexed chunks.
483
+ See postmortem: docs/postmortem/2026-03-23-pdf-index-collection-mismatch.md
484
+ """
485
+ pdf = index_home / "doc.pdf"
486
+ pdf.write_bytes(b"fake pdf")
487
+
488
+ # Return a dict (monitor path) since CliRunner stdout is non-TTY
489
+ mock_result = {"chunks": 5, "pages": [1], "title": "T", "author": "A"}
490
+ with patch("nexus.doc_indexer.index_pdf", return_value=mock_result) as mock_index:
491
+ result = runner.invoke(
492
+ main, ["index", "pdf", str(pdf), "--collection", "knowledge"]
493
+ )
494
+
495
+ assert result.exit_code == 0, result.output
496
+ _, kwargs = mock_index.call_args
497
+ # Must be normalized: "knowledge" → "knowledge__knowledge"
498
+ assert kwargs["collection_name"] == "knowledge__knowledge", (
499
+ f"--collection flag not normalized: got {kwargs['collection_name']!r}"
500
+ )
501
+
502
+
503
+ def test_pdf_collection_flag_already_qualified_unchanged(
504
+ runner: CliRunner, index_home: Path
505
+ ) -> None:
506
+ """--collection knowledge__delos passes through unchanged."""
507
+ pdf = index_home / "doc.pdf"
508
+ pdf.write_bytes(b"fake pdf")
509
+
510
+ mock_result = {"chunks": 3, "pages": [1], "title": "T", "author": "A"}
511
+ with patch("nexus.doc_indexer.index_pdf", return_value=mock_result) as mock_index:
512
+ result = runner.invoke(
513
+ main, ["index", "pdf", str(pdf), "--collection", "knowledge__delos"]
514
+ )
515
+
516
+ assert result.exit_code == 0, result.output
517
+ _, kwargs = mock_index.call_args
518
+ assert kwargs["collection_name"] == "knowledge__delos"
@@ -403,7 +403,7 @@ wheels = [
403
403
 
404
404
  [[package]]
405
405
  name = "conexus"
406
- version = "2.4.0"
406
+ version = "2.4.2"
407
407
  source = { editable = "." }
408
408
  dependencies = [
409
409
  { name = "chromadb" },
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes