sidegraph 0.11.0__tar.gz → 0.12.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (506) hide show
  1. sidegraph-0.12.0/.github/workflows/ci.yml +336 -0
  2. {sidegraph-0.11.0 → sidegraph-0.12.0}/.pre-commit-config.yaml +10 -0
  3. {sidegraph-0.11.0 → sidegraph-0.12.0}/AGENTS.md +2 -1
  4. {sidegraph-0.11.0 → sidegraph-0.12.0}/CHANGELOG.md +219 -0
  5. {sidegraph-0.11.0 → sidegraph-0.12.0}/CLAUDE.md +4 -1
  6. {sidegraph-0.11.0 → sidegraph-0.12.0}/CONTRIBUTING.md +34 -6
  7. sidegraph-0.12.0/PKG-INFO +262 -0
  8. sidegraph-0.12.0/README.md +232 -0
  9. sidegraph-0.12.0/SECURITY.md +206 -0
  10. {sidegraph-0.11.0 → sidegraph-0.12.0}/docs/concepts/data-model.md +13 -4
  11. sidegraph-0.12.0/docs/concepts/decision-memory.md +76 -0
  12. {sidegraph-0.11.0 → sidegraph-0.12.0}/docs/concepts/retrieval.md +9 -4
  13. {sidegraph-0.11.0 → sidegraph-0.12.0}/docs/getting-started/bootstrap.md +26 -12
  14. {sidegraph-0.11.0 → sidegraph-0.12.0}/docs/getting-started/claude-code-setup.md +19 -7
  15. {sidegraph-0.11.0 → sidegraph-0.12.0}/docs/getting-started/codex-setup.md +18 -8
  16. {sidegraph-0.11.0 → sidegraph-0.12.0}/docs/getting-started/installation.md +130 -10
  17. {sidegraph-0.11.0 → sidegraph-0.12.0}/docs/getting-started/quickstart.md +8 -4
  18. {sidegraph-0.11.0 → sidegraph-0.12.0}/docs/guides/capturing-decisions.md +46 -8
  19. {sidegraph-0.11.0 → sidegraph-0.12.0}/docs/guides/naming-your-domains.md +13 -13
  20. {sidegraph-0.11.0 → sidegraph-0.12.0}/docs/guides/retrieval-in-sessions.md +4 -4
  21. {sidegraph-0.11.0 → sidegraph-0.12.0}/docs/guides/semantic-docs.md +18 -13
  22. {sidegraph-0.11.0 → sidegraph-0.12.0}/docs/guides/surviving-refactors.md +2 -2
  23. {sidegraph-0.11.0 → sidegraph-0.12.0}/docs/guides/team-workflow.md +12 -15
  24. {sidegraph-0.11.0 → sidegraph-0.12.0}/docs/guides/troubleshooting.md +70 -4
  25. {sidegraph-0.11.0 → sidegraph-0.12.0}/docs/guides/verifying-your-setup.md +9 -3
  26. {sidegraph-0.11.0 → sidegraph-0.12.0}/docs/integrations/claude-code.md +1 -1
  27. {sidegraph-0.11.0 → sidegraph-0.12.0}/docs/integrations/codex.md +15 -5
  28. {sidegraph-0.11.0 → sidegraph-0.12.0}/docs/integrations/graphify.md +8 -9
  29. sidegraph-0.12.0/docs/llms.txt +66 -0
  30. {sidegraph-0.11.0 → sidegraph-0.12.0}/docs/reference/cli.md +126 -23
  31. {sidegraph-0.11.0 → sidegraph-0.12.0}/docs/reference/configuration.md +5 -4
  32. {sidegraph-0.11.0 → sidegraph-0.12.0}/docs/reference/git-bindings.md +2 -2
  33. {sidegraph-0.11.0 → sidegraph-0.12.0}/docs/reference/hooks.md +60 -4
  34. {sidegraph-0.11.0 → sidegraph-0.12.0}/docs/reference/mcp-tools.md +350 -70
  35. {sidegraph-0.11.0 → sidegraph-0.12.0}/docs/reference/operations.md +7 -4
  36. {sidegraph-0.11.0 → sidegraph-0.12.0}/docs/reference/releasing.md +15 -9
  37. {sidegraph-0.11.0 → sidegraph-0.12.0}/docs/reference/stability.md +6 -6
  38. {sidegraph-0.11.0 → sidegraph-0.12.0}/docs/reference/store-format.md +51 -18
  39. {sidegraph-0.11.0 → sidegraph-0.12.0}/plugin/sidegraph/.claude-plugin/plugin.json +1 -1
  40. {sidegraph-0.11.0 → sidegraph-0.12.0}/plugin/sidegraph/.codex-plugin/plugin.json +1 -1
  41. {sidegraph-0.11.0 → sidegraph-0.12.0}/plugin/sidegraph/codex/hooks.json +1 -1
  42. {sidegraph-0.11.0 → sidegraph-0.12.0}/plugin/sidegraph/hooks/hooks.json +1 -1
  43. {sidegraph-0.11.0 → sidegraph-0.12.0}/plugin/sidegraph/skills/check-plan/SKILL.md +2 -1
  44. {sidegraph-0.11.0 → sidegraph-0.12.0}/plugin/sidegraph/skills/explain-why/SKILL.md +6 -2
  45. {sidegraph-0.11.0 → sidegraph-0.12.0}/plugin/sidegraph/skills/heal-anchors/SKILL.md +6 -6
  46. {sidegraph-0.11.0 → sidegraph-0.12.0}/plugin/sidegraph/skills/import-adrs/SKILL.md +7 -7
  47. {sidegraph-0.11.0 → sidegraph-0.12.0}/plugin/sidegraph/skills/manage-domains/SKILL.md +9 -6
  48. {sidegraph-0.11.0 → sidegraph-0.12.0}/plugin/sidegraph/skills/name-domains/SKILL.md +10 -6
  49. {sidegraph-0.11.0 → sidegraph-0.12.0}/plugin/sidegraph/skills/ratify-decisions/SKILL.md +10 -9
  50. {sidegraph-0.11.0 → sidegraph-0.12.0}/plugin/sidegraph/skills/record-decision/SKILL.md +3 -2
  51. {sidegraph-0.11.0 → sidegraph-0.12.0}/plugin/sidegraph/skills/record-fact/SKILL.md +2 -1
  52. {sidegraph-0.11.0 → sidegraph-0.12.0}/plugin/sidegraph/skills/setup/SKILL.md +12 -7
  53. {sidegraph-0.11.0 → sidegraph-0.12.0}/plugin/sidegraph/skills/stats/SKILL.md +4 -5
  54. {sidegraph-0.11.0 → sidegraph-0.12.0}/plugin/sidegraph/skills/triage-drift/SKILL.md +5 -2
  55. {sidegraph-0.11.0 → sidegraph-0.12.0}/pyproject.toml +4 -4
  56. {sidegraph-0.11.0 → sidegraph-0.12.0}/src/sidegraph/__init__.py +1 -1
  57. {sidegraph-0.11.0 → sidegraph-0.12.0}/src/sidegraph/bash_paths.py +2 -1
  58. {sidegraph-0.11.0 → sidegraph-0.12.0}/src/sidegraph/bootstrap/review.py +9 -2
  59. {sidegraph-0.11.0 → sidegraph-0.12.0}/src/sidegraph/bootstrap/scan.py +72 -8
  60. {sidegraph-0.11.0 → sidegraph-0.12.0}/src/sidegraph/capture.py +367 -125
  61. {sidegraph-0.11.0 → sidegraph-0.12.0}/src/sidegraph/cli.py +43 -8
  62. {sidegraph-0.11.0 → sidegraph-0.12.0}/src/sidegraph/config.py +37 -0
  63. {sidegraph-0.11.0 → sidegraph-0.12.0}/src/sidegraph/doc_import.py +53 -16
  64. {sidegraph-0.11.0 → sidegraph-0.12.0}/src/sidegraph/doctor.py +15 -2
  65. {sidegraph-0.11.0 → sidegraph-0.12.0}/src/sidegraph/engine/reader.py +7 -4
  66. {sidegraph-0.11.0 → sidegraph-0.12.0}/src/sidegraph/host/claude_settings.py +17 -4
  67. {sidegraph-0.11.0 → sidegraph-0.12.0}/src/sidegraph/host/hooks.py +234 -44
  68. sidegraph-0.12.0/src/sidegraph/host/mcp_entry.py +85 -0
  69. sidegraph-0.12.0/src/sidegraph/host/session_identity.py +69 -0
  70. {sidegraph-0.11.0 → sidegraph-0.12.0}/src/sidegraph/hot_index.py +84 -14
  71. sidegraph-0.12.0/src/sidegraph/input_limits.py +215 -0
  72. {sidegraph-0.11.0 → sidegraph-0.12.0}/src/sidegraph/integrity.py +7 -1
  73. {sidegraph-0.11.0 → sidegraph-0.12.0}/src/sidegraph/nearest_anchored.py +88 -22
  74. sidegraph-0.12.0/src/sidegraph/redaction_scan.py +326 -0
  75. sidegraph-0.12.0/src/sidegraph/redaction_tokens.py +117 -0
  76. {sidegraph-0.11.0 → sidegraph-0.12.0}/src/sidegraph/retrieval.py +34 -13
  77. {sidegraph-0.11.0 → sidegraph-0.12.0}/src/sidegraph/seed_ladder.py +105 -21
  78. {sidegraph-0.11.0 → sidegraph-0.12.0}/src/sidegraph/server.py +1667 -390
  79. {sidegraph-0.11.0 → sidegraph-0.12.0}/src/sidegraph/stats/model.py +46 -10
  80. {sidegraph-0.11.0 → sidegraph-0.12.0}/src/sidegraph/stats/render.py +28 -5
  81. {sidegraph-0.11.0 → sidegraph-0.12.0}/src/sidegraph/store.py +70 -71
  82. {sidegraph-0.11.0 → sidegraph-0.12.0}/src/sidegraph/text_paths.py +3 -1
  83. sidegraph-0.12.0/src/sidegraph/tool_rate_limit.py +50 -0
  84. sidegraph-0.12.0/src/sidegraph/validation_errors.py +164 -0
  85. {sidegraph-0.11.0 → sidegraph-0.12.0}/src/sidegraph/verify.py +141 -33
  86. sidegraph-0.12.0/src/sidegraph/worktree_seeds.py +140 -0
  87. sidegraph-0.12.0/src/sidegraph/write_boundary.py +144 -0
  88. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/conftest.py +57 -1
  89. sidegraph-0.12.0/tests/test_batch_panel_fixes.py +621 -0
  90. sidegraph-0.12.0/tests/test_bootstrap_descriptor_cleanup.py +79 -0
  91. sidegraph-0.12.0/tests/test_bootstrap_scan_regular.py +565 -0
  92. sidegraph-0.12.0/tests/test_bounded_listings.py +1058 -0
  93. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/test_capture_facts.py +10 -5
  94. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/test_capture_propose.py +188 -18
  95. sidegraph-0.12.0/tests/test_capture_redact.py +469 -0
  96. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/test_cli_doctor.py +39 -2
  97. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/test_cli_import.py +40 -0
  98. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/test_coverage_telemetry_e2e.py +6 -2
  99. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/test_doc_import.py +69 -1
  100. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/test_docs_claims.py +124 -4
  101. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/test_doctor.py +65 -0
  102. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/test_doctor_integrity.py +8 -2
  103. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/test_domains.py +1 -1
  104. sidegraph-0.12.0/tests/test_hook_showings.py +324 -0
  105. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/test_host_pretool_records.py +2 -2
  106. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/test_host_wiring_checks.py +230 -0
  107. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/test_hot_index.py +8 -2
  108. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/test_hot_index_hook.py +2 -2
  109. sidegraph-0.12.0/tests/test_installed_wheel_smoke.py +487 -0
  110. sidegraph-0.12.0/tests/test_portable_json.py +112 -0
  111. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/test_public_hook_launch.py +83 -0
  112. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/test_ratify_policy.py +47 -20
  113. sidegraph-0.12.0/tests/test_redaction_scan.py +225 -0
  114. sidegraph-0.12.0/tests/test_redaction_tokens.py +223 -0
  115. sidegraph-0.12.0/tests/test_repo_relative_paths_portable.py +325 -0
  116. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/test_retrieval_drilldown.py +2 -2
  117. sidegraph-0.12.0/tests/test_secret_scan_gate.py +223 -0
  118. sidegraph-0.12.0/tests/test_security_binary_limits.py +53 -0
  119. sidegraph-0.12.0/tests/test_security_capture_diagnostics.py +225 -0
  120. sidegraph-0.12.0/tests/test_security_capture_limits.py +132 -0
  121. sidegraph-0.12.0/tests/test_security_cli_diagnostics.py +69 -0
  122. sidegraph-0.12.0/tests/test_security_doc_limits.py +134 -0
  123. sidegraph-0.12.0/tests/test_security_input_limits.py +291 -0
  124. sidegraph-0.12.0/tests/test_security_mcp_write_diagnostics.py +240 -0
  125. sidegraph-0.12.0/tests/test_security_numeric_enums.py +154 -0
  126. sidegraph-0.12.0/tests/test_security_python_shapes.py +234 -0
  127. sidegraph-0.12.0/tests/test_security_redaction_cursor.py +37 -0
  128. sidegraph-0.12.0/tests/test_security_redaction_scaling.py +79 -0
  129. sidegraph-0.12.0/tests/test_security_validation_errors.py +106 -0
  130. sidegraph-0.12.0/tests/test_security_write_boundary.py +291 -0
  131. sidegraph-0.12.0/tests/test_seed_paths_portable.py +163 -0
  132. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/test_server_add_anchors.py +1 -1
  133. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/test_server_argument_names.py +6 -6
  134. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/test_server_borrowed_graph.py +1 -1
  135. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/test_server_capture.py +14 -6
  136. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/test_server_commit_hint.py +1 -3
  137. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/test_server_coverage_events.py +46 -29
  138. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/test_server_decision_listing.py +16 -12
  139. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/test_server_facts.py +22 -10
  140. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/test_server_graph_freshness.py +8 -12
  141. sidegraph-0.12.0/tests/test_server_invocation_policy.py +138 -0
  142. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/test_server_mcp_smoke.py +46 -34
  143. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/test_server_redaction.py +37 -0
  144. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/test_server_render_events.py +8 -7
  145. sidegraph-0.12.0/tests/test_server_result_contract.py +139 -0
  146. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/test_server_supersede.py +8 -4
  147. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/test_server_telemetry.py +8 -5
  148. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/test_server_tolerant_seeds.py +3 -1
  149. sidegraph-0.12.0/tests/test_session_attribution.py +614 -0
  150. sidegraph-0.12.0/tests/test_skill_frontmatter.py +39 -0
  151. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/test_stats_model.py +149 -4
  152. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/test_stats_render.py +47 -1
  153. sidegraph-0.12.0/tests/test_store_cross_process_mutations.py +275 -0
  154. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/test_store_mutation_immediate.py +4 -4
  155. sidegraph-0.12.0/tests/test_verify_git_framing.py +349 -0
  156. sidegraph-0.12.0/tests/test_verify_git_revisions.py +327 -0
  157. sidegraph-0.12.0/tests/test_verify_git_stdin.py +88 -0
  158. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/test_verify_snapshot.py +24 -0
  159. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/test_verify_transitions.py +336 -0
  160. sidegraph-0.12.0/tests/test_worktree_seeds.py +651 -0
  161. sidegraph-0.12.0/tests/wheel_server_trace.py +114 -0
  162. sidegraph-0.12.0/tests/wheel_smoke.py +419 -0
  163. {sidegraph-0.11.0 → sidegraph-0.12.0}/uv.lock +3 -3
  164. sidegraph-0.11.0/.github/workflows/ci.yml +0 -143
  165. sidegraph-0.11.0/PKG-INFO +0 -306
  166. sidegraph-0.11.0/README.md +0 -276
  167. sidegraph-0.11.0/SECURITY.md +0 -59
  168. sidegraph-0.11.0/docs/concepts/decision-memory.md +0 -79
  169. sidegraph-0.11.0/docs/llms.txt +0 -64
  170. sidegraph-0.11.0/tests/test_capture_redact.py +0 -184
  171. {sidegraph-0.11.0 → sidegraph-0.12.0}/.agents/plugins/marketplace.json +0 -0
  172. {sidegraph-0.11.0 → sidegraph-0.12.0}/.claude-plugin/marketplace.json +0 -0
  173. {sidegraph-0.11.0 → sidegraph-0.12.0}/.github/CODEOWNERS +0 -0
  174. {sidegraph-0.11.0 → sidegraph-0.12.0}/.github/ISSUE_TEMPLATE/bug_report.yml +0 -0
  175. {sidegraph-0.11.0 → sidegraph-0.12.0}/.github/ISSUE_TEMPLATE/config.yml +0 -0
  176. {sidegraph-0.11.0 → sidegraph-0.12.0}/.github/ISSUE_TEMPLATE/feature_request.yml +0 -0
  177. {sidegraph-0.11.0 → sidegraph-0.12.0}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
  178. {sidegraph-0.11.0 → sidegraph-0.12.0}/.github/secret_scanning.yml +0 -0
  179. {sidegraph-0.11.0 → sidegraph-0.12.0}/.github/workflows/publish.yml +0 -0
  180. {sidegraph-0.11.0 → sidegraph-0.12.0}/.github/workflows/scorecard.yml +0 -0
  181. {sidegraph-0.11.0 → sidegraph-0.12.0}/.github/workflows/session-link-gate.yml +0 -0
  182. {sidegraph-0.11.0 → sidegraph-0.12.0}/.gitignore +0 -0
  183. {sidegraph-0.11.0 → sidegraph-0.12.0}/.gitleaks.toml +0 -0
  184. {sidegraph-0.11.0 → sidegraph-0.12.0}/.python-version +0 -0
  185. {sidegraph-0.11.0 → sidegraph-0.12.0}/CODE_OF_CONDUCT.md +0 -0
  186. {sidegraph-0.11.0 → sidegraph-0.12.0}/LICENSE +0 -0
  187. {sidegraph-0.11.0 → sidegraph-0.12.0}/docs/README.md +0 -0
  188. {sidegraph-0.11.0 → sidegraph-0.12.0}/docs/concepts/anchoring.md +0 -0
  189. {sidegraph-0.11.0 → sidegraph-0.12.0}/docs/concepts/mind-model.md +0 -0
  190. {sidegraph-0.11.0 → sidegraph-0.12.0}/docs/guides/ci-cd-maintenance.md +0 -0
  191. {sidegraph-0.11.0 → sidegraph-0.12.0}/docs/pilot-kit/README.md +0 -0
  192. {sidegraph-0.11.0 → sidegraph-0.12.0}/docs/pilot-kit/corpus_fit.py +0 -0
  193. {sidegraph-0.11.0 → sidegraph-0.12.0}/docs/pilot-kit/judge-prompt.md +0 -0
  194. {sidegraph-0.11.0 → sidegraph-0.12.0}/docs/pilot-kit/questions-prompt.md +0 -0
  195. {sidegraph-0.11.0 → sidegraph-0.12.0}/docs/pilot-kit/rubric-template.md +0 -0
  196. {sidegraph-0.11.0 → sidegraph-0.12.0}/docs/whitepaper/index.md +0 -0
  197. {sidegraph-0.11.0 → sidegraph-0.12.0}/plugin/sidegraph/.mcp.json +0 -0
  198. {sidegraph-0.11.0 → sidegraph-0.12.0}/plugin/sidegraph/codex/mcp.json +0 -0
  199. {sidegraph-0.11.0 → sidegraph-0.12.0}/plugin/sidegraph/skills/check-plan/agents/openai.yaml +0 -0
  200. {sidegraph-0.11.0 → sidegraph-0.12.0}/plugin/sidegraph/skills/explain-why/agents/openai.yaml +0 -0
  201. {sidegraph-0.11.0 → sidegraph-0.12.0}/plugin/sidegraph/skills/heal-anchors/agents/openai.yaml +0 -0
  202. {sidegraph-0.11.0 → sidegraph-0.12.0}/plugin/sidegraph/skills/import-adrs/agents/openai.yaml +0 -0
  203. {sidegraph-0.11.0 → sidegraph-0.12.0}/plugin/sidegraph/skills/manage-domains/agents/openai.yaml +0 -0
  204. {sidegraph-0.11.0 → sidegraph-0.12.0}/plugin/sidegraph/skills/name-domains/agents/openai.yaml +0 -0
  205. {sidegraph-0.11.0 → sidegraph-0.12.0}/plugin/sidegraph/skills/ratify-decisions/agents/openai.yaml +0 -0
  206. {sidegraph-0.11.0 → sidegraph-0.12.0}/plugin/sidegraph/skills/record-decision/agents/openai.yaml +0 -0
  207. {sidegraph-0.11.0 → sidegraph-0.12.0}/plugin/sidegraph/skills/record-fact/agents/openai.yaml +0 -0
  208. {sidegraph-0.11.0 → sidegraph-0.12.0}/plugin/sidegraph/skills/setup/agents/openai.yaml +0 -0
  209. {sidegraph-0.11.0 → sidegraph-0.12.0}/plugin/sidegraph/skills/stats/agents/openai.yaml +0 -0
  210. {sidegraph-0.11.0 → sidegraph-0.12.0}/plugin/sidegraph/skills/triage-drift/agents/openai.yaml +0 -0
  211. {sidegraph-0.11.0 → sidegraph-0.12.0}/src/sidegraph/anchoring.py +0 -0
  212. {sidegraph-0.11.0 → sidegraph-0.12.0}/src/sidegraph/bootstrap/__init__.py +0 -0
  213. {sidegraph-0.11.0 → sidegraph-0.12.0}/src/sidegraph/bootstrap/apply.py +0 -0
  214. {sidegraph-0.11.0 → sidegraph-0.12.0}/src/sidegraph/bootstrap/catalog.py +0 -0
  215. {sidegraph-0.11.0 → sidegraph-0.12.0}/src/sidegraph/bootstrap/cli.py +0 -0
  216. {sidegraph-0.11.0 → sidegraph-0.12.0}/src/sidegraph/bootstrap/integrations.py +0 -0
  217. {sidegraph-0.11.0 → sidegraph-0.12.0}/src/sidegraph/bootstrap/model.py +0 -0
  218. {sidegraph-0.11.0 → sidegraph-0.12.0}/src/sidegraph/bootstrap/planner.py +0 -0
  219. {sidegraph-0.11.0 → sidegraph-0.12.0}/src/sidegraph/bootstrap/proof.py +0 -0
  220. {sidegraph-0.11.0 → sidegraph-0.12.0}/src/sidegraph/domains.py +0 -0
  221. {sidegraph-0.11.0 → sidegraph-0.12.0}/src/sidegraph/engine/__init__.py +0 -0
  222. {sidegraph-0.11.0 → sidegraph-0.12.0}/src/sidegraph/freshness.py +0 -0
  223. {sidegraph-0.11.0 → sidegraph-0.12.0}/src/sidegraph/gitenv.py +0 -0
  224. {sidegraph-0.11.0 → sidegraph-0.12.0}/src/sidegraph/githooks.py +0 -0
  225. {sidegraph-0.11.0 → sidegraph-0.12.0}/src/sidegraph/gitio.py +0 -0
  226. {sidegraph-0.11.0 → sidegraph-0.12.0}/src/sidegraph/host/__init__.py +0 -0
  227. {sidegraph-0.11.0 → sidegraph-0.12.0}/src/sidegraph/host/launch.py +0 -0
  228. {sidegraph-0.11.0 → sidegraph-0.12.0}/src/sidegraph/host/subagent.py +0 -0
  229. {sidegraph-0.11.0 → sidegraph-0.12.0}/src/sidegraph/importer.py +0 -0
  230. {sidegraph-0.11.0 → sidegraph-0.12.0}/src/sidegraph/okf.py +0 -0
  231. {sidegraph-0.11.0 → sidegraph-0.12.0}/src/sidegraph/profiles.py +0 -0
  232. {sidegraph-0.11.0 → sidegraph-0.12.0}/src/sidegraph/schema.py +0 -0
  233. {sidegraph-0.11.0 → sidegraph-0.12.0}/src/sidegraph/stats/__init__.py +0 -0
  234. {sidegraph-0.11.0 → sidegraph-0.12.0}/src/sidegraph/store_layout.py +0 -0
  235. {sidegraph-0.11.0 → sidegraph-0.12.0}/src/sidegraph/sync.py +0 -0
  236. {sidegraph-0.11.0 → sidegraph-0.12.0}/src/sidegraph/viz/__init__.py +0 -0
  237. {sidegraph-0.11.0 → sidegraph-0.12.0}/src/sidegraph/viz/assets/vis-network.min.js +0 -0
  238. {sidegraph-0.11.0 → sidegraph-0.12.0}/src/sidegraph/viz/model.py +0 -0
  239. {sidegraph-0.11.0 → sidegraph-0.12.0}/src/sidegraph/viz/render.py +0 -0
  240. {sidegraph-0.11.0 → sidegraph-0.12.0}/src/sidegraph/viz/template.html +0 -0
  241. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/__init__.py +0 -0
  242. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/fixtures/auto_policy/parity_goldens.json +0 -0
  243. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/fixtures/bitfinex_slice.json +0 -0
  244. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/fixtures/bootstrap/flows/bmad/_bmad-output/planning-artifacts/architecture/cache/ARCHITECTURE-SPINE.md +0 -0
  245. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/fixtures/bootstrap/flows/generic-adr/docs/adr/001-retry.md +0 -0
  246. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/fixtures/bootstrap/flows/genkovich-sdd/docs/features/cache/adr/001.md +0 -0
  247. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/fixtures/bootstrap/flows/spec-kit/specs/cache/plan.md +0 -0
  248. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/fixtures/bootstrap/flows/superpowers/docs/superpowers/specs/2026-07-01-cache-design.md +0 -0
  249. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/fixtures/bootstrap/graph.json +0 -0
  250. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/fixtures/bootstrap/hosts/claude/.claude/settings.json +0 -0
  251. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/fixtures/bootstrap/hosts/claude/.mcp.json +0 -0
  252. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/fixtures/bootstrap/hosts/codex/.codex/config.toml +0 -0
  253. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/fixtures/bootstrap/hosts/codex/.codex/hooks/hooks.json +0 -0
  254. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/fixtures/bootstrap/scan/docs/adr/001-safe.md +0 -0
  255. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/fixtures/corpus/PUBLIC_CORPORA.txt +0 -0
  256. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/fixtures/corpus/openspec/_provenance.json +0 -0
  257. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/fixtures/corpus/openspec/graph.json +0 -0
  258. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/fixtures/corpus/self-corpus/_provenance.json +0 -0
  259. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/fixtures/corpus/self-corpus/expected/retrieval-engine-reader.md +0 -0
  260. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/fixtures/corpus/self-corpus/graph.json +0 -0
  261. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/fixtures/flows/adr/0001-use-sessions.md +0 -0
  262. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/fixtures/flows/bmad/ARCHITECTURE-SPINE.md +0 -0
  263. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/fixtures/flows/bmad/tree/_bmad-output/planning-artifacts/architecture/architecture-payments-2026-07-30/.memlog.md +0 -0
  264. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/fixtures/flows/bmad/tree/_bmad-output/planning-artifacts/architecture/architecture-payments-2026-07-30/ARCHITECTURE-SPINE.md +0 -0
  265. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/fixtures/flows/bmad/tree/_bmad-output/planning-artifacts/prds/prd-payments-2026-07-30/prd.md +0 -0
  266. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/fixtures/flows/genkovich/0001-queue-backpressure.md +0 -0
  267. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/fixtures/flows/genkovich/sad.md +0 -0
  268. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/fixtures/flows/genkovich/tree/docs/features/payments/adr/0001-queue-backpressure.md +0 -0
  269. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/fixtures/flows/genkovich/tree/docs/features/payments/sad.md +0 -0
  270. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/fixtures/flows/genkovich/tree/docs/features/payments/spec.md +0 -0
  271. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/fixtures/flows/openspec/design-empty.md +0 -0
  272. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/fixtures/flows/openspec/design-h3-split.md +0 -0
  273. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/fixtures/flows/openspec/design-with-summary.md +0 -0
  274. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/fixtures/flows/openspec/design.md +0 -0
  275. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/fixtures/flows/openspec/proposal-alternatives.md +0 -0
  276. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/fixtures/flows/openspec/proposal.md +0 -0
  277. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/fixtures/flows/openspec/tree/openspec/changes/add-thing/design.md +0 -0
  278. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/fixtures/flows/openspec/tree/openspec/changes/add-thing/proposal.md +0 -0
  279. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/fixtures/flows/openspec/tree/openspec/changes/add-thing/specs/cap/spec.md +0 -0
  280. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/fixtures/flows/openspec/tree/openspec/changes/add-thing/tasks.md +0 -0
  281. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/fixtures/flows/openspec/tree/openspec/changes/archive/2026-01-01-add-thing/design.md +0 -0
  282. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/fixtures/flows/openspec/tree/openspec/changes/archive/2026-01-01-add-thing/proposal.md +0 -0
  283. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/fixtures/flows/openspec/tree/openspec/config.yaml +0 -0
  284. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/fixtures/flows/openspec/tree/openspec/specs/cap/spec.md +0 -0
  285. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/fixtures/flows/spec-kit/plan.md +0 -0
  286. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/fixtures/flows/spec-kit/tree/specs/003-payment-retries/plan.md +0 -0
  287. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/fixtures/flows/spec-kit/tree/specs/003-payment-retries/spec.md +0 -0
  288. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/fixtures/flows/superpowers/2026-07-01-example-design.md +0 -0
  289. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/fixtures/flows/superpowers/2026-07-01-thin-design.md +0 -0
  290. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/fixtures/member_names_python_graph.json +0 -0
  291. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/fixtures/member_names_swift_graph.json +0 -0
  292. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/fixtures/mini_graph.json +0 -0
  293. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/githooks_support.py +0 -0
  294. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/test_agent_brief_manifests.py +0 -0
  295. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/test_anchoring.py +0 -0
  296. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/test_anchoring_mapping_refresh.py +0 -0
  297. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/test_bash_paths.py +0 -0
  298. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/test_bootstrap_apply.py +0 -0
  299. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/test_bootstrap_catalog.py +0 -0
  300. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/test_bootstrap_cli.py +0 -0
  301. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/test_bootstrap_integrations.py +0 -0
  302. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/test_bootstrap_model.py +0 -0
  303. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/test_bootstrap_planner.py +0 -0
  304. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/test_bootstrap_proof.py +0 -0
  305. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/test_bootstrap_review.py +0 -0
  306. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/test_bootstrap_scan.py +0 -0
  307. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/test_bootstrap_unanchored.py +0 -0
  308. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/test_capture_auto_accept.py +0 -0
  309. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/test_capture_initiative.py +0 -0
  310. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/test_capture_integration.py +0 -0
  311. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/test_capture_neighbors.py +0 -0
  312. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/test_cli_compact.py +0 -0
  313. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/test_cli_domains.py +0 -0
  314. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/test_cli_graph_paths.py +0 -0
  315. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/test_cli_init.py +0 -0
  316. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/test_cli_init_hooks.py +0 -0
  317. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/test_cli_okf.py +0 -0
  318. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/test_cli_ratify.py +0 -0
  319. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/test_cli_ratify_facts.py +0 -0
  320. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/test_cli_stats.py +0 -0
  321. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/test_cli_sync.py +0 -0
  322. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/test_cli_sync_check.py +0 -0
  323. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/test_cli_unreadable_paths.py +0 -0
  324. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/test_cli_viz.py +0 -0
  325. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/test_codex_plugin.py +0 -0
  326. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/test_community_baseline.py +0 -0
  327. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/test_config.py +0 -0
  328. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/test_config_ancestor_lookup.py +0 -0
  329. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/test_config_borrowed_graph.py +0 -0
  330. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/test_corpus_expected_renders.py +0 -0
  331. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/test_corpus_self_corpus.py +0 -0
  332. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/test_digest_integrity.py +0 -0
  333. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/test_doc_corpus_integration.py +0 -0
  334. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/test_doctor_auto_share.py +0 -0
  335. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/test_doctor_code_drift.py +0 -0
  336. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/test_doctor_dangling_supports.py +0 -0
  337. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/test_doctor_duplicate_entity.py +0 -0
  338. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/test_doctor_graph_root_mismatch.py +0 -0
  339. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/test_doctor_graph_stale.py +0 -0
  340. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/test_doctor_never_surfaced.py +0 -0
  341. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/test_doctor_scan.py +0 -0
  342. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/test_doctor_stale_instructions.py +0 -0
  343. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/test_doctor_unhashable_payload.py +0 -0
  344. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/test_doctor_unratified_accept.py +0 -0
  345. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/test_entity_duplicate_resolution.py +0 -0
  346. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/test_entity_get_or_create_race.py +0 -0
  347. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/test_entry_point_arguments.py +0 -0
  348. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/test_env_isolation.py +0 -0
  349. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/test_fact_reachability_gate.py +0 -0
  350. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/test_flow_profile.py +0 -0
  351. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/test_git_bindings_blame.py +0 -0
  352. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/test_git_bindings_hook.py +0 -0
  353. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/test_git_bindings_provenance.py +0 -0
  354. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/test_git_config_isolation.py +0 -0
  355. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/test_git_env.py +0 -0
  356. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/test_githooks.py +0 -0
  357. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/test_graph_freshness.py +0 -0
  358. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/test_hook_spawn_guard.py +0 -0
  359. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/test_host_agent_brief.py +0 -0
  360. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/test_host_agent_state.py +0 -0
  361. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/test_host_borrowed_graph.py +0 -0
  362. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/test_host_claude_settings.py +0 -0
  363. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/test_host_drift_nudge.py +0 -0
  364. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/test_host_integrity.py +0 -0
  365. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/test_host_launch.py +0 -0
  366. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/test_host_pretool.py +0 -0
  367. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/test_host_session_key.py +0 -0
  368. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/test_host_session_start.py +0 -0
  369. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/test_host_session_start_concurrent.py +0 -0
  370. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/test_host_stop.py +0 -0
  371. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/test_host_subagent_start.py +0 -0
  372. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/test_host_subdirectory_launch.py +0 -0
  373. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/test_host_touch_events.py +0 -0
  374. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/test_hot_path_imports.py +0 -0
  375. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/test_import_dry_run_preview.py +0 -0
  376. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/test_importer.py +0 -0
  377. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/test_index_journal_mode.py +0 -0
  378. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/test_integrity.py +0 -0
  379. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/test_integrity_refresh_hook.py +0 -0
  380. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/test_integrity_replay.py +0 -0
  381. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/test_integrity_stranded.py +0 -0
  382. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/test_lazy_root.py +0 -0
  383. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/test_member_anchor_wiring.py +0 -0
  384. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/test_mind_model_additive_fields.py +0 -0
  385. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/test_nearest_anchored.py +0 -0
  386. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/test_okf.py +0 -0
  387. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/test_openspec_profile.py +0 -0
  388. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/test_pathless_descriptor_adoption.py +0 -0
  389. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/test_pilot_kit_corpus_fit.py +0 -0
  390. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/test_proposal_lifecycle.py +0 -0
  391. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/test_ratify_listing_gone_dark.py +0 -0
  392. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/test_reader_community_labels.py +0 -0
  393. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/test_reader_doc_nodes.py +0 -0
  394. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/test_reader_graph.py +0 -0
  395. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/test_reader_integration.py +0 -0
  396. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/test_reader_member_name_lookup.py +0 -0
  397. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/test_reader_member_names.py +0 -0
  398. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/test_reader_nodes_in_file.py +0 -0
  399. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/test_reader_perf.py +0 -0
  400. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/test_reader_rationale.py +0 -0
  401. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/test_reader_read.py +0 -0
  402. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/test_reader_resolve.py +0 -0
  403. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/test_reader_subdir_mismatch.py +0 -0
  404. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/test_reader_version.py +0 -0
  405. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/test_redaction_seeded.py +0 -0
  406. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/test_repoint_integration.py +0 -0
  407. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/test_retrieval_budget_counters.py +0 -0
  408. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/test_retrieval_context.py +0 -0
  409. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/test_retrieval_drift_marker.py +0 -0
  410. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/test_retrieval_facts.py +0 -0
  411. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/test_retrieval_guessed.py +0 -0
  412. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/test_retrieval_ids.py +0 -0
  413. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/test_retrieval_integration.py +0 -0
  414. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/test_retrieval_rank.py +0 -0
  415. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/test_retrieval_seeds.py +0 -0
  416. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/test_retrieval_shown_ids.py +0 -0
  417. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/test_retrieval_terminal_evidence.py +0 -0
  418. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/test_retrieval_thin_tools.py +0 -0
  419. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/test_retrieval_toc.py +0 -0
  420. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/test_retrieval_toptier.py +0 -0
  421. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/test_retrieval_unratified.py +0 -0
  422. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/test_sandbox_hygiene.py +0 -0
  423. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/test_schema_descriptor.py +0 -0
  424. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/test_schema_domain.py +0 -0
  425. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/test_schema_fact.py +0 -0
  426. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/test_seed_ladder.py +0 -0
  427. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/test_server_anchoring.py +0 -0
  428. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/test_server_annotations.py +0 -0
  429. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/test_server_domains.py +0 -0
  430. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/test_server_drilldown.py +0 -0
  431. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/test_server_find_entity.py +0 -0
  432. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/test_server_get_store.py +0 -0
  433. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/test_server_get_task_context.py +0 -0
  434. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/test_server_graph_path.py +0 -0
  435. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/test_server_import.py +0 -0
  436. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/test_server_nearest_anchored.py +0 -0
  437. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/test_server_prewrite_anchor_validation.py +0 -0
  438. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/test_server_ratify_facts.py +0 -0
  439. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/test_server_record_types.py +0 -0
  440. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/test_server_refresh.py +0 -0
  441. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/test_server_sync_anchors.py +0 -0
  442. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/test_server_thin_tools.py +0 -0
  443. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/test_server_verify.py +0 -0
  444. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/test_stats_graph.py +0 -0
  445. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/test_stats_health.py +0 -0
  446. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/test_stats_skill.py +0 -0
  447. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/test_stats_snapshot.py +0 -0
  448. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/test_stop_hot_path.py +0 -0
  449. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/test_stop_rearm.py +0 -0
  450. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/test_store.py +0 -0
  451. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/test_store_agent_state.py +0 -0
  452. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/test_store_atomic_write_tmp_names.py +0 -0
  453. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/test_store_bad_file.py +0 -0
  454. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/test_store_binding_index.py +0 -0
  455. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/test_store_canonical_stat.py +0 -0
  456. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/test_store_compact.py +0 -0
  457. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/test_store_compact_review.py +0 -0
  458. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/test_store_concurrent_open.py +0 -0
  459. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/test_store_coverage_telemetry.py +0 -0
  460. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/test_store_derived_community.py +0 -0
  461. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/test_store_domains.py +0 -0
  462. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/test_store_entities.py +0 -0
  463. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/test_store_fact_cascade.py +0 -0
  464. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/test_store_facts.py +0 -0
  465. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/test_store_git_root_symlink.py +0 -0
  466. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/test_store_meta.py +0 -0
  467. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/test_store_migration.py +0 -0
  468. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/test_store_mutation_guard.py +0 -0
  469. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/test_store_non_file_entries.py +0 -0
  470. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/test_store_opens_with_merged_duplicate.py +0 -0
  471. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/test_store_persistence.py +0 -0
  472. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/test_store_ratification.py +0 -0
  473. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/test_store_rebuild_atomicity.py +0 -0
  474. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/test_store_record_identity.py +0 -0
  475. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/test_store_record_types.py +0 -0
  476. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/test_store_render_events.py +0 -0
  477. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/test_store_retrieval.py +0 -0
  478. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/test_store_slug_conflicts.py +0 -0
  479. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/test_store_stamping_marker.py +0 -0
  480. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/test_store_symlinks.py +0 -0
  481. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/test_store_telemetry.py +0 -0
  482. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/test_store_threading.py +0 -0
  483. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/test_store_tmp_sweep_age.py +0 -0
  484. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/test_store_update_meta_if.py +0 -0
  485. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/test_subagent_start_manifests.py +0 -0
  486. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/test_sync_canonical_writes.py +0 -0
  487. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/test_sync_clean.py +0 -0
  488. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/test_sync_domains.py +0 -0
  489. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/test_sync_drift_cache.py +0 -0
  490. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/test_sync_fresh_clone.py +0 -0
  491. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/test_sync_integration.py +0 -0
  492. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/test_sync_moved_adoption.py +0 -0
  493. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/test_sync_rebind.py +0 -0
  494. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/test_sync_repoint.py +0 -0
  495. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/test_sync_report_has_findings.py +0 -0
  496. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/test_sync_run.py +0 -0
  497. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/test_sync_toc_cache.py +0 -0
  498. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/test_sync_volatile_heal.py +0 -0
  499. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/test_sync_wiring.py +0 -0
  500. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/test_telemetry_retention.py +0 -0
  501. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/test_text_paths.py +0 -0
  502. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/test_viz_asset_packaged.py +0 -0
  503. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/test_viz_model.py +0 -0
  504. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/test_viz_render_html.py +0 -0
  505. {sidegraph-0.11.0 → sidegraph-0.12.0}/tests/test_viz_render_json.py +0 -0
  506. {sidegraph-0.11.0 → sidegraph-0.12.0}/tools/check_no_session_links.py +0 -0
@@ -0,0 +1,336 @@
1
+ # Project lint+type+test gate. `lint` runs the SAME .pre-commit-config.yaml a developer
2
+ # runs locally, so there is one definition of lint rather than a CI copy that drifts.
3
+ # Mostly distinct from the sidegraph-recipe workflows in docs/guides/ci-cd-maintenance.md
4
+ # (recipes for USER repos consuming Sidegraph) — except `store-lint`, which is Recipe 2
5
+ # self-applied to this repo's own dogfood store (2026-08-09 maintenance retrospective,
6
+ # cadence lever): the store rides every PR, so its transition rules should gate every PR.
7
+ #
8
+ # Actions are pinned to commit SHAs (the tag comment records the version): a mutable tag
9
+ # is a supply-chain hole, and this workflow ships to the public repo by snapshot.
10
+ name: ci
11
+
12
+ on:
13
+ push:
14
+ branches: [main]
15
+ pull_request:
16
+ workflow_call: # reused as the pre-publish gate by publish.yml (tag builds)
17
+
18
+ permissions:
19
+ contents: read
20
+
21
+ jobs:
22
+ lint:
23
+ runs-on: ubuntu-latest
24
+ timeout-minutes: 15
25
+ steps:
26
+ # zizmor artipacked: this job never pushes, so the checkout's git credentials should not
27
+ # persist into the runner's git config where a later step (or an uploaded artifact) could
28
+ # leak them.
29
+ - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
30
+ with:
31
+ fetch-depth: 0 # committed-history secret scan needs every reachable commit
32
+ persist-credentials: false
33
+
34
+ - name: Install uv
35
+ uses: astral-sh/setup-uv@20cfd1bf945f4377ade1205e4dbc17946fc9a30d # v10.0.1
36
+ with:
37
+ python-version: "3.13"
38
+ enable-cache: true
39
+ cache-dependency-glob: "uv.lock"
40
+
41
+ - name: Cache pre-commit hooks
42
+ uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6
43
+ with:
44
+ path: ~/.cache/pre-commit
45
+ key: pre-commit-${{ hashFiles('.pre-commit-config.yaml') }}
46
+
47
+ - name: Install dependencies
48
+ run: uv sync --locked
49
+
50
+ - name: Run pre-commit checks
51
+ run: uv run pre-commit run --all-files
52
+
53
+ - name: Scan committed history for secrets
54
+ run: |
55
+ test "$(git rev-parse --is-shallow-repository)" = false
56
+ uv run pre-commit run gitleaks-history --hook-stage manual --all-files
57
+
58
+ - name: Exercise secret scanner integration
59
+ env:
60
+ SIDEGRAPH_SECRET_SCAN_INTEGRATION: "1"
61
+ run: |
62
+ uv run pytest tests/test_secret_scan_gate.py -q --junitxml="$RUNNER_TEMP/secret-scan.xml"
63
+ python3 - <<'PY'
64
+ import os
65
+ from pathlib import Path
66
+ from xml.etree import ElementTree
67
+
68
+ report = Path(os.environ["RUNNER_TEMP"]) / "secret-scan.xml"
69
+ suites = list(ElementTree.parse(report).getroot().iter("testsuite"))
70
+ assert sum(int(s.attrib["tests"]) for s in suites) > 0, "no scanner tests ran"
71
+ assert sum(int(s.attrib["skipped"]) for s in suites) == 0, "scanner tests skipped"
72
+ PY
73
+
74
+ test:
75
+ runs-on: ubuntu-latest
76
+ timeout-minutes: 30
77
+ strategy:
78
+ fail-fast: false
79
+ matrix:
80
+ python-version: ["3.13", "3.14"]
81
+ steps:
82
+ # zizmor artipacked: this job never pushes; do not persist git credentials past checkout.
83
+ - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
84
+ with:
85
+ persist-credentials: false
86
+
87
+ - name: Install uv
88
+ uses: astral-sh/setup-uv@20cfd1bf945f4377ade1205e4dbc17946fc9a30d # v10.0.1
89
+ with:
90
+ python-version: ${{ matrix.python-version }}
91
+ enable-cache: true
92
+ cache-dependency-glob: "uv.lock"
93
+
94
+ - name: Install dependencies
95
+ run: uv sync --locked
96
+
97
+ - name: Run tests
98
+ run: uv run pytest -q
99
+
100
+ sdk-compatibility:
101
+ runs-on: ubuntu-latest
102
+ timeout-minutes: 15
103
+ strategy:
104
+ fail-fast: false
105
+ matrix:
106
+ sdk: [minimum, latest]
107
+ steps:
108
+ - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
109
+ with:
110
+ persist-credentials: false
111
+
112
+ - name: Install uv
113
+ uses: astral-sh/setup-uv@20cfd1bf945f4377ade1205e4dbc17946fc9a30d # v10.0.1
114
+ with:
115
+ python-version: "3.13"
116
+ enable-cache: true
117
+ cache-dependency-glob: "uv.lock"
118
+
119
+ - name: Validate supported SDK bounds against installed wheel
120
+ env:
121
+ SDK_PAIR: ${{ matrix.sdk }}
122
+ run: |
123
+ uv build
124
+ wheels=(dist/sidegraph-*.whl)
125
+ test "${#wheels[@]}" -eq 1
126
+ wheel="$(realpath "${wheels[0]}")"
127
+ probe="$(realpath tests/wheel_smoke.py)"
128
+ environment="$RUNNER_TEMP/sidegraph-sdk-env"
129
+ uv venv --python 3.13 "$environment"
130
+ interpreter="$environment/bin/python"
131
+ constraints=()
132
+ if [ "$SDK_PAIR" = minimum ]; then
133
+ constraints=(fastmcp==3.4.2 mcp==1.24.0)
134
+ fi
135
+ uv pip install --python "$interpreter" "$wheel" pytest "${constraints[@]}"
136
+ mkdir -p "$RUNNER_TEMP/sdk-check"
137
+ cp -R tests "$RUNNER_TEMP/sdk-check/tests"
138
+ cd "$RUNNER_TEMP/sdk-check"
139
+ "$interpreter" -I "$probe" --wheel "$wheel" --python "$interpreter"
140
+ "$interpreter" -I -m pytest -q tests/test_server_result_contract.py \
141
+ tests/test_server_argument_names.py tests/test_security_write_boundary.py \
142
+ tests/test_security_mcp_write_diagnostics.py tests/test_server_invocation_policy.py
143
+ "$interpreter" -I -m pytest -q tests/test_session_attribution.py \
144
+ -k "not t9 and not t14_every and not t14_the_manual and not console_script_is_the_host_entry"
145
+
146
+ windows-core:
147
+ runs-on: windows-2022
148
+ timeout-minutes: 30
149
+ strategy:
150
+ fail-fast: false
151
+ matrix:
152
+ python-version: ["3.13", "3.14"]
153
+ steps:
154
+ - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
155
+ with:
156
+ persist-credentials: false
157
+
158
+ - name: Install uv
159
+ uses: astral-sh/setup-uv@20cfd1bf945f4377ade1205e4dbc17946fc9a30d # v10.0.1
160
+ with:
161
+ python-version: ${{ matrix.python-version }}
162
+ enable-cache: true
163
+ cache-dependency-glob: "uv.lock"
164
+
165
+ - name: Install dependencies
166
+ run: uv sync --locked
167
+
168
+ # Native core selection; Unix host/editor integrations remain covered on Linux.
169
+ - name: Record native environment
170
+ shell: pwsh
171
+ run: |
172
+ uv run python -c "import json,platform,importlib.metadata as m; print(json.dumps({'os':platform.system(),'python':platform.python_version(),'fastmcp':m.version('fastmcp'),'mcp':m.version('mcp')}))" > "$env:RUNNER_TEMP/windows-environment.json"
173
+ exit $LASTEXITCODE
174
+
175
+ - name: Test portable core and MCP contracts
176
+ shell: pwsh
177
+ run: |
178
+ $privateTests = @()
179
+ if (Test-Path "tools/desktop_e2e_probe.py") {
180
+ $privateTests = @("tests/test_desktop_e2e_probe.py", "tests/test_desktop_e2e_session.py")
181
+ # Later modules' tests join only when present; the snapshot excludes all of them.
182
+ foreach ($name in "appserver", "lifecycle", "preflight", "aggregate", "codex", "receipt") {
183
+ if (Test-Path "tests/test_desktop_e2e_$name.py") {
184
+ $privateTests += "tests/test_desktop_e2e_$name.py"
185
+ }
186
+ }
187
+ }
188
+ uv run pytest -q --junitxml="$env:RUNNER_TEMP/windows-core.xml" `
189
+ tests/test_store_mutation_guard.py `
190
+ tests/test_store_mutation_immediate.py tests/test_store_cross_process_mutations.py `
191
+ tests/test_portable_json.py tests/test_bootstrap_descriptor_cleanup.py `
192
+ tests/test_server_result_contract.py tests/test_server_invocation_policy.py `
193
+ tests/test_verify_git_stdin.py tests/test_seed_paths_portable.py `
194
+ tests/test_repo_relative_paths_portable.py `
195
+ $privateTests `
196
+ tests/test_installed_wheel_smoke.py
197
+ if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE }
198
+
199
+ - name: Validate installed wheel over native stdio
200
+ id: windows-wheel
201
+ shell: pwsh
202
+ env:
203
+ WHEEL_PYTHON_VERSION: ${{ matrix.python-version }}
204
+ run: |
205
+ uv build
206
+ if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE }
207
+ $wheels = @(Get-ChildItem dist/sidegraph-*.whl)
208
+ if ($wheels.Count -ne 1) { throw "Expected one wheel artifact" }
209
+ $wheel = $wheels[0].FullName
210
+ $probe = (Resolve-Path tests/wheel_smoke.py).Path
211
+ $environment = Join-Path $env:RUNNER_TEMP "sidegraph-wheel-env"
212
+ uv venv --python "$env:WHEEL_PYTHON_VERSION" "$environment"
213
+ if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE }
214
+ $interpreter = Join-Path $environment "Scripts/python.exe"
215
+ uv pip install --python "$interpreter" "$wheel"
216
+ if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE }
217
+ Set-Location "$env:RUNNER_TEMP"
218
+ & "$interpreter" -I "$probe" --wheel "$wheel" --python "$interpreter" |
219
+ Tee-Object -FilePath "$env:RUNNER_TEMP/windows-wheel.json"
220
+ exit $LASTEXITCODE
221
+
222
+ # Preserve the primary failure. Instrumentation uses new no-graph/no-repo scratch.
223
+ - name: Diagnose first installed-wheel write
224
+ if: ${{ !cancelled() && steps.windows-wheel.outcome == 'failure' }}
225
+ timeout-minutes: 2
226
+ shell: pwsh
227
+ run: |
228
+ $wheels = @(Get-ChildItem dist/sidegraph-*.whl)
229
+ if ($wheels.Count -ne 1) { throw "Expected one wheel artifact" }
230
+ $wheel = $wheels[0].FullName
231
+ $probe = (Resolve-Path tests/wheel_smoke.py).Path
232
+ $interpreter = Join-Path $env:RUNNER_TEMP "sidegraph-wheel-env/Scripts/python.exe"
233
+ Set-Location "$env:RUNNER_TEMP"
234
+ & "$interpreter" -I "$probe" --wheel "$wheel" --python "$interpreter" `
235
+ --diagnose-first-write
236
+ exit $LASTEXITCODE
237
+
238
+ - name: Sanitize test report
239
+ if: ${{ !cancelled() }}
240
+ shell: pwsh
241
+ run: |
242
+ @'
243
+ import os
244
+ from pathlib import Path
245
+ from xml.etree import ElementTree as ET
246
+ report = Path(os.environ['RUNNER_TEMP']) / 'windows-core.xml'
247
+ if report.exists():
248
+ tree = ET.parse(report)
249
+ for element in tree.getroot().iter():
250
+ if element.tag in {'failure', 'error', 'skipped', 'system-out', 'system-err'}:
251
+ element.attrib.clear()
252
+ element.text = 'Details omitted; see the CI step output.'
253
+ element.attrib.pop('file', None)
254
+ element.attrib.pop('hostname', None)
255
+ tree.write(report, encoding='utf-8', xml_declaration=True)
256
+ '@ | uv run python -
257
+ exit $LASTEXITCODE
258
+
259
+ - name: Upload bounded Windows evidence
260
+ if: ${{ !cancelled() }}
261
+ uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
262
+ with:
263
+ name: windows-core-${{ matrix.python-version }}
264
+ path: |
265
+ ${{ runner.temp }}/windows-core.xml
266
+ ${{ runner.temp }}/windows-environment.json
267
+ ${{ runner.temp }}/windows-wheel.json
268
+ if-no-files-found: warn
269
+ retention-days: 7
270
+
271
+ # Recipe 2 (docs/guides/ci-cd-maintenance.md) on our own store: catch a hand-edited or
272
+ # history-rewritten record no MCP tool would produce. Diffs against the PR's merge base
273
+ # (never a moving branch name — see the recipe for why). Skips cleanly when the checkout
274
+ # carries no store: the public snapshot ships .sidegraph only on the demo branch, and
275
+ # this workflow ships to the public repo.
276
+ store-lint:
277
+ if: github.event_name == 'pull_request'
278
+ runs-on: ubuntu-latest
279
+ timeout-minutes: 10
280
+ steps:
281
+ # zizmor artipacked: this job never pushes; do not persist git credentials past checkout.
282
+ - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
283
+ with:
284
+ fetch-depth: 0 # full history — merge-base needs it
285
+ persist-credentials: false
286
+
287
+ - name: Install uv
288
+ uses: astral-sh/setup-uv@20cfd1bf945f4377ade1205e4dbc17946fc9a30d # v10.0.1
289
+ with:
290
+ python-version: "3.13"
291
+ enable-cache: true
292
+ cache-dependency-glob: "uv.lock"
293
+
294
+ - name: sidegraph-verify --against merge-base
295
+ run: |
296
+ if [ ! -d .sidegraph ]; then
297
+ echo "no .sidegraph in this checkout — store lint not applicable"
298
+ exit 0
299
+ fi
300
+ uv sync --locked
301
+ base="$(git merge-base "origin/$GITHUB_BASE_REF" HEAD)"
302
+ uv run sidegraph-verify --against "$base" --json
303
+
304
+ # Recipe 1 self-applied: rebuild the graph from scratch and fail on attention findings
305
+ # (stale decisions, empty/overbroad domains, slug conflicts, refresh failures). A
306
+ # cache-less rebuild was verified label-identical to the local cached graph and the
307
+ # check green on it (2026-08-09 retrospective, cadence lever) — so a red here is a real
308
+ # finding, not CI-environment noise. Lone orphaned/ambiguous entities do NOT fail the
309
+ # check: multi-anchor tolerates them by design. The engine is version-pinned (engine-
310
+ # seam invariant); the sync writes only to the ephemeral checkout's .sidegraph/.
311
+ anchor-health:
312
+ if: github.event_name == 'pull_request'
313
+ runs-on: ubuntu-latest
314
+ timeout-minutes: 15
315
+ steps:
316
+ # zizmor artipacked: this job never pushes; do not persist git credentials past checkout.
317
+ - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
318
+ with:
319
+ persist-credentials: false
320
+
321
+ - name: Install uv
322
+ uses: astral-sh/setup-uv@20cfd1bf945f4377ade1205e4dbc17946fc9a30d # v10.0.1
323
+ with:
324
+ python-version: "3.13"
325
+ enable-cache: true
326
+ cache-dependency-glob: "uv.lock"
327
+
328
+ - name: Rebuild graph and run sidegraph-sync --check
329
+ run: |
330
+ if [ ! -d .sidegraph ]; then
331
+ echo "no .sidegraph in this checkout — anchor health not applicable"
332
+ exit 0
333
+ fi
334
+ uvx --from graphifyy==0.9.6 graphify update .
335
+ uv sync --locked
336
+ uv run sidegraph-sync --json --check
@@ -71,6 +71,16 @@ repos:
71
71
  rev: v8.30.1
72
72
  hooks:
73
73
  - id: gitleaks
74
+ # Filename exclusions protect immutable files from formatters, not this scanner:
75
+ # its upstream entry reads the staged Git index without filtered filenames.
76
+ always_run: true
77
+ stages: [pre-commit]
78
+ - id: gitleaks
79
+ alias: gitleaks-history
80
+ name: Detect hardcoded secrets in committed history
81
+ entry: gitleaks git --redact "--log-opts=--diff-merges=first-parent HEAD" --verbose
82
+ always_run: true
83
+ stages: [manual]
74
84
 
75
85
  # Finds GitHub Actions supply-chain/security issues (unpinned actions, script injection via
76
86
  # untrusted `${{ }}` template interpolation, excessive `permissions:`) in the workflows that
@@ -37,7 +37,8 @@ Python 3.13+; `uv`:
37
37
  - `uv run pre-commit run --all-files`: shared lint/format/type/secret-scanning gate (also
38
38
  runs `gitleaks`, `detect-private-key`, `zizmor`, `actionlint`, `check-toml`, and a
39
39
  `uv.lock`-in-sync check).
40
- - `uv run sidegraph-mcp`: stdio server; `uv build`: distributions.
40
+ - `uv run sidegraph-mcp`: stdio server; `uv build`: distributions. `python -m sidegraph.server`
41
+ runs the same server without host identity (session ids on writes stay null).
41
42
 
42
43
  Use four spaces, type hints, docstrings, snake_case functions/modules, PascalCase classes,
43
44
  and Ruff's 100-character limit. End text files with a newline.
@@ -7,6 +7,225 @@ interfaces, exactly, and what each one promises: [`docs/reference/stability.md`]
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [0.12.0] — 2026-10-12
11
+
12
+ ### Fixed
13
+
14
+ - The Codex plugin's `SessionStart` hook now starts on native Windows. Its command used POSIX
15
+ syntax (`VAR=value command`, `$(...)`) that the PowerShell Codex runs hooks in cannot parse, so
16
+ Windows sessions showed "the SessionStart hook could not start" although the entry point itself
17
+ worked when run directly. It is now wrapped in `sh -c`, like the `Stop` and `SubagentStart`
18
+ hooks, and keeps the same message if the launch fails. Codex records trust per hook definition,
19
+ so approve the changed `SessionStart` hook once in `/hooks`. On Windows the Codex hooks need
20
+ PowerShell 7: Codex runs hooks in PowerShell, and Windows PowerShell 5.1 cannot run them.
21
+ - On native Windows, `sidegraph-import` now imports the documents a profile covers: their
22
+ repo-relative paths were built with backslashes, so every in-repo document was counted as
23
+ outside the profile and nothing was imported. Record keys, anchor lookups and `provenance.ref`
24
+ now use the POSIX path Graphify's `source_file` carries, so a later re-import on another
25
+ platform does not duplicate records going forward, and a symlink that resolves outside the
26
+ repository is refused there as on other platforms. A document on another drive than the
27
+ repository no longer crashes the import. A store that already holds backslash-keyed records
28
+ from an earlier Windows `--any-doc` import gets a second, POSIX-keyed record for the same
29
+ document on re-import; supersede the old ones.
30
+ - On native Windows, records are now delivered before a Read, Edit, Write or Grep, and before a
31
+ Bash `cat`, `sed`, `grep` or `rg`, and a subagent brief's files find their records. These paths
32
+ were built with backslashes (`src\sample.py`) and never matched the POSIX paths anchors use.
33
+ Touch events and the usage statistics now record POSIX paths, and `query_decisions(files=…)`
34
+ without a graph finds the file's records. A root-level file whose name starts with `..` is no
35
+ longer mistaken for a path outside the repository. Hooks now key a Windows session by its
36
+ transcript file name, as on other platforms, instead of the whole `C:\…` path, so hook showings,
37
+ touch events and capture state join the session the MCP server attributes calls to.
38
+ - The 40,000-character hard cap on `get_task_context` and `query_decisions` now keeps its advice
39
+ blocks (how the seeds were read, what is not in the graph, the supersede hint) when a record's
40
+ text contains a `## ` line or a seed path is absurdly long, and the closing note names what was
41
+ cut. Seed paths echoed in those blocks are clipped to their head and file name. The usage
42
+ statistics count only the records left in the text after the cap, nearest-anchored records
43
+ included, and a worktree seed written as an absolute or nested path is journaled as the
44
+ repo-relative path the answer shows. A record spanning several lines is cut whole, never
45
+ without its id line, and `degraded` and `chars_used` describe the delivered text too. The
46
+ bound-record count of the nearest-anchored block reads "at least N" for a path whose bound
47
+ records include some of the nearest records shown.
48
+ - `drill_down` bounds the whole answer, not only the decisions: a domain summary, titles and member
49
+ lines too long for `budget_chars` (measured as serialized JSON, a slug included) are clipped with a
50
+ marker, and subdomains or members that do not fit are left out with `subdomains_omitted` /
51
+ `members_omitted` counts and a `hint`.
52
+ - `sidegraph-doctor` no longer crashes on an `index.db` that has `anchor_bindings` but no `meta`
53
+ table: such an index counts as having its binding statuses computed, so the checks run. Only an
54
+ unreadable index is reported as skipped.
55
+ - `sidegraph-doctor` no longer reports zero `degraded-binding`/`orphaned-binding` findings while
56
+ binding statuses are not computed for the current graph (after an index reload and before the
57
+ next `sidegraph-sync`). It lists `binding-status` among the skipped checks, and the text
58
+ line for it and `orphaned-records` no longer blames a missing `index.db`.
59
+ - `get_task_context` no longer calls a real file of a sibling linked worktree "not a
60
+ repo-relative path", guesses it to be a same-named graph file, or reads a nested worktree path
61
+ as the main checkout's file. It names the worktree and branch; a well-formed path that is a file in no checkout is "not a
62
+ file in this checkout", and only malformed paths keep the old sentence. A path with records
63
+ bound to a file the graph lacks and not shown elsewhere in the answer says so in the
64
+ nearest-anchored block, and
65
+ `retrieve_decisions(files=[...])` reads such a path exactly.
66
+ - Attribute each MCP call to its own session instead of the last `SessionStart` of any host
67
+ in the repository. A write that omits `session_id` and a retrieval-journal row now carry the
68
+ calling host's session: `CLAUDE_CODE_SESSION_ID` for Claude Code (2.1.154 or later for exact
69
+ attribution, 2.1.163 or later to keep one id across `--resume`) and the request `threadId`
70
+ for Codex. A client that names its host but no session falls back to the one fresh stamp of
71
+ the same host family, else to nothing; a retrieval that cannot be attributed is journaled as
72
+ `unattributed` and `sidegraph-stats` reports those calls instead of counting their sessions
73
+ as silent. The `sidegraph-mcp` console script moves to `sidegraph.host.mcp_entry:main`
74
+ (the command name is unchanged; `python -m sidegraph.server` still starts the server, without
75
+ host identity). Hook commands set the new `SIDEGRAPH_HOST` variable. Hand-written
76
+ SessionStart wiring should add `SIDEGRAPH_HOST=claude` or `SIDEGRAPH_HOST=codex`.
77
+ - Serialize Store state checks and publication behind a SQLite writer reservation,
78
+ including pending verdicts and server-side domain/fact preconditions. Busy admission
79
+ reports conservative inspect-before-retry guidance; file and index commits remain
80
+ separate operations.
81
+ - Read graph/label JSON and Claude settings as UTF-8 independently of the default locale;
82
+ retry incomplete graph encodings and close temporary descriptors on setup failures.
83
+ - Isolate noninteractive Git subprocess stdin from the MCP protocol pipe, resolving
84
+ native Windows first-write stalls in the installed-wheel stdio checks.
85
+ - Set MCP `isError` for complete anchor-operation failures while retaining structured
86
+ payloads and partial-batch outcomes. Unknown tool names receive bounded discovery advice.
87
+
88
+ ### Changed
89
+
90
+ - The Quickstart no longer installs the CLI for plugin users: its commands run through `uvx`,
91
+ as the plugin does. `uv tool install sidegraph` is documented as optional beside a plugin
92
+ and the usual setup without one, and its install now includes a mandatory update after every
93
+ release, `uv tool install sidegraph@latest`. The plugin's skills run every
94
+ `sidegraph-*` command at the session's version through `uvx` and never the copy on `PATH`.
95
+ - The PreToolUse hook records what it hands over as showings: each record printed in a
96
+ file-read block (`inject`) or appended to a subagent's brief (`inject_brief`) is journaled
97
+ and bumps `retrieval_shows`. `sidegraph-stats` gains a `record showings delivered by hooks`
98
+ line (`activation.hook_showings` in `--json`), and `no recorded showing` and the doctor's
99
+ `never-surfaced` check count a record the hook printed as shown. Upgrade `sidegraph-stats`
100
+ together with the plugin: an older CLI reads the new journal rows as memory lookups.
101
+ The Agent-brief path, read-only until now, writes one transaction (up to the one-second busy
102
+ timeout under a held lock; a failed write never costs the brief).
103
+ - Bound the output of five listing tools. `list_facts`, `get_entity_history`, `drill_down`,
104
+ `list_domain_candidates` and `list_proposed` now take `budget_chars` (default 24000,
105
+ maximum 40000) and say what was left out and how to narrow; `list_facts` gains `status`,
106
+ `files`, `query`, `ids` and `limit`, and `get_entity_history` gains `status` and `limit`.
107
+ Before, a store with a few hundred facts or a long-lived entity produced answers (up to
108
+ 170,000 characters) that Claude Code replaced with an "exceeds maximum allowed tokens"
109
+ notice. **Return shapes change:** `list_facts` and `get_entity_history` return a JSON
110
+ object instead of a list; `drill_down` and `list_domain_candidates` add
111
+ `hint`/`truncated`-style fields (`omitted_ids`, `omitted_by_budget`); the first four are sent
112
+ once, as text, with no `structuredContent` copy. `list_domain_candidates` shows fewer
113
+ candidates by default (the budget cuts first; narrow with `paths`; `limit=0` still lifts the
114
+ count limit). `retrieve_decisions`'s maximum `budget_chars` falls from 60000 to 40000, below
115
+ Claude Code's 50,000-character limit, and `get_task_context`, `query_structure`,
116
+ `query_decisions` and `list_proposed` never return more than 40,000 characters (a cut says
117
+ so in a closing note and keeps the advice blocks).
118
+ - Text-only MCP tools `get_task_context`, `query_structure`, `query_decisions`, and
119
+ `list_proposed` no longer advertise an output schema or duplicate text in
120
+ `structuredContent`. Machine-oriented dictionary results retain their schemas.
121
+ - Bound supported dependency majors to FastMCP 3 (`>=3.4.2`) and MCP Python SDK 1 (`>=1.24`).
122
+
123
+ ### Added
124
+
125
+ - A SessionStart advisory, `path-skew`, on macOS and Linux, when a `sidegraph-*` command on
126
+ `PATH` (outside the session's own environment) is a different version than the session, such
127
+ as a forgotten `uv tool install sidegraph`. It reads the install's dist-info and runs nothing.
128
+ - Per-process MCP tool admission: burst 200, refill 100 calls/second, immediate refusal
129
+ before tool work; initialization, ping, and discovery remain available.
130
+ - Native Windows x64 CI for Python 3.13/3.14, covering selected core/MCP contracts and
131
+ an exact installed-wheel CLI/stdio probe outside the checkout.
132
+
133
+ ### Documentation
134
+
135
+ - Reorganize the README around setup, usage, limits, and contribution paths; remove
136
+ unsupported comparisons and clarify the runtime versus host data boundary.
137
+ - Document tested platform coverage, the locked MCP protocol range, result error
138
+ handling, and recovery after a cancelled write. Align guides and reference pages
139
+ with the current release and stability policies.
140
+ - Explain Windows plugin shell/PATH requirements, WSL setup, native MCP-only limits,
141
+ and the distinction between core/wheel CI and full agent-plugin validation.
142
+
143
+ ## [0.11.1] — 2026-10-10
144
+
145
+ ### Fixed
146
+
147
+ - **Bootstrap excludes special files and validates one bounded regular descriptor.** FIFO,
148
+ sockets and devices cannot become selected text sources, including through `--include`.
149
+ Available nonblocking/no-follow flags guard final-component replacement; the opened
150
+ descriptor is rechecked before strict incremental UTF-8 validation. Directory aliases
151
+ are rechecked against exclusions. Include retains its size override but observed growth
152
+ past opened size is excluded. Later planner/apply reads and ancestor races retain their
153
+ existing scope.
154
+
155
+ - **Git verification preserves unusual filenames through binary NUL framing.** Verify and
156
+ doctor detect immutable edits and archive deletions at paths containing Unicode, TAB,
157
+ LF, CR, quotes, backslashes or surrounding whitespace. Malformed or unsupported diff
158
+ output is an operational error (exit `1`), never a partial clean report. Shared Git
159
+ callers keep their decoded-text behavior; only diff reads raw pathname bytes.
160
+
161
+ - **Git verification resolves `--against` to one protected, frozen commit ID.** Verify and
162
+ doctor reject option-shaped, empty, NUL-containing, unavailable and non-commit baselines
163
+ operationally (exit `1`). Diff and every baseline record read use the same full SHA-1 or
164
+ SHA-256 ID, so a branch moving between those operations cannot hide an immutable edit.
165
+ There is no raw-ref fallback. Current working-tree reads retain
166
+ their existing concurrency limits.
167
+
168
+ - **Malformed write diagnostics omit raw input and arbitrary failure causes.** Capture
169
+ errors use bounded schema fields/codes; logical MCP writes apply raw admission before
170
+ signature coercion and intercept exceptions before framework warning/error logging.
171
+ Unknown write arguments keep valid parameter help without echoing their names.
172
+ Unsupported registrations fail closed. Partial-write warnings and recovery guidance
173
+ remain truthful; domain/ratify causes are controlled. Read diagnostics and upstream
174
+ FastMCP DEBUG argument tracing retain their existing scope.
175
+
176
+ - **Capture and direct writes reject oversized input before redaction or canonical writes.**
177
+ Limits are 256 KiB UTF-8 per string, 4 MiB admitted strings and 65,536 admitted nodes per
178
+ request, depth 32 and 4,096 nodes per draft, and 100 agent drafts including attached facts.
179
+ Combined decisions/facts share one budget; item violations reject the containing draft,
180
+ while request-wide violations fail before any write. Documents have an independent 8 MiB
181
+ per-file limit with whole-file skips, matching real/dry reports and no total-import cap.
182
+ Import tags and free-text options are bounded separately; input is never silently truncated.
183
+ Raw Python batches use lists/tuples; supported scalar, mapping and model fields are
184
+ inspected. Other opaque Python values (including sets, deques, generators and non-string
185
+ Enum objects) are rejected before Pydantic coercion, without consuming iterators. Numeric
186
+ enums can become strings rather than behave as numbers in Pydantic string fields; only
187
+ string-derived enums keep their measured base-string behavior.
188
+ - **Redaction avoids repeated suffix searches in four known attack families.** Linear
189
+ assignment-key, URL-credential, JWT and private-key-block recognizers preserve matching
190
+ order/counts and the existing conservative quoted-value behavior. This does not claim
191
+ universal regex linearity or complete secret detection. See [security policy](SECURITY.md).
192
+
193
+ - **Secret-bearing tags are redacted before document import stores their slugs.** Capture,
194
+ direct MCP writes and document import share tag normalization. Import reports tag
195
+ substitutions once per batch in real and dry runs, including duplicate raw tags.
196
+ Comma-separated MCP strings are cleaned before splitting; a secret-bearing string with
197
+ commas drops all its tags conservatively. List input keeps explicit boundaries.
198
+
199
+ - **Quoted assignment redaction consumes multiline, triple-quoted and unterminated values.**
200
+ Escaped closers and glued tails stay covered. An unterminated value removes the
201
+ remaining input conservatively if no legal closer is found. An assignment span,
202
+ including URL/card expansion, that would swallow another assignment's key also consumes
203
+ the remaining input and following prose. A multiline quoted span splitting a URL
204
+ credential or checksum-valid grouped card number does so too. Bare values and
205
+ single-line glued tails extend through crossing URL/card matches while otherwise
206
+ preserving later prose. Prior tag entities and Git history remain: review old tags and
207
+ rotate exposed credentials. Unicode letters/digits after a single quote keep it inside
208
+ the value as an apostrophe; an unclosed value removes the remainder.
209
+
210
+ - **Secret scanning covers store-only commits and committed CI history.** The pinned
211
+ Gitleaks hook runs even when changed files are excluded from formatting. A separate manual
212
+ `gitleaks-history` hook scans committed HEAD history, also run by CI with a full checkout.
213
+ Scanner integration tests exercise staged, committed, and removed synthetic secrets.
214
+
215
+ - **Store verification checks the content of newly archived history.** A matching archive ID
216
+ alone no longer permits deletion of a committed hot decision or domain: every archive copy
217
+ must be compactable and a legal transition from the baseline, preserving raw immutable keys.
218
+ The snapshot check also reports nonterminal archive records. Legal supersede/drop followed
219
+ by compaction, older absent `null`/empty defaults, identical merge copies, and crash cleanup
220
+ still pass.
221
+
222
+ ### Changed
223
+
224
+ - **Security documentation states the limits explicitly.** The privacy overview describes
225
+ best-effort redaction and writes outside the store. CLI documentation distinguishes
226
+ argument syntax errors from rejected Git baselines and recommends JSON output when
227
+ a terminal cannot encode a reported pathname.
228
+
10
229
  ## [0.11.0] — 2026-10-09
11
230
 
12
231
  ### Changed
@@ -13,7 +13,7 @@ task-aware retrieval + decision memory riding on the engine's entity graph.
13
13
  continuing participant in the project. A core feature must preserve, organize, or deliver
14
14
  accumulated project understanding. Document search by itself is not the product.
15
15
 
16
- Sidegraph is pre-1.0 (v0.11.0) — the full loop (capture, ratification, mistakes-first
16
+ Sidegraph is pre-1.0 (v0.12.0) — the full loop (capture, ratification, mistakes-first
17
17
  retrieval, refactor-surviving re-anchoring, semantic docs layer, mind-model domains, and the
18
18
  facts evidence layer) ships and is exercised end-to-end, but interfaces may still move before
19
19
  a stable release. See
@@ -60,6 +60,8 @@ src/sidegraph/
60
60
  │ └── reader.py # GraphifyReader: reads graph.json (read-only input; no MCP)
61
61
  └── host/ # ── HOST SEAM ── Claude Code integration (SessionStart/Stop/PreToolUse/SubagentStart)
62
62
  ├── hooks.py # host-specific; portable core never reaches in here
63
+ ├── mcp_entry.py # `sidegraph-mcp` entry: server + session-binding middleware
64
+ ├── session_identity.py # Claude/Codex session id from clientInfo, env, _meta
63
65
  └── subagent.py # SubagentStart: the memory brief for a starting subagent
64
66
  ```
65
67
 
@@ -103,6 +105,7 @@ uv run pytest -m "not slow" # broader pre-push check: skips subprocess-h
103
105
  uv run pytest # full suite: once before a commit or PR (CI runs it again)
104
106
  uv run pre-commit run --all-files # lint + format + types, exactly what CI runs
105
107
  uv run sidegraph-mcp # run the decision MCP server (stdio)
108
+ # (`python -m sidegraph.server`: same server, no host identity)
106
109
  ```
107
110
 
108
111
  ## Working agreements