conexus 2.3.1__tar.gz → 2.3.3__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 (360) hide show
  1. {conexus-2.3.1 → conexus-2.3.3}/.claude-plugin/marketplace.json +1 -1
  2. {conexus-2.3.1 → conexus-2.3.3}/CHANGELOG.md +27 -0
  3. {conexus-2.3.1 → conexus-2.3.3}/PKG-INFO +1 -1
  4. {conexus-2.3.1 → conexus-2.3.3}/nx/CHANGELOG.md +19 -0
  5. {conexus-2.3.1 → conexus-2.3.3}/nx/agents/plan-enricher.md +9 -6
  6. conexus-2.3.3/nx/commands/rdr-accept.md +262 -0
  7. {conexus-2.3.1 → conexus-2.3.3}/nx/skills/enrich-plan/SKILL.md +1 -1
  8. {conexus-2.3.1 → conexus-2.3.3}/nx/skills/writing-nx-skills/SKILL.md +17 -0
  9. {conexus-2.3.1 → conexus-2.3.3}/pyproject.toml +1 -1
  10. {conexus-2.3.1 → conexus-2.3.3}/src/nexus/db/t3.py +11 -1
  11. {conexus-2.3.1 → conexus-2.3.3}/tests/hooks/test_stop_failure_hook.py +1 -0
  12. {conexus-2.3.1 → conexus-2.3.3}/uv.lock +1 -1
  13. conexus-2.3.1/nx/commands/rdr-accept.md +0 -244
  14. {conexus-2.3.1 → conexus-2.3.3}/.beads/.gitignore +0 -0
  15. {conexus-2.3.1 → conexus-2.3.3}/.beads/README.md +0 -0
  16. {conexus-2.3.1 → conexus-2.3.3}/.beads/config.yaml +0 -0
  17. {conexus-2.3.1 → conexus-2.3.3}/.beads/hooks/post-checkout +0 -0
  18. {conexus-2.3.1 → conexus-2.3.3}/.beads/hooks/post-merge +0 -0
  19. {conexus-2.3.1 → conexus-2.3.3}/.beads/hooks/pre-commit +0 -0
  20. {conexus-2.3.1 → conexus-2.3.3}/.beads/hooks/pre-push +0 -0
  21. {conexus-2.3.1 → conexus-2.3.3}/.beads/hooks/prepare-commit-msg +0 -0
  22. {conexus-2.3.1 → conexus-2.3.3}/.beads/interactions.jsonl +0 -0
  23. {conexus-2.3.1 → conexus-2.3.3}/.beads/issues.jsonl +0 -0
  24. {conexus-2.3.1 → conexus-2.3.3}/.beads/metadata.json +0 -0
  25. {conexus-2.3.1 → conexus-2.3.3}/.claude/skills/release.md +0 -0
  26. {conexus-2.3.1 → conexus-2.3.3}/.devcontainer/Dockerfile +0 -0
  27. {conexus-2.3.1 → conexus-2.3.3}/.devcontainer/devcontainer.json +0 -0
  28. {conexus-2.3.1 → conexus-2.3.3}/.dockerignore +0 -0
  29. {conexus-2.3.1 → conexus-2.3.3}/.env.example +0 -0
  30. {conexus-2.3.1 → conexus-2.3.3}/.gitattributes +0 -0
  31. {conexus-2.3.1 → conexus-2.3.3}/.github/workflows/ci.yml +0 -0
  32. {conexus-2.3.1 → conexus-2.3.3}/.github/workflows/release.yml +0 -0
  33. {conexus-2.3.1 → conexus-2.3.3}/.gitignore +0 -0
  34. {conexus-2.3.1 → conexus-2.3.3}/.markdownlint.json +0 -0
  35. {conexus-2.3.1 → conexus-2.3.3}/AGENTS.md +0 -0
  36. {conexus-2.3.1 → conexus-2.3.3}/CLAUDE.md +0 -0
  37. {conexus-2.3.1 → conexus-2.3.3}/Formula/nx.rb +0 -0
  38. {conexus-2.3.1 → conexus-2.3.3}/LICENSE +0 -0
  39. {conexus-2.3.1 → conexus-2.3.3}/README.md +0 -0
  40. {conexus-2.3.1 → conexus-2.3.3}/docs/README.md +0 -0
  41. {conexus-2.3.1 → conexus-2.3.3}/docs/architecture.md +0 -0
  42. {conexus-2.3.1 → conexus-2.3.3}/docs/cli-reference.md +0 -0
  43. {conexus-2.3.1 → conexus-2.3.3}/docs/configuration.md +0 -0
  44. {conexus-2.3.1 → conexus-2.3.3}/docs/contributing.md +0 -0
  45. {conexus-2.3.1 → conexus-2.3.3}/docs/getting-started.md +0 -0
  46. {conexus-2.3.1 → conexus-2.3.3}/docs/historical/README.md +0 -0
  47. {conexus-2.3.1 → conexus-2.3.3}/docs/historical/architecture.md +0 -0
  48. {conexus-2.3.1 → conexus-2.3.3}/docs/historical/plans/2026-02-23-rdr-workflow-skills-design.md +0 -0
  49. {conexus-2.3.1 → conexus-2.3.3}/docs/historical/plans/2026-02-23-rdr-workflow-skills-impl-plan.md +0 -0
  50. {conexus-2.3.1 → conexus-2.3.3}/docs/historical/plans/2026-02-24-nx-plugin-v0.4.0.md +0 -0
  51. {conexus-2.3.1 → conexus-2.3.3}/docs/historical/plans/2026-02-24-smart-repo-indexing-design.md +0 -0
  52. {conexus-2.3.1 → conexus-2.3.3}/docs/historical/plans/2026-02-24-smart-repo-indexing-impl-plan.md +0 -0
  53. {conexus-2.3.1 → conexus-2.3.3}/docs/historical/spec.md +0 -0
  54. {conexus-2.3.1 → conexus-2.3.3}/docs/memory-and-tasks.md +0 -0
  55. {conexus-2.3.1 → conexus-2.3.3}/docs/plans/2026-02-28-rdr-004-four-store-cloud-design.md +0 -0
  56. {conexus-2.3.1 → conexus-2.3.3}/docs/plans/2026-02-28-rdr-004-four-store-cloud-impl-plan.md +0 -0
  57. {conexus-2.3.1 → conexus-2.3.3}/docs/plans/2026-03-01-dry-run-pdf-design.md +0 -0
  58. {conexus-2.3.1 → conexus-2.3.3}/docs/plans/2026-03-01-dry-run-pdf-impl-plan.md +0 -0
  59. {conexus-2.3.1 → conexus-2.3.3}/docs/plans/2026-03-01-pdfplumber-tier-design.md +0 -0
  60. {conexus-2.3.1 → conexus-2.3.3}/docs/plans/2026-03-01-rc10-1.0.0-readiness-design.md +0 -0
  61. {conexus-2.3.1 → conexus-2.3.3}/docs/plans/2026-03-01-rc10-critique-findings.md +0 -0
  62. {conexus-2.3.1 → conexus-2.3.3}/docs/plans/2026-03-02-classifier-skip-design.md +0 -0
  63. {conexus-2.3.1 → conexus-2.3.3}/docs/plans/2026-03-03-chunk-byte-cap-design.md +0 -0
  64. {conexus-2.3.1 → conexus-2.3.3}/docs/plans/2026-03-03-chunk-byte-cap-impl-plan.md +0 -0
  65. {conexus-2.3.1 → conexus-2.3.3}/docs/plans/2026-03-03-force-reindex-impl-plan.md +0 -0
  66. {conexus-2.3.1 → conexus-2.3.3}/docs/plans/2026-03-03-rdr017-phase2-cli-monitor-design.md +0 -0
  67. {conexus-2.3.1 → conexus-2.3.3}/docs/plans/2026-03-03-rdr017-phase2-cli-monitor-impl-plan.md +0 -0
  68. {conexus-2.3.1 → conexus-2.3.3}/docs/plans/2026-03-03-rdr018-git-hooks-impl-plan.md +0 -0
  69. {conexus-2.3.1 → conexus-2.3.3}/docs/plans/2026-03-04-doc-ux-polish-design.md +0 -0
  70. {conexus-2.3.1 → conexus-2.3.3}/docs/plans/2026-03-04-rdr-doc-polish-design.md +0 -0
  71. {conexus-2.3.1 → conexus-2.3.3}/docs/plans/2026-03-07-rdr-023-agent-tool-permissions-design.md +0 -0
  72. {conexus-2.3.1 → conexus-2.3.3}/docs/plans/2026-03-07-rdr-023-agent-tool-permissions-impl-plan.md +0 -0
  73. {conexus-2.3.1 → conexus-2.3.3}/docs/plans/2026-03-08-rdr-025-language-agnostic-agents-impl-plan.md +0 -0
  74. {conexus-2.3.1 → conexus-2.3.3}/docs/plans/2026-03-09-rdr-027-search-ux-impl-plan.md +0 -0
  75. {conexus-2.3.1 → conexus-2.3.3}/docs/plans/2026-03-09-rdr-028-language-registry-impl-plan.md +0 -0
  76. {conexus-2.3.1 → conexus-2.3.3}/docs/plans/2026-03-09-rdr-029-pipeline-versioning-impl-plan.md +0 -0
  77. {conexus-2.3.1 → conexus-2.3.3}/docs/plans/2026-03-09-rdr-030-reliability-hardening-impl-plan.md +0 -0
  78. {conexus-2.3.1 → conexus-2.3.3}/docs/plans/2026-03-11-rdr-034-mcp-server-impl-plan.md +0 -0
  79. {conexus-2.3.1 → conexus-2.3.3}/docs/plans/2026-03-21-rdr039-phase2-hooks-impl-plan.md +0 -0
  80. {conexus-2.3.1 → conexus-2.3.3}/docs/rdr/README.md +0 -0
  81. {conexus-2.3.1 → conexus-2.3.3}/docs/rdr/post-mortem/001-rdr-process-validation.md +0 -0
  82. {conexus-2.3.1 → conexus-2.3.3}/docs/rdr/post-mortem/002-t2-status-synchronization.md +0 -0
  83. {conexus-2.3.1 → conexus-2.3.3}/docs/rdr/post-mortem/010-t1-http-server.md +0 -0
  84. {conexus-2.3.1 → conexus-2.3.3}/docs/rdr/post-mortem/011-pdf-ingest-test-coverage.md +0 -0
  85. {conexus-2.3.1 → conexus-2.3.3}/docs/rdr/post-mortem/012-pdfplumber-extraction-tier.md +0 -0
  86. {conexus-2.3.1 → conexus-2.3.3}/docs/rdr/post-mortem/014-knowledge-base-retrieval-quality.md +0 -0
  87. {conexus-2.3.1 → conexus-2.3.3}/docs/rdr/post-mortem/015-indexing-pipeline-rethink.md +0 -0
  88. {conexus-2.3.1 → conexus-2.3.3}/docs/rdr/post-mortem/016-ast-chunk-line-range-bug.md +0 -0
  89. {conexus-2.3.1 → conexus-2.3.3}/docs/rdr/post-mortem/017-indexing-progress-reporting.md +0 -0
  90. {conexus-2.3.1 → conexus-2.3.3}/docs/rdr/post-mortem/018-replace-serve-with-git-hooks.md +0 -0
  91. {conexus-2.3.1 → conexus-2.3.3}/docs/rdr/post-mortem/023-agent-tool-permissions-audit.md +0 -0
  92. {conexus-2.3.1 → conexus-2.3.3}/docs/rdr/post-mortem/024-rdr-process-guardrails.md +0 -0
  93. {conexus-2.3.1 → conexus-2.3.3}/docs/rdr/post-mortem/028-language-registry-unification.md +0 -0
  94. {conexus-2.3.1 → conexus-2.3.3}/docs/rdr/post-mortem/029-pipeline-versioning.md +0 -0
  95. {conexus-2.3.1 → conexus-2.3.3}/docs/rdr/post-mortem/cce-query-model-mismatch.md +0 -0
  96. {conexus-2.3.1 → conexus-2.3.3}/docs/rdr/rdr-001-rdr-process-validation.md +0 -0
  97. {conexus-2.3.1 → conexus-2.3.3}/docs/rdr/rdr-002-t2-status-synchronization.md +0 -0
  98. {conexus-2.3.1 → conexus-2.3.3}/docs/rdr/rdr-004-four-store-architecture.md +0 -0
  99. {conexus-2.3.1 → conexus-2.3.3}/docs/rdr/rdr-005-chromadb-cloud-quota-enforcement.md +0 -0
  100. {conexus-2.3.1 → conexus-2.3.3}/docs/rdr/rdr-006-chunk-size-configuration.md +0 -0
  101. {conexus-2.3.1 → conexus-2.3.3}/docs/rdr/rdr-007-claude-adoption-session-context-and-search-guidance.md +0 -0
  102. {conexus-2.3.1 → conexus-2.3.3}/docs/rdr/rdr-008-nx-workflow-integration.md +0 -0
  103. {conexus-2.3.1 → conexus-2.3.3}/docs/rdr/rdr-009-remove-agentic-and-answer-flags.md +0 -0
  104. {conexus-2.3.1 → conexus-2.3.3}/docs/rdr/rdr-010-t1-scratch-persistent-bounded-store.md +0 -0
  105. {conexus-2.3.1 → conexus-2.3.3}/docs/rdr/rdr-011-pdf-ingest-test-coverage.md +0 -0
  106. {conexus-2.3.1 → conexus-2.3.3}/docs/rdr/rdr-012-pdfplumber-extraction-tier.md +0 -0
  107. {conexus-2.3.1 → conexus-2.3.3}/docs/rdr/rdr-013-remove-nx-pm-layer.md +0 -0
  108. {conexus-2.3.1 → conexus-2.3.3}/docs/rdr/rdr-014-knowledge-base-retrieval-quality.md +0 -0
  109. {conexus-2.3.1 → conexus-2.3.3}/docs/rdr/rdr-015-indexing-pipeline-rethink.md +0 -0
  110. {conexus-2.3.1 → conexus-2.3.3}/docs/rdr/rdr-016-ast-chunk-line-range-bug.md +0 -0
  111. {conexus-2.3.1 → conexus-2.3.3}/docs/rdr/rdr-017-indexing-progress-reporting.md +0 -0
  112. {conexus-2.3.1 → conexus-2.3.3}/docs/rdr/rdr-018-replace-serve-with-git-hooks.md +0 -0
  113. {conexus-2.3.1 → conexus-2.3.3}/docs/rdr/rdr-019-chromadb-transient-retry.md +0 -0
  114. {conexus-2.3.1 → conexus-2.3.3}/docs/rdr/rdr-020-voyage-chromadb-read-timeout.md +0 -0
  115. {conexus-2.3.1 → conexus-2.3.3}/docs/rdr/rdr-021-docling-pdf-extraction.md +0 -0
  116. {conexus-2.3.1 → conexus-2.3.3}/docs/rdr/rdr-022-memory-delete-command.md +0 -0
  117. {conexus-2.3.1 → conexus-2.3.3}/docs/rdr/rdr-023-agent-tool-permissions-audit.md +0 -0
  118. {conexus-2.3.1 → conexus-2.3.3}/docs/rdr/rdr-024-rdr-process-guardrails.md +0 -0
  119. {conexus-2.3.1 → conexus-2.3.3}/docs/rdr/rdr-025-language-agnostic-agents.md +0 -0
  120. {conexus-2.3.1 → conexus-2.3.3}/docs/rdr/rdr-026-hybrid-search-fusion.md +0 -0
  121. {conexus-2.3.1 → conexus-2.3.3}/docs/rdr/rdr-027-search-results-ux.md +0 -0
  122. {conexus-2.3.1 → conexus-2.3.3}/docs/rdr/rdr-028-code-search-recall.md +0 -0
  123. {conexus-2.3.1 → conexus-2.3.3}/docs/rdr/rdr-029-pipeline-versioning.md +0 -0
  124. {conexus-2.3.1 → conexus-2.3.3}/docs/rdr/rdr-030-reliability-hardening.md +0 -0
  125. {conexus-2.3.1 → conexus-2.3.3}/docs/rdr/rdr-031-collection-portability.md +0 -0
  126. {conexus-2.3.1 → conexus-2.3.3}/docs/rdr/rdr-032-indexer-decomposition.md +0 -0
  127. {conexus-2.3.1 → conexus-2.3.3}/docs/rdr/rdr-033-pdf-agent-nx-index-alignment.md +0 -0
  128. {conexus-2.3.1 → conexus-2.3.3}/docs/rdr/rdr-034-mcp-server-agent-storage.md +0 -0
  129. {conexus-2.3.1 → conexus-2.3.3}/docs/rdr/rdr-035-plugin-agent-mcp-tool-access.md +0 -0
  130. {conexus-2.3.1 → conexus-2.3.3}/docs/rdr/rdr-036-post-accept-planning-workflow.md +0 -0
  131. {conexus-2.3.1 → conexus-2.3.3}/docs/rdr/rdr-037-t3-database-consolidation.md +0 -0
  132. {conexus-2.3.1 → conexus-2.3.3}/docs/rdr/rdr-038-local-t3-backend.md +0 -0
  133. {conexus-2.3.1 → conexus-2.3.3}/docs/rdr/rdr-039-claude-code-framework-alignment.md +0 -0
  134. {conexus-2.3.1 → conexus-2.3.3}/docs/rdr-nexus-integration.md +0 -0
  135. {conexus-2.3.1 → conexus-2.3.3}/docs/rdr-overview.md +0 -0
  136. {conexus-2.3.1 → conexus-2.3.3}/docs/rdr-templates.md +0 -0
  137. {conexus-2.3.1 → conexus-2.3.3}/docs/rdr-workflow.md +0 -0
  138. {conexus-2.3.1 → conexus-2.3.3}/docs/repo-indexing.md +0 -0
  139. {conexus-2.3.1 → conexus-2.3.3}/docs/storage-tiers.md +0 -0
  140. {conexus-2.3.1 → conexus-2.3.3}/nx/.mcp.json +0 -0
  141. {conexus-2.3.1 → conexus-2.3.3}/nx/README.md +0 -0
  142. {conexus-2.3.1 → conexus-2.3.3}/nx/agents/_shared/CONTEXT_PROTOCOL.md +0 -0
  143. {conexus-2.3.1 → conexus-2.3.3}/nx/agents/_shared/ERROR_HANDLING.md +0 -0
  144. {conexus-2.3.1 → conexus-2.3.3}/nx/agents/_shared/MAINTENANCE.md +0 -0
  145. {conexus-2.3.1 → conexus-2.3.3}/nx/agents/_shared/README.md +0 -0
  146. {conexus-2.3.1 → conexus-2.3.3}/nx/agents/_shared/RELAY_TEMPLATE.md +0 -0
  147. {conexus-2.3.1 → conexus-2.3.3}/nx/agents/architect-planner.md +0 -0
  148. {conexus-2.3.1 → conexus-2.3.3}/nx/agents/code-review-expert.md +0 -0
  149. {conexus-2.3.1 → conexus-2.3.3}/nx/agents/codebase-deep-analyzer.md +0 -0
  150. {conexus-2.3.1 → conexus-2.3.3}/nx/agents/debugger.md +0 -0
  151. {conexus-2.3.1 → conexus-2.3.3}/nx/agents/deep-analyst.md +0 -0
  152. {conexus-2.3.1 → conexus-2.3.3}/nx/agents/deep-research-synthesizer.md +0 -0
  153. {conexus-2.3.1 → conexus-2.3.3}/nx/agents/developer.md +0 -0
  154. {conexus-2.3.1 → conexus-2.3.3}/nx/agents/knowledge-tidier.md +0 -0
  155. {conexus-2.3.1 → conexus-2.3.3}/nx/agents/orchestrator.md +0 -0
  156. {conexus-2.3.1 → conexus-2.3.3}/nx/agents/pdf-chromadb-processor.md +0 -0
  157. {conexus-2.3.1 → conexus-2.3.3}/nx/agents/plan-auditor.md +0 -0
  158. {conexus-2.3.1 → conexus-2.3.3}/nx/agents/strategic-planner.md +0 -0
  159. {conexus-2.3.1 → conexus-2.3.3}/nx/agents/substantive-critic.md +0 -0
  160. {conexus-2.3.1 → conexus-2.3.3}/nx/agents/test-validator.md +0 -0
  161. {conexus-2.3.1 → conexus-2.3.3}/nx/commands/analyze-code.md +0 -0
  162. {conexus-2.3.1 → conexus-2.3.3}/nx/commands/architecture.md +0 -0
  163. {conexus-2.3.1 → conexus-2.3.3}/nx/commands/create-plan.md +0 -0
  164. {conexus-2.3.1 → conexus-2.3.3}/nx/commands/debug.md +0 -0
  165. {conexus-2.3.1 → conexus-2.3.3}/nx/commands/deep-analysis.md +0 -0
  166. {conexus-2.3.1 → conexus-2.3.3}/nx/commands/enrich-plan.md +0 -0
  167. {conexus-2.3.1 → conexus-2.3.3}/nx/commands/implement.md +0 -0
  168. {conexus-2.3.1 → conexus-2.3.3}/nx/commands/knowledge-tidy.md +0 -0
  169. {conexus-2.3.1 → conexus-2.3.3}/nx/commands/nx-preflight.md +0 -0
  170. {conexus-2.3.1 → conexus-2.3.3}/nx/commands/pdf-process.md +0 -0
  171. {conexus-2.3.1 → conexus-2.3.3}/nx/commands/plan-audit.md +0 -0
  172. {conexus-2.3.1 → conexus-2.3.3}/nx/commands/rdr-close.md +0 -0
  173. {conexus-2.3.1 → conexus-2.3.3}/nx/commands/rdr-create.md +0 -0
  174. {conexus-2.3.1 → conexus-2.3.3}/nx/commands/rdr-gate.md +0 -0
  175. {conexus-2.3.1 → conexus-2.3.3}/nx/commands/rdr-list.md +0 -0
  176. {conexus-2.3.1 → conexus-2.3.3}/nx/commands/rdr-research.md +0 -0
  177. {conexus-2.3.1 → conexus-2.3.3}/nx/commands/rdr-show.md +0 -0
  178. {conexus-2.3.1 → conexus-2.3.3}/nx/commands/research.md +0 -0
  179. {conexus-2.3.1 → conexus-2.3.3}/nx/commands/review-code.md +0 -0
  180. {conexus-2.3.1 → conexus-2.3.3}/nx/commands/substantive-critique.md +0 -0
  181. {conexus-2.3.1 → conexus-2.3.3}/nx/commands/test-validate.md +0 -0
  182. {conexus-2.3.1 → conexus-2.3.3}/nx/hooks/hooks.json +0 -0
  183. {conexus-2.3.1 → conexus-2.3.3}/nx/hooks/scripts/post_compact_hook.sh +0 -0
  184. {conexus-2.3.1 → conexus-2.3.3}/nx/hooks/scripts/rdr_hook.py +0 -0
  185. {conexus-2.3.1 → conexus-2.3.3}/nx/hooks/scripts/session_start_hook.py +0 -0
  186. {conexus-2.3.1 → conexus-2.3.3}/nx/hooks/scripts/stop_failure_hook.py +0 -0
  187. {conexus-2.3.1 → conexus-2.3.3}/nx/hooks/scripts/subagent-start.sh +0 -0
  188. {conexus-2.3.1 → conexus-2.3.3}/nx/hooks/scripts/t2_prefix_scan.py +0 -0
  189. {conexus-2.3.1 → conexus-2.3.3}/nx/registry.yaml +0 -0
  190. {conexus-2.3.1 → conexus-2.3.3}/nx/resources/rdr/README-TEMPLATE.md +0 -0
  191. {conexus-2.3.1 → conexus-2.3.3}/nx/resources/rdr/TEMPLATE.md +0 -0
  192. {conexus-2.3.1 → conexus-2.3.3}/nx/resources/rdr/post-mortem/TEMPLATE.md +0 -0
  193. {conexus-2.3.1 → conexus-2.3.3}/nx/skills/architecture/SKILL.md +0 -0
  194. {conexus-2.3.1 → conexus-2.3.3}/nx/skills/brainstorming-gate/SKILL.md +0 -0
  195. {conexus-2.3.1 → conexus-2.3.3}/nx/skills/cli-controller/SKILL.md +0 -0
  196. {conexus-2.3.1 → conexus-2.3.3}/nx/skills/code-review/SKILL.md +0 -0
  197. {conexus-2.3.1 → conexus-2.3.3}/nx/skills/codebase-analysis/SKILL.md +0 -0
  198. {conexus-2.3.1 → conexus-2.3.3}/nx/skills/debugging/SKILL.md +0 -0
  199. {conexus-2.3.1 → conexus-2.3.3}/nx/skills/deep-analysis/SKILL.md +0 -0
  200. {conexus-2.3.1 → conexus-2.3.3}/nx/skills/development/SKILL.md +0 -0
  201. {conexus-2.3.1 → conexus-2.3.3}/nx/skills/knowledge-tidying/SKILL.md +0 -0
  202. {conexus-2.3.1 → conexus-2.3.3}/nx/skills/nexus/SKILL.md +0 -0
  203. {conexus-2.3.1 → conexus-2.3.3}/nx/skills/nexus/reference.md +0 -0
  204. {conexus-2.3.1 → conexus-2.3.3}/nx/skills/orchestration/SKILL.md +0 -0
  205. {conexus-2.3.1 → conexus-2.3.3}/nx/skills/pdf-processing/SKILL.md +0 -0
  206. {conexus-2.3.1 → conexus-2.3.3}/nx/skills/plan-validation/SKILL.md +0 -0
  207. {conexus-2.3.1 → conexus-2.3.3}/nx/skills/rdr-accept/SKILL.md +0 -0
  208. {conexus-2.3.1 → conexus-2.3.3}/nx/skills/rdr-close/SKILL.md +0 -0
  209. {conexus-2.3.1 → conexus-2.3.3}/nx/skills/rdr-create/SKILL.md +0 -0
  210. {conexus-2.3.1 → conexus-2.3.3}/nx/skills/rdr-gate/SKILL.md +0 -0
  211. {conexus-2.3.1 → conexus-2.3.3}/nx/skills/rdr-list/SKILL.md +0 -0
  212. {conexus-2.3.1 → conexus-2.3.3}/nx/skills/rdr-research/SKILL.md +0 -0
  213. {conexus-2.3.1 → conexus-2.3.3}/nx/skills/rdr-show/SKILL.md +0 -0
  214. {conexus-2.3.1 → conexus-2.3.3}/nx/skills/research-synthesis/SKILL.md +0 -0
  215. {conexus-2.3.1 → conexus-2.3.3}/nx/skills/serena-code-nav/SKILL.md +0 -0
  216. {conexus-2.3.1 → conexus-2.3.3}/nx/skills/strategic-planning/SKILL.md +0 -0
  217. {conexus-2.3.1 → conexus-2.3.3}/nx/skills/substantive-critique/SKILL.md +0 -0
  218. {conexus-2.3.1 → conexus-2.3.3}/nx/skills/test-validation/SKILL.md +0 -0
  219. {conexus-2.3.1 → conexus-2.3.3}/nx/skills/using-nx-skills/SKILL.md +0 -0
  220. {conexus-2.3.1 → conexus-2.3.3}/src/nexus/__init__.py +0 -0
  221. {conexus-2.3.1 → conexus-2.3.3}/src/nexus/chunker.py +0 -0
  222. {conexus-2.3.1 → conexus-2.3.3}/src/nexus/classifier.py +0 -0
  223. {conexus-2.3.1 → conexus-2.3.3}/src/nexus/cli.py +0 -0
  224. {conexus-2.3.1 → conexus-2.3.3}/src/nexus/code_indexer.py +0 -0
  225. {conexus-2.3.1 → conexus-2.3.3}/src/nexus/commands/__init__.py +0 -0
  226. {conexus-2.3.1 → conexus-2.3.3}/src/nexus/commands/_helpers.py +0 -0
  227. {conexus-2.3.1 → conexus-2.3.3}/src/nexus/commands/_provision.py +0 -0
  228. {conexus-2.3.1 → conexus-2.3.3}/src/nexus/commands/collection.py +0 -0
  229. {conexus-2.3.1 → conexus-2.3.3}/src/nexus/commands/config_cmd.py +0 -0
  230. {conexus-2.3.1 → conexus-2.3.3}/src/nexus/commands/doctor.py +0 -0
  231. {conexus-2.3.1 → conexus-2.3.3}/src/nexus/commands/hook.py +0 -0
  232. {conexus-2.3.1 → conexus-2.3.3}/src/nexus/commands/hooks.py +0 -0
  233. {conexus-2.3.1 → conexus-2.3.3}/src/nexus/commands/index.py +0 -0
  234. {conexus-2.3.1 → conexus-2.3.3}/src/nexus/commands/memory.py +0 -0
  235. {conexus-2.3.1 → conexus-2.3.3}/src/nexus/commands/scratch.py +0 -0
  236. {conexus-2.3.1 → conexus-2.3.3}/src/nexus/commands/search_cmd.py +0 -0
  237. {conexus-2.3.1 → conexus-2.3.3}/src/nexus/commands/store.py +0 -0
  238. {conexus-2.3.1 → conexus-2.3.3}/src/nexus/config.py +0 -0
  239. {conexus-2.3.1 → conexus-2.3.3}/src/nexus/corpus.py +0 -0
  240. {conexus-2.3.1 → conexus-2.3.3}/src/nexus/db/__init__.py +0 -0
  241. {conexus-2.3.1 → conexus-2.3.3}/src/nexus/db/chroma_quotas.py +0 -0
  242. {conexus-2.3.1 → conexus-2.3.3}/src/nexus/db/local_ef.py +0 -0
  243. {conexus-2.3.1 → conexus-2.3.3}/src/nexus/db/t1.py +0 -0
  244. {conexus-2.3.1 → conexus-2.3.3}/src/nexus/db/t2.py +0 -0
  245. {conexus-2.3.1 → conexus-2.3.3}/src/nexus/doc_indexer.py +0 -0
  246. {conexus-2.3.1 → conexus-2.3.3}/src/nexus/errors.py +0 -0
  247. {conexus-2.3.1 → conexus-2.3.3}/src/nexus/exporter.py +0 -0
  248. {conexus-2.3.1 → conexus-2.3.3}/src/nexus/formatters.py +0 -0
  249. {conexus-2.3.1 → conexus-2.3.3}/src/nexus/frecency.py +0 -0
  250. {conexus-2.3.1 → conexus-2.3.3}/src/nexus/hooks.py +0 -0
  251. {conexus-2.3.1 → conexus-2.3.3}/src/nexus/index_context.py +0 -0
  252. {conexus-2.3.1 → conexus-2.3.3}/src/nexus/indexer.py +0 -0
  253. {conexus-2.3.1 → conexus-2.3.3}/src/nexus/indexer_utils.py +0 -0
  254. {conexus-2.3.1 → conexus-2.3.3}/src/nexus/languages.py +0 -0
  255. {conexus-2.3.1 → conexus-2.3.3}/src/nexus/mcp_server.py +0 -0
  256. {conexus-2.3.1 → conexus-2.3.3}/src/nexus/md_chunker.py +0 -0
  257. {conexus-2.3.1 → conexus-2.3.3}/src/nexus/pdf_chunker.py +0 -0
  258. {conexus-2.3.1 → conexus-2.3.3}/src/nexus/pdf_extractor.py +0 -0
  259. {conexus-2.3.1 → conexus-2.3.3}/src/nexus/prose_indexer.py +0 -0
  260. {conexus-2.3.1 → conexus-2.3.3}/src/nexus/registry.py +0 -0
  261. {conexus-2.3.1 → conexus-2.3.3}/src/nexus/retry.py +0 -0
  262. {conexus-2.3.1 → conexus-2.3.3}/src/nexus/ripgrep_cache.py +0 -0
  263. {conexus-2.3.1 → conexus-2.3.3}/src/nexus/scoring.py +0 -0
  264. {conexus-2.3.1 → conexus-2.3.3}/src/nexus/search_engine.py +0 -0
  265. {conexus-2.3.1 → conexus-2.3.3}/src/nexus/session.py +0 -0
  266. {conexus-2.3.1 → conexus-2.3.3}/src/nexus/ttl.py +0 -0
  267. {conexus-2.3.1 → conexus-2.3.3}/src/nexus/types.py +0 -0
  268. {conexus-2.3.1 → conexus-2.3.3}/tests/__init__.py +0 -0
  269. {conexus-2.3.1 → conexus-2.3.3}/tests/__snapshots__/test_search_snapshot.ambr +0 -0
  270. {conexus-2.3.1 → conexus-2.3.3}/tests/conftest.py +0 -0
  271. {conexus-2.3.1 → conexus-2.3.3}/tests/e2e/auth-login.sh +0 -0
  272. {conexus-2.3.1 → conexus-2.3.3}/tests/e2e/lib.sh +0 -0
  273. {conexus-2.3.1 → conexus-2.3.3}/tests/e2e/run.sh +0 -0
  274. {conexus-2.3.1 → conexus-2.3.3}/tests/e2e/sandbox.sh +0 -0
  275. {conexus-2.3.1 → conexus-2.3.3}/tests/e2e/scenarios/00_debug_load.sh +0 -0
  276. {conexus-2.3.1 → conexus-2.3.3}/tests/e2e/scenarios/01_smoke.sh +0 -0
  277. {conexus-2.3.1 → conexus-2.3.3}/tests/e2e/scenarios/02_sequential_thinking.sh +0 -0
  278. {conexus-2.3.1 → conexus-2.3.3}/tests/e2e/scenarios/03_skills.sh +0 -0
  279. {conexus-2.3.1 → conexus-2.3.3}/tests/hooks/__init__.py +0 -0
  280. {conexus-2.3.1 → conexus-2.3.3}/tests/hooks/test_post_compact_hook.py +0 -0
  281. {conexus-2.3.1 → conexus-2.3.3}/tests/test_ast_languages.py +0 -0
  282. {conexus-2.3.1 → conexus-2.3.3}/tests/test_chroma_quotas.py +0 -0
  283. {conexus-2.3.1 → conexus-2.3.3}/tests/test_chroma_retry.py +0 -0
  284. {conexus-2.3.1 → conexus-2.3.3}/tests/test_chunker.py +0 -0
  285. {conexus-2.3.1 → conexus-2.3.3}/tests/test_chunker_ast_languages.py +0 -0
  286. {conexus-2.3.1 → conexus-2.3.3}/tests/test_classifier.py +0 -0
  287. {conexus-2.3.1 → conexus-2.3.3}/tests/test_collection_cmd.py +0 -0
  288. {conexus-2.3.1 → conexus-2.3.3}/tests/test_config.py +0 -0
  289. {conexus-2.3.1 → conexus-2.3.3}/tests/test_config_cmd.py +0 -0
  290. {conexus-2.3.1 → conexus-2.3.3}/tests/test_corpus.py +0 -0
  291. {conexus-2.3.1 → conexus-2.3.3}/tests/test_doc_indexer.py +0 -0
  292. {conexus-2.3.1 → conexus-2.3.3}/tests/test_doc_indexer_hash_sync.py +0 -0
  293. {conexus-2.3.1 → conexus-2.3.3}/tests/test_doc_indexer_pagination.py +0 -0
  294. {conexus-2.3.1 → conexus-2.3.3}/tests/test_doctor_cmd.py +0 -0
  295. {conexus-2.3.1 → conexus-2.3.3}/tests/test_doctor_integrity.py +0 -0
  296. {conexus-2.3.1 → conexus-2.3.3}/tests/test_e2e.py +0 -0
  297. {conexus-2.3.1 → conexus-2.3.3}/tests/test_exporter.py +0 -0
  298. {conexus-2.3.1 → conexus-2.3.3}/tests/test_formatters.py +0 -0
  299. {conexus-2.3.1 → conexus-2.3.3}/tests/test_frecency.py +0 -0
  300. {conexus-2.3.1 → conexus-2.3.3}/tests/test_git_hooks.py +0 -0
  301. {conexus-2.3.1 → conexus-2.3.3}/tests/test_hooks.py +0 -0
  302. {conexus-2.3.1 → conexus-2.3.3}/tests/test_hybrid_boost.py +0 -0
  303. {conexus-2.3.1 → conexus-2.3.3}/tests/test_index_cmd.py +0 -0
  304. {conexus-2.3.1 → conexus-2.3.3}/tests/test_index_lock.py +0 -0
  305. {conexus-2.3.1 → conexus-2.3.3}/tests/test_index_rdr_cmd.py +0 -0
  306. {conexus-2.3.1 → conexus-2.3.3}/tests/test_index_reminder.py +0 -0
  307. {conexus-2.3.1 → conexus-2.3.3}/tests/test_indexer.py +0 -0
  308. {conexus-2.3.1 → conexus-2.3.3}/tests/test_indexer_chunk_flow.py +0 -0
  309. {conexus-2.3.1 → conexus-2.3.3}/tests/test_indexer_e2e.py +0 -0
  310. {conexus-2.3.1 → conexus-2.3.3}/tests/test_indexer_modules.py +0 -0
  311. {conexus-2.3.1 → conexus-2.3.3}/tests/test_integration.py +0 -0
  312. {conexus-2.3.1 → conexus-2.3.3}/tests/test_languages.py +0 -0
  313. {conexus-2.3.1 → conexus-2.3.3}/tests/test_local_mode.py +0 -0
  314. {conexus-2.3.1 → conexus-2.3.3}/tests/test_mcp_concurrency.py +0 -0
  315. {conexus-2.3.1 → conexus-2.3.3}/tests/test_mcp_integration.py +0 -0
  316. {conexus-2.3.1 → conexus-2.3.3}/tests/test_mcp_server.py +0 -0
  317. {conexus-2.3.1 → conexus-2.3.3}/tests/test_mcp_session.py +0 -0
  318. {conexus-2.3.1 → conexus-2.3.3}/tests/test_md_chunker.py +0 -0
  319. {conexus-2.3.1 → conexus-2.3.3}/tests/test_md_chunker_semantic_integrity.py +0 -0
  320. {conexus-2.3.1 → conexus-2.3.3}/tests/test_md_preservation.py +0 -0
  321. {conexus-2.3.1 → conexus-2.3.3}/tests/test_memory.py +0 -0
  322. {conexus-2.3.1 → conexus-2.3.3}/tests/test_minified_chunking.py +0 -0
  323. {conexus-2.3.1 → conexus-2.3.3}/tests/test_p0_regressions.py +0 -0
  324. {conexus-2.3.1 → conexus-2.3.3}/tests/test_pdf_chunker.py +0 -0
  325. {conexus-2.3.1 → conexus-2.3.3}/tests/test_pdf_chunker_integration.py +0 -0
  326. {conexus-2.3.1 → conexus-2.3.3}/tests/test_pdf_e2e.py +0 -0
  327. {conexus-2.3.1 → conexus-2.3.3}/tests/test_pdf_extractor.py +0 -0
  328. {conexus-2.3.1 → conexus-2.3.3}/tests/test_pdf_extractor_integration.py +0 -0
  329. {conexus-2.3.1 → conexus-2.3.3}/tests/test_pdf_extractor_normalization.py +0 -0
  330. {conexus-2.3.1 → conexus-2.3.3}/tests/test_pdf_normalization.py +0 -0
  331. {conexus-2.3.1 → conexus-2.3.3}/tests/test_pdf_subsystem.py +0 -0
  332. {conexus-2.3.1 → conexus-2.3.3}/tests/test_pipeline_version.py +0 -0
  333. {conexus-2.3.1 → conexus-2.3.3}/tests/test_plugin.py +0 -0
  334. {conexus-2.3.1 → conexus-2.3.3}/tests/test_plugin_install.py +0 -0
  335. {conexus-2.3.1 → conexus-2.3.3}/tests/test_plugin_structure.py +0 -0
  336. {conexus-2.3.1 → conexus-2.3.3}/tests/test_ppid_chain_hypothesis.py +0 -0
  337. {conexus-2.3.1 → conexus-2.3.3}/tests/test_provision.py +0 -0
  338. {conexus-2.3.1 → conexus-2.3.3}/tests/test_registry.py +0 -0
  339. {conexus-2.3.1 → conexus-2.3.3}/tests/test_ripgrep_cache.py +0 -0
  340. {conexus-2.3.1 → conexus-2.3.3}/tests/test_schema.py +0 -0
  341. {conexus-2.3.1 → conexus-2.3.3}/tests/test_scoring.py +0 -0
  342. {conexus-2.3.1 → conexus-2.3.3}/tests/test_scratch.py +0 -0
  343. {conexus-2.3.1 → conexus-2.3.3}/tests/test_scratch_cmd.py +0 -0
  344. {conexus-2.3.1 → conexus-2.3.3}/tests/test_search_cmd.py +0 -0
  345. {conexus-2.3.1 → conexus-2.3.3}/tests/test_search_engine.py +0 -0
  346. {conexus-2.3.1 → conexus-2.3.3}/tests/test_search_modules.py +0 -0
  347. {conexus-2.3.1 → conexus-2.3.3}/tests/test_search_snapshot.py +0 -0
  348. {conexus-2.3.1 → conexus-2.3.3}/tests/test_session.py +0 -0
  349. {conexus-2.3.1 → conexus-2.3.3}/tests/test_session_propagation_hypotheses.py +0 -0
  350. {conexus-2.3.1 → conexus-2.3.3}/tests/test_silent_error_logging.py +0 -0
  351. {conexus-2.3.1 → conexus-2.3.3}/tests/test_store_cmd.py +0 -0
  352. {conexus-2.3.1 → conexus-2.3.3}/tests/test_t1.py +0 -0
  353. {conexus-2.3.1 → conexus-2.3.3}/tests/test_t2.py +0 -0
  354. {conexus-2.3.1 → conexus-2.3.3}/tests/test_t2_prefix_scan.py +0 -0
  355. {conexus-2.3.1 → conexus-2.3.3}/tests/test_t3.py +0 -0
  356. {conexus-2.3.1 → conexus-2.3.3}/tests/test_t3_quota_enforcement.py +0 -0
  357. {conexus-2.3.1 → conexus-2.3.3}/tests/test_ttl.py +0 -0
  358. {conexus-2.3.1 → conexus-2.3.3}/tests/test_tuning_config.py +0 -0
  359. {conexus-2.3.1 → conexus-2.3.3}/tests/test_types_and_errors.py +0 -0
  360. {conexus-2.3.1 → conexus-2.3.3}/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.3.1"
12
+ "version": "2.3.3"
13
13
  }
14
14
  ]
15
15
  }
@@ -6,6 +6,33 @@ Versioning follows [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
6
6
 
7
7
  ## [Unreleased]
8
8
 
9
+ ## [2.3.3] - 2026-03-23
10
+
11
+ ### Fixed
12
+ - **Python 3.14 compatibility** — `import voyageai` at module level in `t3.py`
13
+ crashed on Python 3.14 due to Pydantic v1 incompatibility in the voyageai SDK.
14
+ Import is now guarded with `try/except`; cloud mode raises a clear error, local
15
+ mode works without voyageai.
16
+
17
+ ## [2.3.2] - 2026-03-22
18
+
19
+ ### Fixed
20
+ - **Planning chain bypass prevention** — agents can no longer skip the
21
+ strategic-planner → plan-auditor → plan-enricher chain by creating beads
22
+ directly or compensating when subagents fail. PROHIBITION block added to
23
+ rdr-accept, chain mandatory for multi-phase RDRs.
24
+ - **Silent bead content corruption** — `bd update --description "..."` silently
25
+ destroys multi-line markdown (backticks, `$variables`, nested quotes). Replaced
26
+ with Write tool → `--body-file` pattern in plan-enricher agent and skill.
27
+ - **Dead T2 idempotency code** — removed Python comparisons against always-None
28
+ `t2_status`; self-healing logic moved to Action section with live `memory_get`.
29
+ - **Unbound placeholders** — fixed `{id}`, `{t2_status}`, `{repo_name}`, `{type}`
30
+ leaking from Python into agent instructions; standardized to `<ID>` notation.
31
+
32
+ ### Added
33
+ - **Known Pitfalls** section in writing-nx-skills skill — documents the
34
+ `--description` corruption bug so future agent authors use `--body-file`.
35
+
9
36
  ## [2.3.1] - 2026-03-22
10
37
 
11
38
  ### Fixed
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: conexus
3
- Version: 2.3.1
3
+ Version: 2.3.3
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
@@ -6,6 +6,25 @@ Versioning follows [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
6
6
 
7
7
  ## [Unreleased]
8
8
 
9
+ ## [2.3.3] - 2026-03-23
10
+
11
+ Plugin version aligned with Nexus CLI 2.3.3. No plugin-level functional changes.
12
+
13
+ ## [2.3.2] - 2026-03-22
14
+
15
+ ### Fixed
16
+ - **rdr-accept**: PROHIBITION block prevents orchestrator from bypassing
17
+ planning chain. Chain mandatory for multi-phase RDRs. Subagent failure
18
+ clause blocks "let me finish this directly" compensation. Dead T2
19
+ idempotency code removed; self-healing uses live memory_get results.
20
+ Unbound placeholders fixed with `<ID>` notation.
21
+ - **plan-enricher**: `bd update --description` replaced with Write tool →
22
+ `--body-file` pattern. Prevents silent content corruption from shell escaping.
23
+ - **enrich-plan skill**: Standalone invocation path updated to match agent fix.
24
+
25
+ ### Added
26
+ - **writing-nx-skills**: Known Pitfalls section for `--description` corruption.
27
+
9
28
  ## [2.3.1] - 2026-03-22
10
29
 
11
30
  ### Fixed
@@ -114,10 +114,13 @@ For each child bead, update its description with:
114
114
 
115
115
  ### Step 4: Update Beads
116
116
 
117
- For each enriched bead:
118
- ```bash
119
- bd update <id> --description "enriched content"
120
- ```
117
+ For each enriched bead, two actions in sequence:
118
+
119
+ **Step 4a** — Write enriched content to a temp file using the **Write tool** (file_path: `/tmp/bead-<id>.md`, content: the enriched markdown). Do NOT use echo, cat, or heredoc — use the Write tool.
120
+
121
+ **Step 4b** — Update the bead from the file: `bd update <id> --body-file /tmp/bead-<id>.md`
122
+
123
+ **IMPORTANT**: Do NOT use `--description "..."` for multi-line or markdown content — shell escaping silently corrupts backticks, `$variables`, and nested quotes without raising an error. Always use `--body-file`.
121
124
 
122
125
  ## T2 Persistence
123
126
 
@@ -154,7 +157,7 @@ This agent follows the [Shared Context Protocol](./_shared/CONTEXT_PROTOCOL.md).
154
157
  See [ERROR_HANDLING.md](./_shared/ERROR_HANDLING.md) for common error patterns and recovery.
155
158
 
156
159
  ### Agent-Specific PRODUCE
157
- - **Enriched Beads**: Updated via `bd update <id> --description "..."` with execution-ready context
160
+ - **Enriched Beads**: Updated via Write tool → `bd update <id> --body-file /tmp/bead-<id>.md` with execution-ready context
158
161
  - **T2 memory**: Epic bead ID written via memory_put tool: project="{repo}_rdr", title="NNN"
159
162
  - **T1 scratch**: Enrichment summary via scratch tool: action="put", tags="enrichment-complete"
160
163
  - **Console output**: Enriched plan summary table
@@ -168,7 +171,7 @@ Store using these naming conventions:
168
171
  **CRITICAL**: Complete all data persistence BEFORE generating final response.
169
172
 
170
173
  **Sequence** (follow strictly):
171
- 1. **Update All Beads**: Run `bd update` for every enriched bead
174
+ 1. **Update All Beads**: For each bead — Write content to `/tmp/bead-<id>.md` via Write tool, then `bd update <id> --body-file /tmp/bead-<id>.md` (never `--description`)
172
175
  2. **Write T2 Record**: Store epic bead ID and enrichment metadata via memory_put tool
173
176
  3. **Write T1 Summary**: Store enrichment summary to scratch
174
177
  4. **Verify Persistence**: Confirm beads updated (bd show <id> for sample), T2 written (memory_get)
@@ -0,0 +1,262 @@
1
+ ---
2
+ description: Accept a gated RDR — verifies gate PASSED in T2, updates status to accepted
3
+ ---
4
+
5
+ # RDR Accept
6
+
7
+ !{
8
+ NEXUS_RDR_ARGS="${ARGUMENTS:-}" python3 << 'PYEOF'
9
+ import os, sys, re, subprocess
10
+ from pathlib import Path
11
+
12
+ args = os.environ.get('NEXUS_RDR_ARGS', '').strip()
13
+
14
+ # Repo root and name
15
+ try:
16
+ repo_root = subprocess.check_output(
17
+ ['git', 'rev-parse', '--show-toplevel'],
18
+ stderr=subprocess.DEVNULL, text=True).strip()
19
+ repo_name = os.path.basename(repo_root)
20
+ except Exception:
21
+ repo_root = os.getcwd()
22
+ repo_name = os.path.basename(repo_root)
23
+
24
+ # Resolve RDR directory from .nexus.yml (default: docs/rdr)
25
+ rdr_dir = 'docs/rdr'
26
+ nexus_yml = Path(repo_root) / '.nexus.yml'
27
+ if nexus_yml.exists():
28
+ content = nexus_yml.read_text()
29
+ try:
30
+ import yaml
31
+ d = yaml.safe_load(content) or {}
32
+ paths = (d.get('indexing') or {}).get('rdr_paths', ['docs/rdr'])
33
+ rdr_dir = paths[0] if paths else 'docs/rdr'
34
+ except ImportError:
35
+ m_yml = (re.search(r'rdr_paths[^\[]*\[([^\]]+)\]', content) or
36
+ re.search(r'rdr_paths:\s*\n\s+-\s*(.+)', content))
37
+ if m_yml:
38
+ v = m_yml.group(1)
39
+ parts = re.findall(r'[a-z][a-z0-9/_-]+', v)
40
+ rdr_dir = parts[0] if parts else 'docs/rdr'
41
+
42
+ rdr_path = Path(repo_root) / rdr_dir
43
+
44
+ print(f"**Repo:** `{repo_name}` **RDR directory:** `{rdr_dir}`")
45
+ print()
46
+
47
+
48
+ def parse_frontmatter(filepath):
49
+ text = filepath.read_text(errors='replace')
50
+ meta = {}
51
+ if text.startswith('---'):
52
+ parts = text.split('---', 2)
53
+ if len(parts) >= 3:
54
+ block = parts[1]
55
+ try:
56
+ import yaml; meta = yaml.safe_load(block) or {}
57
+ except Exception:
58
+ for line in block.splitlines():
59
+ if ':' in line:
60
+ k, _, v = line.partition(':')
61
+ meta[k.strip().lower()] = v.strip()
62
+ if 'title' not in meta and 'name' not in meta:
63
+ h1 = re.search(r'^#\s+(.+)', text, re.MULTILINE)
64
+ if h1:
65
+ meta['title'] = h1.group(1).strip()
66
+ return meta, text
67
+
68
+
69
+ def find_rdr_file(rdr_path, id_str):
70
+ m = re.search(r'\d+', id_str)
71
+ if not m:
72
+ return None
73
+ num_int = int(m.group(0))
74
+ for f in sorted(rdr_path.glob('*.md')):
75
+ nums = re.findall(r'\d+', f.stem)
76
+ if nums and int(nums[0]) == num_int:
77
+ return f
78
+ return None
79
+
80
+
81
+ EXCLUDED = {'readme.md', 'template.md', 'index.md', 'overview.md', 'workflow.md', 'templates.md'}
82
+
83
+ def get_all_rdrs(rdr_path):
84
+ """Return list of dicts for all RDRs in the directory."""
85
+ all_md = sorted(rdr_path.glob('*.md'))
86
+ rdrs = []
87
+ for f in all_md:
88
+ if f.name.lower() in EXCLUDED:
89
+ continue
90
+ fm, text = parse_frontmatter(f)
91
+ rtype = fm.get('type', '?')
92
+ doc_status = fm.get('status', '?')
93
+ if doc_status == '?' and rtype == '?':
94
+ continue
95
+ rdrs.append({
96
+ 'file': f.name,
97
+ 'path': f,
98
+ 'title': fm.get('title', fm.get('name', f.stem)),
99
+ 'status': doc_status,
100
+ 'rtype': rtype,
101
+ 'priority': fm.get('priority', '?'),
102
+ })
103
+ return rdrs
104
+
105
+
106
+ if not rdr_path.exists():
107
+ print(f"> No RDRs found — `{rdr_dir}` does not exist in this repo.")
108
+ sys.exit(0)
109
+
110
+ id_match = re.search(r'\d+', args)
111
+
112
+ if not id_match:
113
+ print("> **Usage**: `/nx:rdr-accept <id>` — e.g. `/nx:rdr-accept 003` or `/nx:rdr-accept RDR-003`")
114
+ print()
115
+ rdrs = get_all_rdrs(rdr_path)
116
+ draft_rdrs = [r for r in rdrs if r['status'].lower() == 'draft']
117
+ print("### Draft RDRs (eligible for acceptance)")
118
+ print()
119
+ if draft_rdrs:
120
+ print("| File | Title | Status | Type |")
121
+ print("|------|-------|--------|------|")
122
+ for r in draft_rdrs:
123
+ print(f"| {r['file']} | {r['title']} | {r['status']} | {r['rtype']} |")
124
+ else:
125
+ print("No Draft RDRs found. Only Draft RDRs can be accepted.")
126
+ sys.exit(0)
127
+
128
+ rdr_file = find_rdr_file(rdr_path, id_match.group(0))
129
+ if not rdr_file:
130
+ print(f"> RDR not found for ID: `{id_match.group(0)}`")
131
+ sys.exit(0)
132
+
133
+ fm, text = parse_frontmatter(rdr_file)
134
+ title = fm.get('title', fm.get('name', rdr_file.stem))
135
+ current_status = fm.get('status', '?')
136
+ rdr_type = fm.get('type', '?')
137
+ rdr_num = re.search(r'\d+', rdr_file.stem)
138
+ t2_key = rdr_num.group(0) if rdr_num else rdr_file.stem
139
+
140
+ print(f"### RDR: {rdr_file.name}")
141
+ print(f"**RDR ID:** {t2_key} **Title:** {title} **Type:** {rdr_type} **File Status:** {current_status}")
142
+ print()
143
+
144
+ # Accepted status is allowed — agent handles idempotency in Step 1
145
+ if current_status.lower() not in ('draft', 'accepted'):
146
+ print(f"> **BLOCKED**: RDR status is `{current_status}`. Only Draft RDRs can be accepted.")
147
+ sys.exit(0)
148
+
149
+ # T2 lookups — agent must call these MCP tools and use the results in the Action section
150
+ print("### T2 Lookups (call these before executing Action steps)")
151
+ print()
152
+ print(f"1. **T2 metadata**: Use **memory_get** tool: project=\"{repo_name}_rdr\", title=\"{t2_key}\"")
153
+ print(f"2. **T2 gate result**: Use **memory_get** tool: project=\"{repo_name}_rdr\", title=\"{t2_key}-gate-latest\"")
154
+ print(f" If no gate record exists, run `/nx:rdr-gate {t2_key}` first.")
155
+ print()
156
+ print(f"**RDR file path:** `{rdr_file}`")
157
+ print()
158
+
159
+ # Phase count auto-detection for planning handoff
160
+ ip_match = re.search(
161
+ r'^## Implementation Plan\s*\n(.*?)(?=^## |\Z)',
162
+ text, re.MULTILINE | re.DOTALL)
163
+ phase_count = 0
164
+ has_impl_plan = ip_match is not None
165
+ if has_impl_plan:
166
+ phase_count = len(re.findall(r'^### Phase', ip_match.group(1), re.MULTILINE))
167
+
168
+ print("### Planning Handoff")
169
+ print(f"**Phase count detected:** {phase_count}")
170
+ print(f"**Has Implementation Plan section:** {'yes' if has_impl_plan else 'no'}")
171
+ if phase_count >= 2:
172
+ print("**Recommendation:** Invoke strategic planner (multi-phase RDR)")
173
+ print("**Default:** yes")
174
+ elif not has_impl_plan:
175
+ print("**Warning:** No Implementation Plan section detected — this RDR may not be ready for planning.")
176
+ print("**Recommendation:** Skip planning")
177
+ print("**Default:** no")
178
+ else:
179
+ print("**Recommendation:** Skip planning (single-phase)")
180
+ print("**Default:** no")
181
+ print()
182
+ PYEOF
183
+ }
184
+
185
+ ## RDR to Accept
186
+
187
+ $ARGUMENTS
188
+
189
+ ## Action
190
+
191
+ > **PROHIBITION — PLANNING CHAIN INTEGRITY**
192
+ > You MUST NOT create beads, write plans, enrich beads, or perform any planning/enrichment work yourself.
193
+ > You are the **orchestrator only**. Running `bd create`, `bd dep add`, `bd update --description`,
194
+ > or writing plan content in the Planning Chain is a HARD STOP — halt and report the error.
195
+ > Only the dispatched subagents (strategic-planner, plan-auditor, plan-enricher) do this work.
196
+ > Doing it yourself bypasses the audit and enrichment chain, producing unvalidated plans.
197
+ >
198
+ > **SUBAGENT FAILURE**: If any subagent in the chain fails or returns partial results,
199
+ > you MUST NOT compensate by doing the subagent's work yourself. Report the failure,
200
+ > state which step broke, and provide the retry command. "Let me finish this directly"
201
+ > is the exact behavior this prohibition exists to prevent.
202
+ >
203
+ > If the Agent tool is not available (e.g., you are a subagent), report:
204
+ > "Cannot dispatch planning chain — Agent tool unavailable. Run /nx:rdr-accept from the main conversation."
205
+
206
+ All RDR metadata is pre-loaded above. Step 8 requires additional tool calls for planning dispatch.
207
+
208
+ **Notation**: All references to `<ID>` below mean the **RDR ID** value from the script output (e.g. `027`). All references to `<type>` mean the **Type** value (e.g. `design`). Substitute with the actual values.
209
+
210
+ **Before executing steps below**, call both T2 lookups listed above (memory_get for metadata and gate result). You need these results for Steps 1–2.
211
+
212
+ - **Step 1 — T2 idempotency and self-healing**: Compare the **File Status** (from script output above) against the **T2 metadata status** (from your memory_get call):
213
+ - **Both show `accepted`**: True no-op. Print `> RDR is already accepted (file and T2 agree). Nothing to do.` and stop.
214
+ - **File shows `accepted`, T2 does not**: Self-healing — update T2 to match file. Print `> Self-healing: file shows accepted but T2 shows <actual-T2-status>. Updating T2.` Use memory_put to set T2 status to `accepted`. Then stop (no further steps needed).
215
+ - **T2 shows `accepted`, file shows `draft`**: Self-healing — update file to match T2. Print `> Self-healing: T2 shows accepted but file shows draft. Updating file.` Change file frontmatter to `status: accepted` and `git add` the updated file. Then stop.
216
+ - **File shows `draft` and T2 shows `draft` (or T2 record not found)**: Normal flow — proceed to Step 2.
217
+ - **Step 2 — Verify gate**: Check that the T2 gate result (from your memory_get call) shows `outcome: "PASSED"`. If the record exists but `outcome` is absent or is not `"PASSED"`, treat as BLOCKED. If no gate record exists at all, also BLOCKED. Report **BLOCKED** and stop. Print: `> Run /nx:rdr-gate <ID> first.`
218
+ - **Step 3 — Update T2** (T2 is the process authority):
219
+ Use **memory_put** tool: content="status: accepted\naccepted_date: <today YYYY-MM-DD>\ntitle: <title>\ntype: <type>\n(preserve other fields from T2 Metadata lookup)", project="<repo-name>_rdr" (same project as in the T2 Lookups above), title="<ID>", ttl="permanent", tags="rdr,<type>"
220
+ - **Step 4 — Update the RDR file**: Change `status: draft` to `status: accepted` in the YAML frontmatter. Add `accepted_date: YYYY-MM-DD` if not present.
221
+ - **Step 5 — Update `reviewed-by`**: If `reviewed-by` is empty or placeholder, set to `self` (solo review).
222
+ - **Step 6 — Regenerate README**: Update `<rdr-dir>/README.md` (the RDR directory from the script output header) index to reflect the new status.
223
+ - **Step 7 — Stage files**: `git add` the modified RDR file and README.
224
+ - **Step 8 — Planning handoff**: Use the phase count and recommendation from the script output above.
225
+ - **If phase_count >= 2**: The planning chain is **MANDATORY**. Do not ask — print `> Multi-phase RDR — dispatching planning chain (mandatory).` and proceed to the Planning Chain below.
226
+ - **If phase_count < 2**: Ask: "Invoke strategic planner to build execution beads? (y/n) [default: no]"
227
+ - **If no:** Accept is complete. Print: `> RDR <ID> accepted. Ready for implementation.`
228
+ - **If yes:** Proceed to the Planning Chain below.
229
+
230
+ ---
231
+
232
+ ### Planning Chain (triggered from Step 8 above)
233
+
234
+ Execute these steps sequentially when the planning handoff triggers (mandatory multi-phase or user opted in). **Reminder: you are the orchestrator. Do NOT create beads or plans yourself.**
235
+
236
+ **Step 8a — Write T1 context:**
237
+ Write T1 scratch entry: Use scratch tool: action="put", content="RDR-<ID>: planning context for <title>. RDR file: <RDR-file-path>", tags="rdr-planning-context,rdr-<ID>"
238
+
239
+ **Step 8b — Dispatch strategic-planner (MANDATORY — do NOT do this yourself):**
240
+ Dispatch `nx:strategic-planner` agent (via Agent tool, subagent_type="nx:strategic-planner") with prompt:
241
+ > Create phased execution plan for RDR-<ID>: <title>. RDR file: <RDR-file-path>. Read the RDR content for implementation phases. Create epic and task beads with dependencies.
242
+
243
+ **Wait for the planner to complete before proceeding.**
244
+ Note the plan file path and bead IDs from the planner's output.
245
+ **If the planner did not create beads, this is a failure — report it and stop. The RDR acceptance is still valid. To retry the planning chain only, run `/nx:create-plan` manually with the RDR file path.**
246
+
247
+ **Step 8c — Dispatch plan-auditor (MANDATORY — do NOT skip):**
248
+ After the planner completes, dispatch `nx:plan-auditor` agent (via Agent tool, subagent_type="nx:plan-auditor") with prompt:
249
+ > Audit the execution plan just created for RDR-<ID>: <title>. Check T1 scratch for rdr-planning-context. Validate the plan against the codebase. Check beads created by the planner.
250
+
251
+ **Wait for the auditor to complete before proceeding. Do NOT skip this step.**
252
+
253
+ **Step 8d — Dispatch plan-enricher (MANDATORY — do NOT skip):**
254
+ After the auditor completes, dispatch `nx:plan-enricher` agent (via Agent tool, subagent_type="nx:plan-enricher") with prompt:
255
+ > Enrich all beads for RDR-<ID>: <title> with audit findings from T1 scratch. Write epic bead ID to T2.
256
+
257
+ **Wait for the enricher to complete. Do NOT skip this step.**
258
+
259
+ **Step 8e — Verify chain completion:**
260
+ Confirm all three agents ran: planner created beads, auditor validated, enricher enriched.
261
+ Print: `> RDR-<ID> accepted. Planning chain complete: planner → auditor → enricher. Use 'bd ready' to see executable tasks.`
262
+ **If any step was skipped or failed, report which step broke the chain and provide the retry command.**
@@ -46,7 +46,7 @@ T1 scratch is session-scoped. Standalone invocation only works within the same s
46
46
 
47
47
  ## Agent-Specific PRODUCE
48
48
 
49
- - **Enriched Beads**: Updated via `bd update <id> --description "..."` with execution-ready context
49
+ - **Enriched Beads**: Updated via Write tool → `bd update <id> --body-file /tmp/bead-<id>.md` with execution-ready context
50
50
  - **T2 memory**: Epic bead ID written via memory_put tool: project="{repo}_rdr", title="NNN"
51
51
  - **T1 scratch**: Enrichment summary via scratch tool: action="put", tags="enrichment-complete"
52
52
  - **Console output**: Enriched plan summary table
@@ -89,6 +89,23 @@ After creating a skill, update `nx/registry.yaml`:
89
89
 
90
90
  When adding a new skill, also add it to `nx/skills/using-nx-skills/SKILL.md` routing tree. This file is injected every session — if your skill isn't listed there, it won't be discovered.
91
91
 
92
+ ## Known Pitfalls
93
+
94
+ ### bd update --description silently corrupts multi-line content
95
+
96
+ **Never** instruct agents to use `bd update <id> --description "..."` for multi-line or markdown content. Shell escaping silently destroys backticks (executed as command substitution), `$variables` (expanded to empty), and nested quotes (break argument boundaries). No error is raised — the command reports success with mangled data.
97
+
98
+ **Correct pattern**: Write content to a temp file via the Write tool, then use `--body-file`:
99
+
100
+ ```
101
+ Step 1 — Write enriched content using the Write tool (file_path: /tmp/bead-<id>.md)
102
+ Step 2 — bd update <id> --body-file /tmp/bead-<id>.md
103
+ ```
104
+
105
+ Short single-phrase values (e.g. `--design "revised scope"`) are safe. The bug only affects multi-line content with markdown formatting.
106
+
107
+ This applies to `--description`, `--notes`, `--design`, and any flag that accepts free-text content longer than a simple phrase. Use `--body-file` or `--design-file` respectively.
108
+
92
109
  ## Quality Checklist
93
110
 
94
111
  - [ ] Frontmatter has `name`, `description`, and `effort`
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "conexus"
7
- version = "2.3.1"
7
+ version = "2.3.3"
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"
@@ -11,10 +11,14 @@ from typing import Literal
11
11
  import chromadb
12
12
  import chromadb.errors
13
13
  import httpx
14
- import voyageai
15
14
  from chromadb.errors import NotFoundError as _ChromaNotFoundError
16
15
  import structlog
17
16
 
17
+ try:
18
+ import voyageai
19
+ except Exception: # Pydantic v1 crashes on Python ≥ 3.14
20
+ voyageai = None # type: ignore[assignment]
21
+
18
22
  from nexus.config import get_credential
19
23
  from nexus.corpus import embedding_model_for_collection, index_model_for_collection
20
24
  from nexus.db.chroma_quotas import QUOTAS, QuotaValidator
@@ -92,6 +96,12 @@ class T3Database:
92
96
  return
93
97
 
94
98
  # ── Cloud mode ───────────────────────────────────────────────────
99
+ if voyageai is None:
100
+ raise ImportError(
101
+ "voyageai is required for cloud mode but failed to import "
102
+ "(likely Pydantic v1 incompatibility with Python ≥ 3.14). "
103
+ "Use local mode (NX_LOCAL_MODE=1) or downgrade to Python ≤ 3.13."
104
+ )
95
105
  self._voyage_client: voyageai.Client | None = (
96
106
  voyageai.Client(api_key=voyage_api_key, timeout=read_timeout_seconds, max_retries=3)
97
107
  if voyage_api_key else None
@@ -40,6 +40,7 @@ def _run_hook(
40
40
  env = {
41
41
  **os.environ,
42
42
  "PATH": os.environ.get("PATH", ""),
43
+ "CLAUDECODE": "", # Prevent side effects (bd remember/create) in tests
43
44
  **(env_overrides or {}),
44
45
  }
45
46
  return subprocess.run(
@@ -489,7 +489,7 @@ wheels = [
489
489
 
490
490
  [[package]]
491
491
  name = "conexus"
492
- version = "2.3.1"
492
+ version = "2.3.3"
493
493
  source = { editable = "." }
494
494
  dependencies = [
495
495
  { name = "chromadb" },