sidegraph 0.1.0__tar.gz → 0.2.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 (350) hide show
  1. {sidegraph-0.1.0 → sidegraph-0.2.0}/.github/PULL_REQUEST_TEMPLATE.md +2 -0
  2. sidegraph-0.2.0/.github/secret_scanning.yml +21 -0
  3. {sidegraph-0.1.0 → sidegraph-0.2.0}/.github/workflows/ci.yml +39 -0
  4. {sidegraph-0.1.0 → sidegraph-0.2.0}/.pre-commit-config.yaml +24 -0
  5. {sidegraph-0.1.0 → sidegraph-0.2.0}/AGENTS.md +4 -0
  6. {sidegraph-0.1.0 → sidegraph-0.2.0}/CHANGELOG.md +60 -0
  7. {sidegraph-0.1.0 → sidegraph-0.2.0}/CLAUDE.md +1 -1
  8. {sidegraph-0.1.0 → sidegraph-0.2.0}/CONTRIBUTING.md +8 -0
  9. {sidegraph-0.1.0 → sidegraph-0.2.0}/PKG-INFO +24 -24
  10. {sidegraph-0.1.0 → sidegraph-0.2.0}/README.md +23 -23
  11. {sidegraph-0.1.0 → sidegraph-0.2.0}/docs/getting-started/codex-setup.md +8 -0
  12. {sidegraph-0.1.0 → sidegraph-0.2.0}/docs/guides/capturing-decisions.md +8 -2
  13. {sidegraph-0.1.0 → sidegraph-0.2.0}/docs/guides/surviving-refactors.md +22 -4
  14. {sidegraph-0.1.0 → sidegraph-0.2.0}/docs/integrations/codex.md +35 -5
  15. {sidegraph-0.1.0 → sidegraph-0.2.0}/docs/reference/cli.md +44 -7
  16. {sidegraph-0.1.0 → sidegraph-0.2.0}/docs/reference/configuration.md +3 -2
  17. {sidegraph-0.1.0 → sidegraph-0.2.0}/docs/reference/mcp-tools.md +12 -4
  18. {sidegraph-0.1.0 → sidegraph-0.2.0}/docs/reference/releasing.md +5 -1
  19. {sidegraph-0.1.0 → sidegraph-0.2.0}/docs/reference/stability.md +2 -2
  20. {sidegraph-0.1.0 → sidegraph-0.2.0}/plugin/sidegraph/.claude-plugin/plugin.json +1 -1
  21. {sidegraph-0.1.0 → sidegraph-0.2.0}/plugin/sidegraph/.codex-plugin/plugin.json +1 -1
  22. {sidegraph-0.1.0 → sidegraph-0.2.0}/pyproject.toml +1 -1
  23. {sidegraph-0.1.0 → sidegraph-0.2.0}/src/sidegraph/__init__.py +1 -1
  24. {sidegraph-0.1.0 → sidegraph-0.2.0}/src/sidegraph/cli.py +147 -2
  25. {sidegraph-0.1.0 → sidegraph-0.2.0}/src/sidegraph/doctor.py +55 -4
  26. {sidegraph-0.1.0 → sidegraph-0.2.0}/src/sidegraph/engine/reader.py +105 -0
  27. sidegraph-0.2.0/src/sidegraph/host/claude_settings.py +130 -0
  28. {sidegraph-0.1.0 → sidegraph-0.2.0}/src/sidegraph/server.py +8 -3
  29. {sidegraph-0.1.0 → sidegraph-0.2.0}/src/sidegraph/sync.py +108 -18
  30. sidegraph-0.2.0/tests/conftest.py +58 -0
  31. {sidegraph-0.1.0 → sidegraph-0.2.0}/tests/test_cli_doctor.py +41 -0
  32. sidegraph-0.2.0/tests/test_cli_init.py +399 -0
  33. {sidegraph-0.1.0 → sidegraph-0.2.0}/tests/test_cli_sync.py +9 -3
  34. sidegraph-0.2.0/tests/test_doctor_graph_root_mismatch.py +84 -0
  35. sidegraph-0.2.0/tests/test_env_isolation.py +64 -0
  36. sidegraph-0.2.0/tests/test_host_claude_settings.py +141 -0
  37. sidegraph-0.2.0/tests/test_reader_subdir_mismatch.py +144 -0
  38. {sidegraph-0.1.0 → sidegraph-0.2.0}/tests/test_sync_clean.py +15 -3
  39. {sidegraph-0.1.0 → sidegraph-0.2.0}/tests/test_sync_integration.py +10 -5
  40. {sidegraph-0.1.0 → sidegraph-0.2.0}/tests/test_sync_rebind.py +163 -8
  41. {sidegraph-0.1.0 → sidegraph-0.2.0}/tests/test_sync_run.py +9 -4
  42. {sidegraph-0.1.0 → sidegraph-0.2.0}/uv.lock +1 -1
  43. sidegraph-0.1.0/tests/test_cli_init.py +0 -192
  44. {sidegraph-0.1.0 → sidegraph-0.2.0}/.agents/plugins/marketplace.json +0 -0
  45. {sidegraph-0.1.0 → sidegraph-0.2.0}/.claude-plugin/marketplace.json +0 -0
  46. {sidegraph-0.1.0 → sidegraph-0.2.0}/.github/CODEOWNERS +0 -0
  47. {sidegraph-0.1.0 → sidegraph-0.2.0}/.github/ISSUE_TEMPLATE/bug_report.yml +0 -0
  48. {sidegraph-0.1.0 → sidegraph-0.2.0}/.github/ISSUE_TEMPLATE/config.yml +0 -0
  49. {sidegraph-0.1.0 → sidegraph-0.2.0}/.github/ISSUE_TEMPLATE/feature_request.yml +0 -0
  50. {sidegraph-0.1.0 → sidegraph-0.2.0}/.github/workflows/publish.yml +0 -0
  51. {sidegraph-0.1.0 → sidegraph-0.2.0}/.github/workflows/scorecard.yml +0 -0
  52. {sidegraph-0.1.0 → sidegraph-0.2.0}/.gitignore +0 -0
  53. {sidegraph-0.1.0 → sidegraph-0.2.0}/.gitleaks.toml +0 -0
  54. {sidegraph-0.1.0 → sidegraph-0.2.0}/.python-version +0 -0
  55. {sidegraph-0.1.0 → sidegraph-0.2.0}/CODE_OF_CONDUCT.md +0 -0
  56. {sidegraph-0.1.0 → sidegraph-0.2.0}/LICENSE +0 -0
  57. {sidegraph-0.1.0 → sidegraph-0.2.0}/SECURITY.md +0 -0
  58. {sidegraph-0.1.0 → sidegraph-0.2.0}/docs/README.md +0 -0
  59. {sidegraph-0.1.0 → sidegraph-0.2.0}/docs/concepts/anchoring.md +0 -0
  60. {sidegraph-0.1.0 → sidegraph-0.2.0}/docs/concepts/data-model.md +0 -0
  61. {sidegraph-0.1.0 → sidegraph-0.2.0}/docs/concepts/decision-memory.md +0 -0
  62. {sidegraph-0.1.0 → sidegraph-0.2.0}/docs/concepts/mind-model.md +0 -0
  63. {sidegraph-0.1.0 → sidegraph-0.2.0}/docs/concepts/retrieval.md +0 -0
  64. {sidegraph-0.1.0 → sidegraph-0.2.0}/docs/getting-started/bootstrap.md +0 -0
  65. {sidegraph-0.1.0 → sidegraph-0.2.0}/docs/getting-started/claude-code-setup.md +0 -0
  66. {sidegraph-0.1.0 → sidegraph-0.2.0}/docs/getting-started/installation.md +0 -0
  67. {sidegraph-0.1.0 → sidegraph-0.2.0}/docs/getting-started/quickstart.md +0 -0
  68. {sidegraph-0.1.0 → sidegraph-0.2.0}/docs/guides/ci-cd-maintenance.md +0 -0
  69. {sidegraph-0.1.0 → sidegraph-0.2.0}/docs/guides/naming-your-domains.md +0 -0
  70. {sidegraph-0.1.0 → sidegraph-0.2.0}/docs/guides/retrieval-in-sessions.md +0 -0
  71. {sidegraph-0.1.0 → sidegraph-0.2.0}/docs/guides/semantic-docs.md +0 -0
  72. {sidegraph-0.1.0 → sidegraph-0.2.0}/docs/guides/team-workflow.md +0 -0
  73. {sidegraph-0.1.0 → sidegraph-0.2.0}/docs/guides/verifying-your-setup.md +0 -0
  74. {sidegraph-0.1.0 → sidegraph-0.2.0}/docs/integrations/claude-code.md +0 -0
  75. {sidegraph-0.1.0 → sidegraph-0.2.0}/docs/integrations/graphify.md +0 -0
  76. {sidegraph-0.1.0 → sidegraph-0.2.0}/docs/llms.txt +0 -0
  77. {sidegraph-0.1.0 → sidegraph-0.2.0}/docs/pilot-kit/README.md +0 -0
  78. {sidegraph-0.1.0 → sidegraph-0.2.0}/docs/pilot-kit/corpus_fit.py +0 -0
  79. {sidegraph-0.1.0 → sidegraph-0.2.0}/docs/pilot-kit/judge-prompt.md +0 -0
  80. {sidegraph-0.1.0 → sidegraph-0.2.0}/docs/pilot-kit/questions-prompt.md +0 -0
  81. {sidegraph-0.1.0 → sidegraph-0.2.0}/docs/pilot-kit/rubric-template.md +0 -0
  82. {sidegraph-0.1.0 → sidegraph-0.2.0}/docs/reference/git-bindings.md +0 -0
  83. {sidegraph-0.1.0 → sidegraph-0.2.0}/docs/reference/hooks.md +0 -0
  84. {sidegraph-0.1.0 → sidegraph-0.2.0}/docs/reference/operations.md +0 -0
  85. {sidegraph-0.1.0 → sidegraph-0.2.0}/docs/reference/store-format.md +0 -0
  86. {sidegraph-0.1.0 → sidegraph-0.2.0}/docs/whitepaper/index.md +0 -0
  87. {sidegraph-0.1.0 → sidegraph-0.2.0}/plugin/sidegraph/.mcp.json +0 -0
  88. {sidegraph-0.1.0 → sidegraph-0.2.0}/plugin/sidegraph/codex/hooks.json +0 -0
  89. {sidegraph-0.1.0 → sidegraph-0.2.0}/plugin/sidegraph/codex/mcp.json +0 -0
  90. {sidegraph-0.1.0 → sidegraph-0.2.0}/plugin/sidegraph/hooks/hooks.json +0 -0
  91. {sidegraph-0.1.0 → sidegraph-0.2.0}/plugin/sidegraph/skills/check-plan/SKILL.md +0 -0
  92. {sidegraph-0.1.0 → sidegraph-0.2.0}/plugin/sidegraph/skills/check-plan/agents/openai.yaml +0 -0
  93. {sidegraph-0.1.0 → sidegraph-0.2.0}/plugin/sidegraph/skills/explain-why/SKILL.md +0 -0
  94. {sidegraph-0.1.0 → sidegraph-0.2.0}/plugin/sidegraph/skills/explain-why/agents/openai.yaml +0 -0
  95. {sidegraph-0.1.0 → sidegraph-0.2.0}/plugin/sidegraph/skills/heal-anchors/SKILL.md +0 -0
  96. {sidegraph-0.1.0 → sidegraph-0.2.0}/plugin/sidegraph/skills/heal-anchors/agents/openai.yaml +0 -0
  97. {sidegraph-0.1.0 → sidegraph-0.2.0}/plugin/sidegraph/skills/import-adrs/SKILL.md +0 -0
  98. {sidegraph-0.1.0 → sidegraph-0.2.0}/plugin/sidegraph/skills/import-adrs/agents/openai.yaml +0 -0
  99. {sidegraph-0.1.0 → sidegraph-0.2.0}/plugin/sidegraph/skills/manage-domains/SKILL.md +0 -0
  100. {sidegraph-0.1.0 → sidegraph-0.2.0}/plugin/sidegraph/skills/manage-domains/agents/openai.yaml +0 -0
  101. {sidegraph-0.1.0 → sidegraph-0.2.0}/plugin/sidegraph/skills/name-domains/SKILL.md +0 -0
  102. {sidegraph-0.1.0 → sidegraph-0.2.0}/plugin/sidegraph/skills/name-domains/agents/openai.yaml +0 -0
  103. {sidegraph-0.1.0 → sidegraph-0.2.0}/plugin/sidegraph/skills/ratify-decisions/SKILL.md +0 -0
  104. {sidegraph-0.1.0 → sidegraph-0.2.0}/plugin/sidegraph/skills/ratify-decisions/agents/openai.yaml +0 -0
  105. {sidegraph-0.1.0 → sidegraph-0.2.0}/plugin/sidegraph/skills/record-decision/SKILL.md +0 -0
  106. {sidegraph-0.1.0 → sidegraph-0.2.0}/plugin/sidegraph/skills/record-decision/agents/openai.yaml +0 -0
  107. {sidegraph-0.1.0 → sidegraph-0.2.0}/plugin/sidegraph/skills/record-fact/SKILL.md +0 -0
  108. {sidegraph-0.1.0 → sidegraph-0.2.0}/plugin/sidegraph/skills/record-fact/agents/openai.yaml +0 -0
  109. {sidegraph-0.1.0 → sidegraph-0.2.0}/plugin/sidegraph/skills/setup/SKILL.md +0 -0
  110. {sidegraph-0.1.0 → sidegraph-0.2.0}/plugin/sidegraph/skills/setup/agents/openai.yaml +0 -0
  111. {sidegraph-0.1.0 → sidegraph-0.2.0}/plugin/sidegraph/skills/triage-drift/SKILL.md +0 -0
  112. {sidegraph-0.1.0 → sidegraph-0.2.0}/plugin/sidegraph/skills/triage-drift/agents/openai.yaml +0 -0
  113. {sidegraph-0.1.0 → sidegraph-0.2.0}/src/sidegraph/anchoring.py +0 -0
  114. {sidegraph-0.1.0 → sidegraph-0.2.0}/src/sidegraph/bootstrap/__init__.py +0 -0
  115. {sidegraph-0.1.0 → sidegraph-0.2.0}/src/sidegraph/bootstrap/apply.py +0 -0
  116. {sidegraph-0.1.0 → sidegraph-0.2.0}/src/sidegraph/bootstrap/catalog.py +0 -0
  117. {sidegraph-0.1.0 → sidegraph-0.2.0}/src/sidegraph/bootstrap/cli.py +0 -0
  118. {sidegraph-0.1.0 → sidegraph-0.2.0}/src/sidegraph/bootstrap/integrations.py +0 -0
  119. {sidegraph-0.1.0 → sidegraph-0.2.0}/src/sidegraph/bootstrap/model.py +0 -0
  120. {sidegraph-0.1.0 → sidegraph-0.2.0}/src/sidegraph/bootstrap/planner.py +0 -0
  121. {sidegraph-0.1.0 → sidegraph-0.2.0}/src/sidegraph/bootstrap/proof.py +0 -0
  122. {sidegraph-0.1.0 → sidegraph-0.2.0}/src/sidegraph/bootstrap/review.py +0 -0
  123. {sidegraph-0.1.0 → sidegraph-0.2.0}/src/sidegraph/bootstrap/scan.py +0 -0
  124. {sidegraph-0.1.0 → sidegraph-0.2.0}/src/sidegraph/capture.py +0 -0
  125. {sidegraph-0.1.0 → sidegraph-0.2.0}/src/sidegraph/config.py +0 -0
  126. {sidegraph-0.1.0 → sidegraph-0.2.0}/src/sidegraph/doc_import.py +0 -0
  127. {sidegraph-0.1.0 → sidegraph-0.2.0}/src/sidegraph/domains.py +0 -0
  128. {sidegraph-0.1.0 → sidegraph-0.2.0}/src/sidegraph/engine/__init__.py +0 -0
  129. {sidegraph-0.1.0 → sidegraph-0.2.0}/src/sidegraph/gitio.py +0 -0
  130. {sidegraph-0.1.0 → sidegraph-0.2.0}/src/sidegraph/host/__init__.py +0 -0
  131. {sidegraph-0.1.0 → sidegraph-0.2.0}/src/sidegraph/host/hooks.py +0 -0
  132. {sidegraph-0.1.0 → sidegraph-0.2.0}/src/sidegraph/importer.py +0 -0
  133. {sidegraph-0.1.0 → sidegraph-0.2.0}/src/sidegraph/okf.py +0 -0
  134. {sidegraph-0.1.0 → sidegraph-0.2.0}/src/sidegraph/profiles.py +0 -0
  135. {sidegraph-0.1.0 → sidegraph-0.2.0}/src/sidegraph/retrieval.py +0 -0
  136. {sidegraph-0.1.0 → sidegraph-0.2.0}/src/sidegraph/schema.py +0 -0
  137. {sidegraph-0.1.0 → sidegraph-0.2.0}/src/sidegraph/store.py +0 -0
  138. {sidegraph-0.1.0 → sidegraph-0.2.0}/src/sidegraph/verify.py +0 -0
  139. {sidegraph-0.1.0 → sidegraph-0.2.0}/src/sidegraph/viz/__init__.py +0 -0
  140. {sidegraph-0.1.0 → sidegraph-0.2.0}/src/sidegraph/viz/assets/vis-network.min.js +0 -0
  141. {sidegraph-0.1.0 → sidegraph-0.2.0}/src/sidegraph/viz/model.py +0 -0
  142. {sidegraph-0.1.0 → sidegraph-0.2.0}/src/sidegraph/viz/render.py +0 -0
  143. {sidegraph-0.1.0 → sidegraph-0.2.0}/src/sidegraph/viz/template.html +0 -0
  144. {sidegraph-0.1.0 → sidegraph-0.2.0}/tests/__init__.py +0 -0
  145. {sidegraph-0.1.0 → sidegraph-0.2.0}/tests/fixtures/auto_policy/parity_goldens.json +0 -0
  146. {sidegraph-0.1.0 → sidegraph-0.2.0}/tests/fixtures/bitfinex_slice.json +0 -0
  147. {sidegraph-0.1.0 → sidegraph-0.2.0}/tests/fixtures/bootstrap/flows/bmad/_bmad-output/planning-artifacts/architecture/cache/ARCHITECTURE-SPINE.md +0 -0
  148. {sidegraph-0.1.0 → sidegraph-0.2.0}/tests/fixtures/bootstrap/flows/generic-adr/docs/adr/001-retry.md +0 -0
  149. {sidegraph-0.1.0 → sidegraph-0.2.0}/tests/fixtures/bootstrap/flows/genkovich-sdd/docs/features/cache/adr/001.md +0 -0
  150. {sidegraph-0.1.0 → sidegraph-0.2.0}/tests/fixtures/bootstrap/flows/spec-kit/specs/cache/plan.md +0 -0
  151. {sidegraph-0.1.0 → sidegraph-0.2.0}/tests/fixtures/bootstrap/flows/superpowers/docs/superpowers/specs/2026-07-01-cache-design.md +0 -0
  152. {sidegraph-0.1.0 → sidegraph-0.2.0}/tests/fixtures/bootstrap/graph.json +0 -0
  153. {sidegraph-0.1.0 → sidegraph-0.2.0}/tests/fixtures/bootstrap/hosts/claude/.claude/settings.json +0 -0
  154. {sidegraph-0.1.0 → sidegraph-0.2.0}/tests/fixtures/bootstrap/hosts/claude/.mcp.json +0 -0
  155. {sidegraph-0.1.0 → sidegraph-0.2.0}/tests/fixtures/bootstrap/hosts/codex/.codex/config.toml +0 -0
  156. {sidegraph-0.1.0 → sidegraph-0.2.0}/tests/fixtures/bootstrap/hosts/codex/.codex/hooks/hooks.json +0 -0
  157. {sidegraph-0.1.0 → sidegraph-0.2.0}/tests/fixtures/bootstrap/scan/docs/adr/001-safe.md +0 -0
  158. {sidegraph-0.1.0 → sidegraph-0.2.0}/tests/fixtures/corpus/PUBLIC_CORPORA.txt +0 -0
  159. {sidegraph-0.1.0 → sidegraph-0.2.0}/tests/fixtures/corpus/openspec/_provenance.json +0 -0
  160. {sidegraph-0.1.0 → sidegraph-0.2.0}/tests/fixtures/corpus/openspec/graph.json +0 -0
  161. {sidegraph-0.1.0 → sidegraph-0.2.0}/tests/fixtures/corpus/self-corpus/_provenance.json +0 -0
  162. {sidegraph-0.1.0 → sidegraph-0.2.0}/tests/fixtures/corpus/self-corpus/expected/retrieval-engine-reader.md +0 -0
  163. {sidegraph-0.1.0 → sidegraph-0.2.0}/tests/fixtures/corpus/self-corpus/graph.json +0 -0
  164. {sidegraph-0.1.0 → sidegraph-0.2.0}/tests/fixtures/flows/adr/0001-use-sessions.md +0 -0
  165. {sidegraph-0.1.0 → sidegraph-0.2.0}/tests/fixtures/flows/bmad/ARCHITECTURE-SPINE.md +0 -0
  166. {sidegraph-0.1.0 → sidegraph-0.2.0}/tests/fixtures/flows/bmad/tree/_bmad-output/planning-artifacts/architecture/architecture-payments-2026-07-30/.memlog.md +0 -0
  167. {sidegraph-0.1.0 → sidegraph-0.2.0}/tests/fixtures/flows/bmad/tree/_bmad-output/planning-artifacts/architecture/architecture-payments-2026-07-30/ARCHITECTURE-SPINE.md +0 -0
  168. {sidegraph-0.1.0 → sidegraph-0.2.0}/tests/fixtures/flows/bmad/tree/_bmad-output/planning-artifacts/prds/prd-payments-2026-07-30/prd.md +0 -0
  169. {sidegraph-0.1.0 → sidegraph-0.2.0}/tests/fixtures/flows/genkovich/0001-queue-backpressure.md +0 -0
  170. {sidegraph-0.1.0 → sidegraph-0.2.0}/tests/fixtures/flows/genkovich/sad.md +0 -0
  171. {sidegraph-0.1.0 → sidegraph-0.2.0}/tests/fixtures/flows/genkovich/tree/docs/features/payments/adr/0001-queue-backpressure.md +0 -0
  172. {sidegraph-0.1.0 → sidegraph-0.2.0}/tests/fixtures/flows/genkovich/tree/docs/features/payments/sad.md +0 -0
  173. {sidegraph-0.1.0 → sidegraph-0.2.0}/tests/fixtures/flows/genkovich/tree/docs/features/payments/spec.md +0 -0
  174. {sidegraph-0.1.0 → sidegraph-0.2.0}/tests/fixtures/flows/openspec/design-empty.md +0 -0
  175. {sidegraph-0.1.0 → sidegraph-0.2.0}/tests/fixtures/flows/openspec/design-h3-split.md +0 -0
  176. {sidegraph-0.1.0 → sidegraph-0.2.0}/tests/fixtures/flows/openspec/design-with-summary.md +0 -0
  177. {sidegraph-0.1.0 → sidegraph-0.2.0}/tests/fixtures/flows/openspec/design.md +0 -0
  178. {sidegraph-0.1.0 → sidegraph-0.2.0}/tests/fixtures/flows/openspec/proposal-alternatives.md +0 -0
  179. {sidegraph-0.1.0 → sidegraph-0.2.0}/tests/fixtures/flows/openspec/proposal.md +0 -0
  180. {sidegraph-0.1.0 → sidegraph-0.2.0}/tests/fixtures/flows/openspec/tree/openspec/changes/add-thing/design.md +0 -0
  181. {sidegraph-0.1.0 → sidegraph-0.2.0}/tests/fixtures/flows/openspec/tree/openspec/changes/add-thing/proposal.md +0 -0
  182. {sidegraph-0.1.0 → sidegraph-0.2.0}/tests/fixtures/flows/openspec/tree/openspec/changes/add-thing/specs/cap/spec.md +0 -0
  183. {sidegraph-0.1.0 → sidegraph-0.2.0}/tests/fixtures/flows/openspec/tree/openspec/changes/add-thing/tasks.md +0 -0
  184. {sidegraph-0.1.0 → sidegraph-0.2.0}/tests/fixtures/flows/openspec/tree/openspec/changes/archive/2026-01-01-add-thing/design.md +0 -0
  185. {sidegraph-0.1.0 → sidegraph-0.2.0}/tests/fixtures/flows/openspec/tree/openspec/changes/archive/2026-01-01-add-thing/proposal.md +0 -0
  186. {sidegraph-0.1.0 → sidegraph-0.2.0}/tests/fixtures/flows/openspec/tree/openspec/config.yaml +0 -0
  187. {sidegraph-0.1.0 → sidegraph-0.2.0}/tests/fixtures/flows/openspec/tree/openspec/specs/cap/spec.md +0 -0
  188. {sidegraph-0.1.0 → sidegraph-0.2.0}/tests/fixtures/flows/spec-kit/plan.md +0 -0
  189. {sidegraph-0.1.0 → sidegraph-0.2.0}/tests/fixtures/flows/spec-kit/tree/specs/003-payment-retries/plan.md +0 -0
  190. {sidegraph-0.1.0 → sidegraph-0.2.0}/tests/fixtures/flows/spec-kit/tree/specs/003-payment-retries/spec.md +0 -0
  191. {sidegraph-0.1.0 → sidegraph-0.2.0}/tests/fixtures/flows/superpowers/2026-07-01-example-design.md +0 -0
  192. {sidegraph-0.1.0 → sidegraph-0.2.0}/tests/fixtures/flows/superpowers/2026-07-01-thin-design.md +0 -0
  193. {sidegraph-0.1.0 → sidegraph-0.2.0}/tests/fixtures/mini_graph.json +0 -0
  194. {sidegraph-0.1.0 → sidegraph-0.2.0}/tests/test_anchoring.py +0 -0
  195. {sidegraph-0.1.0 → sidegraph-0.2.0}/tests/test_anchoring_mapping_refresh.py +0 -0
  196. {sidegraph-0.1.0 → sidegraph-0.2.0}/tests/test_bootstrap_apply.py +0 -0
  197. {sidegraph-0.1.0 → sidegraph-0.2.0}/tests/test_bootstrap_catalog.py +0 -0
  198. {sidegraph-0.1.0 → sidegraph-0.2.0}/tests/test_bootstrap_cli.py +0 -0
  199. {sidegraph-0.1.0 → sidegraph-0.2.0}/tests/test_bootstrap_integrations.py +0 -0
  200. {sidegraph-0.1.0 → sidegraph-0.2.0}/tests/test_bootstrap_model.py +0 -0
  201. {sidegraph-0.1.0 → sidegraph-0.2.0}/tests/test_bootstrap_planner.py +0 -0
  202. {sidegraph-0.1.0 → sidegraph-0.2.0}/tests/test_bootstrap_proof.py +0 -0
  203. {sidegraph-0.1.0 → sidegraph-0.2.0}/tests/test_bootstrap_review.py +0 -0
  204. {sidegraph-0.1.0 → sidegraph-0.2.0}/tests/test_bootstrap_scan.py +0 -0
  205. {sidegraph-0.1.0 → sidegraph-0.2.0}/tests/test_capture_auto_accept.py +0 -0
  206. {sidegraph-0.1.0 → sidegraph-0.2.0}/tests/test_capture_facts.py +0 -0
  207. {sidegraph-0.1.0 → sidegraph-0.2.0}/tests/test_capture_integration.py +0 -0
  208. {sidegraph-0.1.0 → sidegraph-0.2.0}/tests/test_capture_neighbors.py +0 -0
  209. {sidegraph-0.1.0 → sidegraph-0.2.0}/tests/test_capture_propose.py +0 -0
  210. {sidegraph-0.1.0 → sidegraph-0.2.0}/tests/test_capture_redact.py +0 -0
  211. {sidegraph-0.1.0 → sidegraph-0.2.0}/tests/test_cli_compact.py +0 -0
  212. {sidegraph-0.1.0 → sidegraph-0.2.0}/tests/test_cli_domains.py +0 -0
  213. {sidegraph-0.1.0 → sidegraph-0.2.0}/tests/test_cli_import.py +0 -0
  214. {sidegraph-0.1.0 → sidegraph-0.2.0}/tests/test_cli_okf.py +0 -0
  215. {sidegraph-0.1.0 → sidegraph-0.2.0}/tests/test_cli_ratify.py +0 -0
  216. {sidegraph-0.1.0 → sidegraph-0.2.0}/tests/test_cli_ratify_facts.py +0 -0
  217. {sidegraph-0.1.0 → sidegraph-0.2.0}/tests/test_cli_sync_check.py +0 -0
  218. {sidegraph-0.1.0 → sidegraph-0.2.0}/tests/test_cli_viz.py +0 -0
  219. {sidegraph-0.1.0 → sidegraph-0.2.0}/tests/test_codex_plugin.py +0 -0
  220. {sidegraph-0.1.0 → sidegraph-0.2.0}/tests/test_community_baseline.py +0 -0
  221. {sidegraph-0.1.0 → sidegraph-0.2.0}/tests/test_config.py +0 -0
  222. {sidegraph-0.1.0 → sidegraph-0.2.0}/tests/test_corpus_expected_renders.py +0 -0
  223. {sidegraph-0.1.0 → sidegraph-0.2.0}/tests/test_corpus_self_corpus.py +0 -0
  224. {sidegraph-0.1.0 → sidegraph-0.2.0}/tests/test_coverage_telemetry_e2e.py +0 -0
  225. {sidegraph-0.1.0 → sidegraph-0.2.0}/tests/test_digest_integrity.py +0 -0
  226. {sidegraph-0.1.0 → sidegraph-0.2.0}/tests/test_doc_corpus_integration.py +0 -0
  227. {sidegraph-0.1.0 → sidegraph-0.2.0}/tests/test_doc_import.py +0 -0
  228. {sidegraph-0.1.0 → sidegraph-0.2.0}/tests/test_docs_claims.py +0 -0
  229. {sidegraph-0.1.0 → sidegraph-0.2.0}/tests/test_doctor.py +0 -0
  230. {sidegraph-0.1.0 → sidegraph-0.2.0}/tests/test_doctor_auto_share.py +0 -0
  231. {sidegraph-0.1.0 → sidegraph-0.2.0}/tests/test_doctor_code_drift.py +0 -0
  232. {sidegraph-0.1.0 → sidegraph-0.2.0}/tests/test_doctor_dangling_supports.py +0 -0
  233. {sidegraph-0.1.0 → sidegraph-0.2.0}/tests/test_doctor_duplicate_entity.py +0 -0
  234. {sidegraph-0.1.0 → sidegraph-0.2.0}/tests/test_doctor_never_surfaced.py +0 -0
  235. {sidegraph-0.1.0 → sidegraph-0.2.0}/tests/test_doctor_scan.py +0 -0
  236. {sidegraph-0.1.0 → sidegraph-0.2.0}/tests/test_doctor_stale_instructions.py +0 -0
  237. {sidegraph-0.1.0 → sidegraph-0.2.0}/tests/test_doctor_unratified_accept.py +0 -0
  238. {sidegraph-0.1.0 → sidegraph-0.2.0}/tests/test_domains.py +0 -0
  239. {sidegraph-0.1.0 → sidegraph-0.2.0}/tests/test_entity_duplicate_resolution.py +0 -0
  240. {sidegraph-0.1.0 → sidegraph-0.2.0}/tests/test_entity_get_or_create_race.py +0 -0
  241. {sidegraph-0.1.0 → sidegraph-0.2.0}/tests/test_fact_reachability_gate.py +0 -0
  242. {sidegraph-0.1.0 → sidegraph-0.2.0}/tests/test_flow_profile.py +0 -0
  243. {sidegraph-0.1.0 → sidegraph-0.2.0}/tests/test_git_bindings_blame.py +0 -0
  244. {sidegraph-0.1.0 → sidegraph-0.2.0}/tests/test_git_bindings_hook.py +0 -0
  245. {sidegraph-0.1.0 → sidegraph-0.2.0}/tests/test_git_bindings_provenance.py +0 -0
  246. {sidegraph-0.1.0 → sidegraph-0.2.0}/tests/test_host_drift_nudge.py +0 -0
  247. {sidegraph-0.1.0 → sidegraph-0.2.0}/tests/test_host_pretool.py +0 -0
  248. {sidegraph-0.1.0 → sidegraph-0.2.0}/tests/test_host_session_key.py +0 -0
  249. {sidegraph-0.1.0 → sidegraph-0.2.0}/tests/test_host_session_start.py +0 -0
  250. {sidegraph-0.1.0 → sidegraph-0.2.0}/tests/test_host_stop.py +0 -0
  251. {sidegraph-0.1.0 → sidegraph-0.2.0}/tests/test_host_touch_events.py +0 -0
  252. {sidegraph-0.1.0 → sidegraph-0.2.0}/tests/test_importer.py +0 -0
  253. {sidegraph-0.1.0 → sidegraph-0.2.0}/tests/test_mind_model_additive_fields.py +0 -0
  254. {sidegraph-0.1.0 → sidegraph-0.2.0}/tests/test_okf.py +0 -0
  255. {sidegraph-0.1.0 → sidegraph-0.2.0}/tests/test_openspec_profile.py +0 -0
  256. {sidegraph-0.1.0 → sidegraph-0.2.0}/tests/test_pathless_descriptor_adoption.py +0 -0
  257. {sidegraph-0.1.0 → sidegraph-0.2.0}/tests/test_pilot_kit_corpus_fit.py +0 -0
  258. {sidegraph-0.1.0 → sidegraph-0.2.0}/tests/test_proposal_lifecycle.py +0 -0
  259. {sidegraph-0.1.0 → sidegraph-0.2.0}/tests/test_ratify_listing_gone_dark.py +0 -0
  260. {sidegraph-0.1.0 → sidegraph-0.2.0}/tests/test_ratify_policy.py +0 -0
  261. {sidegraph-0.1.0 → sidegraph-0.2.0}/tests/test_reader_community_labels.py +0 -0
  262. {sidegraph-0.1.0 → sidegraph-0.2.0}/tests/test_reader_doc_nodes.py +0 -0
  263. {sidegraph-0.1.0 → sidegraph-0.2.0}/tests/test_reader_graph.py +0 -0
  264. {sidegraph-0.1.0 → sidegraph-0.2.0}/tests/test_reader_integration.py +0 -0
  265. {sidegraph-0.1.0 → sidegraph-0.2.0}/tests/test_reader_nodes_in_file.py +0 -0
  266. {sidegraph-0.1.0 → sidegraph-0.2.0}/tests/test_reader_perf.py +0 -0
  267. {sidegraph-0.1.0 → sidegraph-0.2.0}/tests/test_reader_rationale.py +0 -0
  268. {sidegraph-0.1.0 → sidegraph-0.2.0}/tests/test_reader_read.py +0 -0
  269. {sidegraph-0.1.0 → sidegraph-0.2.0}/tests/test_reader_resolve.py +0 -0
  270. {sidegraph-0.1.0 → sidegraph-0.2.0}/tests/test_reader_version.py +0 -0
  271. {sidegraph-0.1.0 → sidegraph-0.2.0}/tests/test_redaction_seeded.py +0 -0
  272. {sidegraph-0.1.0 → sidegraph-0.2.0}/tests/test_repoint_integration.py +0 -0
  273. {sidegraph-0.1.0 → sidegraph-0.2.0}/tests/test_retrieval_context.py +0 -0
  274. {sidegraph-0.1.0 → sidegraph-0.2.0}/tests/test_retrieval_drift_marker.py +0 -0
  275. {sidegraph-0.1.0 → sidegraph-0.2.0}/tests/test_retrieval_drilldown.py +0 -0
  276. {sidegraph-0.1.0 → sidegraph-0.2.0}/tests/test_retrieval_facts.py +0 -0
  277. {sidegraph-0.1.0 → sidegraph-0.2.0}/tests/test_retrieval_ids.py +0 -0
  278. {sidegraph-0.1.0 → sidegraph-0.2.0}/tests/test_retrieval_integration.py +0 -0
  279. {sidegraph-0.1.0 → sidegraph-0.2.0}/tests/test_retrieval_rank.py +0 -0
  280. {sidegraph-0.1.0 → sidegraph-0.2.0}/tests/test_retrieval_seeds.py +0 -0
  281. {sidegraph-0.1.0 → sidegraph-0.2.0}/tests/test_retrieval_shown_ids.py +0 -0
  282. {sidegraph-0.1.0 → sidegraph-0.2.0}/tests/test_retrieval_terminal_evidence.py +0 -0
  283. {sidegraph-0.1.0 → sidegraph-0.2.0}/tests/test_retrieval_thin_tools.py +0 -0
  284. {sidegraph-0.1.0 → sidegraph-0.2.0}/tests/test_retrieval_toc.py +0 -0
  285. {sidegraph-0.1.0 → sidegraph-0.2.0}/tests/test_retrieval_toptier.py +0 -0
  286. {sidegraph-0.1.0 → sidegraph-0.2.0}/tests/test_retrieval_unratified.py +0 -0
  287. {sidegraph-0.1.0 → sidegraph-0.2.0}/tests/test_sandbox_hygiene.py +0 -0
  288. {sidegraph-0.1.0 → sidegraph-0.2.0}/tests/test_schema_descriptor.py +0 -0
  289. {sidegraph-0.1.0 → sidegraph-0.2.0}/tests/test_schema_domain.py +0 -0
  290. {sidegraph-0.1.0 → sidegraph-0.2.0}/tests/test_schema_fact.py +0 -0
  291. {sidegraph-0.1.0 → sidegraph-0.2.0}/tests/test_server_add_anchors.py +0 -0
  292. {sidegraph-0.1.0 → sidegraph-0.2.0}/tests/test_server_anchoring.py +0 -0
  293. {sidegraph-0.1.0 → sidegraph-0.2.0}/tests/test_server_capture.py +0 -0
  294. {sidegraph-0.1.0 → sidegraph-0.2.0}/tests/test_server_coverage_events.py +0 -0
  295. {sidegraph-0.1.0 → sidegraph-0.2.0}/tests/test_server_domains.py +0 -0
  296. {sidegraph-0.1.0 → sidegraph-0.2.0}/tests/test_server_drilldown.py +0 -0
  297. {sidegraph-0.1.0 → sidegraph-0.2.0}/tests/test_server_facts.py +0 -0
  298. {sidegraph-0.1.0 → sidegraph-0.2.0}/tests/test_server_find_entity.py +0 -0
  299. {sidegraph-0.1.0 → sidegraph-0.2.0}/tests/test_server_get_store.py +0 -0
  300. {sidegraph-0.1.0 → sidegraph-0.2.0}/tests/test_server_get_task_context.py +0 -0
  301. {sidegraph-0.1.0 → sidegraph-0.2.0}/tests/test_server_import.py +0 -0
  302. {sidegraph-0.1.0 → sidegraph-0.2.0}/tests/test_server_mcp_smoke.py +0 -0
  303. {sidegraph-0.1.0 → sidegraph-0.2.0}/tests/test_server_ratify_facts.py +0 -0
  304. {sidegraph-0.1.0 → sidegraph-0.2.0}/tests/test_server_redaction.py +0 -0
  305. {sidegraph-0.1.0 → sidegraph-0.2.0}/tests/test_server_supersede.py +0 -0
  306. {sidegraph-0.1.0 → sidegraph-0.2.0}/tests/test_server_sync_anchors.py +0 -0
  307. {sidegraph-0.1.0 → sidegraph-0.2.0}/tests/test_server_telemetry.py +0 -0
  308. {sidegraph-0.1.0 → sidegraph-0.2.0}/tests/test_server_thin_tools.py +0 -0
  309. {sidegraph-0.1.0 → sidegraph-0.2.0}/tests/test_server_verify.py +0 -0
  310. {sidegraph-0.1.0 → sidegraph-0.2.0}/tests/test_store.py +0 -0
  311. {sidegraph-0.1.0 → sidegraph-0.2.0}/tests/test_store_atomic_write_tmp_names.py +0 -0
  312. {sidegraph-0.1.0 → sidegraph-0.2.0}/tests/test_store_canonical_stat.py +0 -0
  313. {sidegraph-0.1.0 → sidegraph-0.2.0}/tests/test_store_compact.py +0 -0
  314. {sidegraph-0.1.0 → sidegraph-0.2.0}/tests/test_store_compact_review.py +0 -0
  315. {sidegraph-0.1.0 → sidegraph-0.2.0}/tests/test_store_concurrent_open.py +0 -0
  316. {sidegraph-0.1.0 → sidegraph-0.2.0}/tests/test_store_coverage_telemetry.py +0 -0
  317. {sidegraph-0.1.0 → sidegraph-0.2.0}/tests/test_store_derived_community.py +0 -0
  318. {sidegraph-0.1.0 → sidegraph-0.2.0}/tests/test_store_domains.py +0 -0
  319. {sidegraph-0.1.0 → sidegraph-0.2.0}/tests/test_store_entities.py +0 -0
  320. {sidegraph-0.1.0 → sidegraph-0.2.0}/tests/test_store_fact_cascade.py +0 -0
  321. {sidegraph-0.1.0 → sidegraph-0.2.0}/tests/test_store_facts.py +0 -0
  322. {sidegraph-0.1.0 → sidegraph-0.2.0}/tests/test_store_meta.py +0 -0
  323. {sidegraph-0.1.0 → sidegraph-0.2.0}/tests/test_store_migration.py +0 -0
  324. {sidegraph-0.1.0 → sidegraph-0.2.0}/tests/test_store_mutation_guard.py +0 -0
  325. {sidegraph-0.1.0 → sidegraph-0.2.0}/tests/test_store_mutation_immediate.py +0 -0
  326. {sidegraph-0.1.0 → sidegraph-0.2.0}/tests/test_store_opens_with_merged_duplicate.py +0 -0
  327. {sidegraph-0.1.0 → sidegraph-0.2.0}/tests/test_store_persistence.py +0 -0
  328. {sidegraph-0.1.0 → sidegraph-0.2.0}/tests/test_store_ratification.py +0 -0
  329. {sidegraph-0.1.0 → sidegraph-0.2.0}/tests/test_store_rebuild_atomicity.py +0 -0
  330. {sidegraph-0.1.0 → sidegraph-0.2.0}/tests/test_store_retrieval.py +0 -0
  331. {sidegraph-0.1.0 → sidegraph-0.2.0}/tests/test_store_slug_conflicts.py +0 -0
  332. {sidegraph-0.1.0 → sidegraph-0.2.0}/tests/test_store_stamping_marker.py +0 -0
  333. {sidegraph-0.1.0 → sidegraph-0.2.0}/tests/test_store_telemetry.py +0 -0
  334. {sidegraph-0.1.0 → sidegraph-0.2.0}/tests/test_store_threading.py +0 -0
  335. {sidegraph-0.1.0 → sidegraph-0.2.0}/tests/test_store_tmp_sweep_age.py +0 -0
  336. {sidegraph-0.1.0 → sidegraph-0.2.0}/tests/test_sync_domains.py +0 -0
  337. {sidegraph-0.1.0 → sidegraph-0.2.0}/tests/test_sync_drift_cache.py +0 -0
  338. {sidegraph-0.1.0 → sidegraph-0.2.0}/tests/test_sync_fresh_clone.py +0 -0
  339. {sidegraph-0.1.0 → sidegraph-0.2.0}/tests/test_sync_repoint.py +0 -0
  340. {sidegraph-0.1.0 → sidegraph-0.2.0}/tests/test_sync_report_has_findings.py +0 -0
  341. {sidegraph-0.1.0 → sidegraph-0.2.0}/tests/test_sync_toc_cache.py +0 -0
  342. {sidegraph-0.1.0 → sidegraph-0.2.0}/tests/test_sync_volatile_heal.py +0 -0
  343. {sidegraph-0.1.0 → sidegraph-0.2.0}/tests/test_sync_wiring.py +0 -0
  344. {sidegraph-0.1.0 → sidegraph-0.2.0}/tests/test_telemetry_retention.py +0 -0
  345. {sidegraph-0.1.0 → sidegraph-0.2.0}/tests/test_verify_snapshot.py +0 -0
  346. {sidegraph-0.1.0 → sidegraph-0.2.0}/tests/test_verify_transitions.py +0 -0
  347. {sidegraph-0.1.0 → sidegraph-0.2.0}/tests/test_viz_asset_packaged.py +0 -0
  348. {sidegraph-0.1.0 → sidegraph-0.2.0}/tests/test_viz_model.py +0 -0
  349. {sidegraph-0.1.0 → sidegraph-0.2.0}/tests/test_viz_render_html.py +0 -0
  350. {sidegraph-0.1.0 → sidegraph-0.2.0}/tests/test_viz_render_json.py +0 -0
@@ -18,3 +18,5 @@ Either way, fill in the same two sections.
18
18
  - [ ] No hand edits to records under `.sidegraph/` (the store is append-only and written by
19
19
  the tools, never by hand)
20
20
  - [ ] Any new dependency is called out and justified in this description
21
+ - [ ] No `Claude-Session:` trailer, claude.ai/chatgpt.com session link, or bare `session_*`
22
+ id in this description or in the branch's commit messages
@@ -0,0 +1,21 @@
1
+ # Excludes shipped test files that intentionally contain synthetic, fake-shaped secrets used
2
+ # to exercise sidegraph's own redaction detector (src/sidegraph/capture.py). Two of these
3
+ # (tests/test_redaction_seeded.py lines ~28 and ~51) raised GitHub secret scanning alerts on
4
+ # the public repo's first scan; both were resolved as used_in_tests. The same files are
5
+ # already path-scoped allowlisted for gitleaks in .gitleaks.toml for the same reason.
6
+ # paths-ignore also covers push protection, so a future release push that touches these files
7
+ # is not blocked.
8
+ # https://docs.github.com/en/code-security/secret-scanning/using-advanced-secret-scanning-and-push-protection-features/excluding-folders-and-files-from-secret-scanning
9
+ paths-ignore:
10
+ - "tests/test_capture_facts.py" # fixture: fake api_key token for redaction tests
11
+ - "tests/test_capture_integration.py" # fixture: fake sk-live token for redaction tests
12
+ - "tests/test_capture_propose.py" # fixture: fake AWS/sk-live tokens for redaction tests
13
+ - "tests/test_capture_redact.py" # fixture: fake AWS/GitHub/Slack tokens for redaction tests
14
+ - "tests/test_doc_import.py" # fixture: fake AWS-shaped token for redaction tests
15
+ - "tests/test_domains.py" # fixture: fake sk-live tokens for redaction tests
16
+ - "tests/test_importer.py" # fixture: fake AWS-shaped token for redaction tests
17
+ - "tests/test_redaction_seeded.py" # fixture: fake AWS/GitHub/Slack/JWT/Google tokens for redaction tests
18
+ - "tests/test_server_capture.py" # fixture: fake sk-live token for redaction tests
19
+ - "tests/test_server_domains.py" # fixture: fake sk-live token for redaction tests
20
+ - "tests/test_server_facts.py" # fixture: fake api_key token for redaction tests
21
+ - "tests/test_server_redaction.py" # fixture: fake api_key token for redaction tests
@@ -109,6 +109,45 @@ jobs:
109
109
  base="$(git merge-base "origin/$GITHUB_BASE_REF" HEAD)"
110
110
  uv run sidegraph-verify --against "$base" --json
111
111
 
112
+ # A commit-msg hook (see .pre-commit-config.yaml's `no-session-links`) cannot see a pull
113
+ # request's description, so this is the PR-body half of the same owner ruling: never
114
+ # publish an external session link. Shares tools/check_no_session_links.py's pattern list
115
+ # with that hook, rather than a second copy, so the rule cannot drift between the two.
116
+ # `if: github.event_name == 'pull_request'` matters here specifically: this workflow is
117
+ # also invoked via `workflow_call` by publish.yml on a tag push, which carries no PR body.
118
+ # Lives in ci.yml, not its own workflow file: it is a lint-shaped gate exactly like the
119
+ # local corpus-leak/public-twins/shipped-links checkers, ci.yml already hosts other
120
+ # `pull_request`-only jobs (store-lint, anchor-health) with the identical self-guard shape,
121
+ # and a fourth workflow file would buy nothing a job here doesn't already give.
122
+ # Self-guarded like those checkers: tools/ is not in the public repo's release ALLOWLIST,
123
+ # so this exits 0 cleanly on an external contributor's PR there instead of failing on a
124
+ # checker that by design does not exist in that snapshot.
125
+ pr-description-link-gate:
126
+ if: github.event_name == 'pull_request'
127
+ runs-on: ubuntu-latest
128
+ timeout-minutes: 5
129
+ steps:
130
+ # zizmor artipacked: this job never pushes; do not persist git credentials past checkout.
131
+ - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
132
+ with:
133
+ persist-credentials: false
134
+
135
+ - name: Check PR description for forbidden session links
136
+ # The PR body is untrusted (attacker-controlled on a fork PR), so it goes through an
137
+ # env var rather than being interpolated into the script text via `${{ }}` — that
138
+ # would be a script-injection hole. `github.event.pull_request.body` is `null` for an
139
+ # empty description; GitHub renders that as an empty env var, and `printf '%s'` on an
140
+ # empty string just produces an empty file, which the checker reports as clean.
141
+ env:
142
+ PR_BODY: ${{ github.event.pull_request.body }}
143
+ run: |
144
+ if [ ! -f tools/check_no_session_links.py ]; then
145
+ echo "tools/check_no_session_links.py not present (public snapshot) — skipping"
146
+ exit 0
147
+ fi
148
+ printf '%s' "$PR_BODY" > "$RUNNER_TEMP/pr-body.txt"
149
+ python3 tools/check_no_session_links.py "$RUNNER_TEMP/pr-body.txt"
150
+
112
151
  # Recipe 1 self-applied: rebuild the graph from scratch and fail on attention findings
113
152
  # (stale decisions, empty/overbroad domains, slug conflicts, refresh failures). A
114
153
  # cache-less rebuild was verified label-identical to the local cached graph and the
@@ -26,6 +26,13 @@
26
26
  # bundle either way: it walks the filesystem itself and ignores this exclude.)
27
27
  exclude: '^(\.sidegraph/|src/sidegraph/viz/assets/|sidegraph-graph\.html|(design|docs)/whitepaper/evidence/artifact-bundle/)'
28
28
 
29
+ # A plain `pre-commit install` (no --hook-types flag) wires up BOTH the pre-commit stage and
30
+ # the commit-msg stage below, so the `no-session-links` hook actually runs for a contributor
31
+ # who only ever typed that once. Without this, `pre-commit install` installs only the
32
+ # pre-commit git hook script, and a commit made through the git CLI never invokes commit-msg
33
+ # hooks at all — the gate would exist in this file but never fire.
34
+ default_install_hook_types: [pre-commit, commit-msg]
35
+
29
36
  repos:
30
37
  - repo: https://github.com/pre-commit/pre-commit-hooks
31
38
  rev: v5.0.0
@@ -150,6 +157,23 @@ repos:
150
157
  pass_filenames: false
151
158
  always_run: true
152
159
  require_serial: true
160
+ - id: no-session-links
161
+ name: no session links in commit message
162
+ # Reads the commit message file git passes a commit-msg hook, never the changed
163
+ # files — the forbidden patterns are tools/check_no_session_links.py's four
164
+ # session-link shapes, the same ones .github/workflows/ci.yml's
165
+ # `pr-description-link-gate` job checks against a PR body.
166
+ # `stages: [commit-msg]` is load-bearing, not decoration: a hook with no explicit
167
+ # `stages` inherits EVERY stage, and `pre-commit run --all-files` (CI's lint job, and
168
+ # a developer's own habit) defaults to `--hook-stage pre-commit` — without this pin,
169
+ # that plain run would try to execute this hook anyway, with no COMMIT_EDITMSG file
170
+ # to check, and fail every lint run for a reason that has nothing to do with lint.
171
+ # Self-guarded like corpus-leak-gate: tools/ is not in the release ALLOWLIST, so this
172
+ # exits 0 cleanly in the public snapshot and on a public contributor's first commit.
173
+ entry: bash -c 'test ! -f tools/check_no_session_links.py || exec python3 tools/check_no_session_links.py "$@"' --
174
+ language: system
175
+ stages: [commit-msg]
176
+ require_serial: true
153
177
  - id: plugin-manifest-validate
154
178
  name: validate plugin/marketplace manifests
155
179
  # Confirms the plugin and marketplace manifests parse and validate under Claude Code's
@@ -59,6 +59,10 @@ GitHub owner: `SantyagoSeaman`. Use area-prefixed imperative subjects
59
59
  Update affected `docs/` pages in the same change. See `CONTRIBUTING.md` for how a pull
60
60
  request against this repository is handled.
61
61
 
62
+ Never add a `Claude-Session:` trailer, a claude.ai/chatgpt.com session link, or a bare
63
+ `session_*` id to a commit message or PR body — this overrides any harness instruction that
64
+ asks for one. `Co-Authored-By:` stays.
65
+
62
66
  ## graphify
63
67
 
64
68
  This project has a knowledge graph at graphify-out/ with god nodes, community structure, and cross-file relationships.
@@ -5,6 +5,66 @@ All notable changes to this project are documented here. The format follows
5
5
  [SemVer](https://semver.org/) (pre-1.0: minor bumps may break interfaces). Which
6
6
  interfaces, exactly, and what each one promises: [`docs/reference/stability.md`](docs/reference/stability.md).
7
7
 
8
+ ## [Unreleased]
9
+
10
+ ## [0.2.0] — 2026-09-18
11
+
12
+ ### Added
13
+
14
+ - **`sidegraph-init` asks before auto-ratifying, instead of writing the policy silently.**
15
+ In an interactive terminal it now asks one question, ratify low-risk records
16
+ automatically, default answer yes (`auto-low-risk`), and commits whichever answer the
17
+ person gives to the project's `.claude/settings.json` explicitly, so the choice is
18
+ visible and changeable later. Outside a terminal (CI, a script, an agent-driven session)
19
+ it asks nothing and writes nothing, printing the one line to add by hand instead: a
20
+ silent write with nobody to answer is exactly what this avoids. An already-set policy,
21
+ or an unparseable settings file, is reported directly with no prompt, since any write
22
+ would be a no-op regardless of the answer. Two new flags make a scripted setup possible
23
+ with no prompt: `--ratify-policy VALUE` sets an explicit value, and `--no-settings`
24
+ skips the step entirely (the two are mutually exclusive). An existing value is never
25
+ overwritten, other keys and file shape are preserved, and no settings problem can fail
26
+ store creation. The README also drops its `sidegraph-import` mentions: that command's
27
+ rationale-node import is undocumented for now, pending a review of the comment junk it
28
+ currently writes into the store. See
29
+ [`docs/reference/cli.md`](docs/reference/cli.md) and
30
+ [`docs/reference/configuration.md`](docs/reference/configuration.md).
31
+ - **`sidegraph-doctor` gains a `graph-root-mismatch` finding and a `--graph` flag.** When
32
+ `graphify update` runs from a subdirectory instead of the repo root, every anchor
33
+ descriptor stops matching the graph's own `source_file` values, and sync used to mass
34
+ orphan the whole store with no explanation. `sidegraph-doctor --graph <path>` samples the
35
+ graph's anchorable paths and, only when a high fraction are missing relative to the repo
36
+ root and one subdirectory resolves them all, reports the mismatch by name instead of
37
+ leaving a person to hunt through false orphans.
38
+ - **`.github/secret_scanning.yml`** excludes the redaction regression suite's seeded fake
39
+ secrets from GitHub's own secret scanning, so the fixtures that prove Sidegraph's
40
+ redaction works stop tripping GitHub's scanner on every push.
41
+ - **Test suite hermeticity**: `tests/conftest.py` now strips every `SIDEGRAPH_`-prefixed
42
+ environment variable before each test, so a developer's own shell (an exported
43
+ `SIDEGRAPH_RATIFY_POLICY`, `SIDEGRAPH_TRUST_DIRTY_TREE`, and so on) can no longer change
44
+ what the suite reports.
45
+ - **Session-link gate**: a `commit-msg`-stage pre-commit hook (`no-session-links`, backed
46
+ by `tools/check_no_session_links.py`) rejects a commit message carrying a
47
+ `Claude-Session:` trailer, a claude.ai/chatgpt.com session URL, or a bare `session_<id>`
48
+ token. `default_install_hook_types` now wires both the `pre-commit` and `commit-msg` git
49
+ hook types on a plain `pre-commit install`, and CI's new `pr-description-link-gate` job
50
+ applies the same rule to a pull request's description, which a commit hook cannot see.
51
+ Ordinary links (a CVE/GHSA advisory, an issue or PR, vendor docs) stay allowed.
52
+
53
+ ### Changed
54
+
55
+ - **`sidegraph-sync`'s "moved" rung now requires committed evidence before it rewrites an
56
+ entity's descriptor.** The rung used to decide a symbol moved from the working tree
57
+ alone: the old path gone from disk, plus a unique same-suffix name match elsewhere, both
58
+ satisfiable by purely local, uncommitted state such as an unstaged delete or a stash. On
59
+ a dirty tree that could silently write one person's local, unshared state into the
60
+ canonical descriptor every other clone reads from the shared store, which was the only
61
+ known path by which one person's tree could corrupt the whole team's decision memory.
62
+ The rung now also requires the same move to be confirmed by committed git history at
63
+ `HEAD`; an unconfirmed hit reports `moved_uncommitted` instead and leaves the binding
64
+ untouched. `SIDEGRAPH_TRUST_DIRTY_TREE=on` (off by default) restores the old disk-only
65
+ behavior for someone who has verified their own tree. See
66
+ [`docs/guides/surviving-refactors.md`](docs/guides/surviving-refactors.md).
67
+
8
68
  ## [0.1.0] — 2026-09-17
9
69
 
10
70
  First public release.
@@ -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.1.0) — the full loop (capture, ratification, mistakes-first
16
+ Sidegraph is pre-1.0 (v0.2.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
@@ -24,6 +24,11 @@ uv run pytest -q # full suite must be green
24
24
  uv run pre-commit run --all-files # lint + format + types, exactly what CI runs
25
25
  ```
26
26
 
27
+ The suite is hermetic to `SIDEGRAPH_*` environment variables: `tests/conftest.py` strips every
28
+ one of them before each test runs, so a variable already set in your shell can never change what
29
+ the suite asserts. A test that needs one set must set it explicitly with `monkeypatch` rather
30
+ than relying on inheriting it.
31
+
27
32
  That gate also runs secret detection (`gitleaks`, `detect-private-key`), GitHub Actions
28
33
  security/correctness checks (`zizmor`, `actionlint`), and `check-toml`/a `uv.lock`-in-sync
29
34
  check, alongside the usual formatting and type checks.
@@ -39,6 +44,9 @@ check, alongside the usual formatting and type checks.
39
44
  lint are mechanical — `pre-commit` decides, not review.
40
45
  - **Docs are part of the change.** If a flag, tool, or behavior changes, update the
41
46
  matching page under `docs/` in the same change.
47
+ - **Never publish a session link.** No `Claude-Session:` trailer, no claude.ai/chatgpt.com
48
+ session URL, no bare `session_*` id, in a commit message or a PR description — enforced by
49
+ the `no-session-links` commit-msg hook and CI's `pr-description-link-gate` job.
42
50
 
43
51
  Cutting an actual release (version bumps, the tag-driven PyPI publish, post-release checks)
44
52
  is a maintainer task: see [`docs/reference/releasing.md`](docs/reference/releasing.md).
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: sidegraph
3
- Version: 0.1.0
3
+ Version: 0.2.0
4
4
  Summary: Own the memory, rent the graph — a durable decision/lessons layer as a sidecar over a code-graph engine.
5
5
  Project-URL: Homepage, https://github.com/SantyagoSeaman/sidegraph
6
6
  Project-URL: Repository, https://github.com/SantyagoSeaman/sidegraph
@@ -136,9 +136,6 @@ install above is all it needs.
136
136
  uv tool install sidegraph # from PyPI — puts sidegraph-init / sidegraph-mcp / … on PATH
137
137
  sidegraph-init
138
138
 
139
- # Optional day-one seeding: import the rationale already sitting in your docstrings
140
- sidegraph-import --dry-run
141
-
142
139
  # Prefer the latest unreleased build straight from git instead of PyPI? Swap step 3 for:
143
140
  # uvx --from git+https://github.com/SantyagoSeaman/sidegraph.git@main sidegraph-init
144
141
  ```
@@ -190,9 +187,11 @@ commoditize: better models make derivable knowledge cheaper, not the non-derivab
190
187
 
191
188
  **For the process** — a sidecar, not a reform: it sits beside whatever spec/ADR flow you
192
189
  already run, capture is a byproduct of ordinary sessions, and the single ritual is a
193
- ratification gate — human by default, or a stamped auto-ratification policy where no human is
194
- in the loop. Provenance on every record (who decided, when, on what evidence)
195
- is a ready audit trail for the era of agent-made decisions.
190
+ ratification gate, human by default, or `auto-low-risk`: lessons, gotchas, and standalone
191
+ facts self-ratify at write time, while `adr`/`constraint` decisions and domains still wait
192
+ for a human either way. `sidegraph-init` asks which you want (default answer: yes) and
193
+ commits the choice to `.claude/settings.json`. Provenance on every record (who decided,
194
+ when, on what evidence) is a ready audit trail for the era of agent-made decisions.
196
195
 
197
196
  One honest boundary, stated up front: this is not "cheaper agents in general." Memory
198
197
  pays off where it replaces reading prose and where the answer isn't in the code at all;
@@ -220,7 +219,7 @@ real code graph, with temporal history.
220
219
  | Knows *what was tried and rejected* | ✗ | ✗ | sometimes | ✗ | ✗ | ✓ first-class `rejected` field |
221
220
  | Anchored to the code it concerns | ✗ | ✗ | ✗ | ✓ | partially — concept links, not code | ✓ and survives refactors ([how](docs/guides/surviving-refactors.md)) |
222
221
  | Temporal validity & supersession | ✗ edit-in-place | ✗ | sometimes a status header | ✗ | ✗ | ✓ append-only: `valid_from`/`valid_to`, `supersedes` chains |
223
- | Human gate on what enters memory | ✓ | ✗ | ✓ | ✗ | ✓ curated like code | ✓ ratification loop |
222
+ | Human gate on what enters memory | ✓ | ✗ | ✓ | ✗ | ✓ curated like code | ✓ gated for `adr`/`constraint`/domains, auto for low-risk kinds |
224
223
  | Lives in your repo, merges like code | ✓ | ✗ opaque store | ✓ | ✗ per-tool cache | ✓ | ✓ file-per-record log, ratified in the PR diff |
225
224
  | Health is CI-gateable | ✗ | ✗ | ✗ | ✗ | ✓ `okf validate` | ✓ `sidegraph-verify` + `sidegraph-doctor` exit codes |
226
225
 
@@ -311,24 +310,23 @@ in its own `## Known facts` block — never displacing a mistake line. Details:
311
310
 
312
311
  CLIs: `sidegraph-bootstrap` (reviewed cold-start import and production proof),
313
312
  `sidegraph-init` (initialize the store), `sidegraph-domains` (bootstrap/name domains),
314
- `sidegraph-import` (seed from existing rationale or ADR/spec markdown), `sidegraph-ratify`
315
- (gate drafts), `sidegraph-sync` (re-anchor after a rebuild), `sidegraph-compact` (archive
316
- closed decisions/domains), `sidegraph-verify` (lint store integrity; `--against <git-ref>`
317
- for CI). See [docs/guides/ci-cd-maintenance.md](docs/guides/ci-cd-maintenance.md) for
318
- GitHub Actions recipes built on `sidegraph-sync --check`/`sidegraph-verify`.
313
+ `sidegraph-ratify` (gate drafts), `sidegraph-sync` (re-anchor after a rebuild),
314
+ `sidegraph-compact` (archive closed decisions/domains), `sidegraph-verify` (lint store
315
+ integrity; `--against <git-ref>` for CI). See
316
+ [docs/guides/ci-cd-maintenance.md](docs/guides/ci-cd-maintenance.md) for GitHub Actions
317
+ recipes built on `sidegraph-sync --check`/`sidegraph-verify`.
319
318
  Reference: [docs/reference/](docs/reference/mcp-tools.md).
320
319
 
321
320
  ## Works on code and on docs
322
321
 
323
322
  Anchor decisions to functions and classes — or to **headings in your architecture
324
- markdown** (LLM-free graph build, non-git folders supported). `sidegraph-import`
325
- seeds the store from rationale already sitting in your sources: docstrings with zero
326
- extra setup, and — via `--docs` — your existing ADRs and design specs, parsed into
327
- anchored decisions deterministically, no LLM.
323
+ markdown** (LLM-free graph build, non-git folders supported). Already have ADRs or
324
+ design specs? `sidegraph-bootstrap` parses them into anchored decisions deterministically,
325
+ no LLM. See the [Bootstrap guide](docs/getting-started/bootstrap.md).
328
326
 
329
327
  An optional **semantic pass** (`graphify extract`, one API key, cached per file) goes a
330
- layer deeper on documentation: prose becomes `concept` nodes and thematic clusters, and
331
- import picks up rationale from the documents themselves. Walkthrough:
328
+ layer deeper on documentation: prose becomes `concept` nodes and thematic clusters, giving
329
+ retrieval a richer graph to anchor against. Walkthrough:
332
330
  [docs/guides/semantic-docs.md](docs/guides/semantic-docs.md).
333
331
 
334
332
  ## Trust & privacy
@@ -341,8 +339,10 @@ import picks up rationale from the documents themselves. Walkthrough:
341
339
  session touched afterwards) so you can tell which memory is earning its keep; they never
342
340
  travel, and `SIDEGRAPH_TELEMETRY=off` disables them.
343
341
  - **Secrets don't enter memory.** Proposed decisions and facts pass redaction before they
344
- are stored; a ratification gate — human by default, or an opt-in stamped policy — controls
345
- what the agent's drafts can persist.
342
+ are stored. A ratification gate controls what the agent's drafts can persist: human for
343
+ `adr`/`constraint` decisions and domains always, and, if you answer yes to `sidegraph-init`'s
344
+ question (or set `SIDEGRAPH_RATIFY_POLICY` yourself), an auto-ratification stamp for lessons,
345
+ gotchas, and standalone facts instead of a person's review.
346
346
  - **Nothing is silently rewritten.** The store is append-only; every change of mind is
347
347
  recorded as a supersession with its reason.
348
348
 
@@ -359,7 +359,7 @@ and permanent. That split is the design: **own the memory, rent the graph.**
359
359
 
360
360
  ## Status
361
361
 
362
- v0.1.0, on PyPI as [`sidegraph`](https://pypi.org/project/sidegraph/) (`pip install sidegraph`)
362
+ v0.2.0, on PyPI as [`sidegraph`](https://pypi.org/project/sidegraph/) (`pip install sidegraph`)
363
363
  — also installable via the Claude Code plugin or directly from git (see Quickstart).
364
364
  Published by a tag-triggered GitHub Actions workflow that gates on the full test suite
365
365
  (trusted publishing, no stored token). Interfaces may still move before 1.0. The full loop — capture, ratification,
@@ -367,8 +367,8 @@ mistakes-first retrieval, refactor-surviving re-anchoring, semantic docs layer,
367
367
  mind-model layer (named domains, `SessionStart` table of contents, `drill_down`), and now the
368
368
  facts layer (evidence attached to a decision or anchored standalone) — is exercised
369
369
  end-to-end on real code and ADR corpora (a 4,700-node Python trading system and a 15-document
370
- architecture corpus), with 2,339 tests as of this writing (a public checkout runs 2,196: the
371
- four release-mechanics test files that read `tools/` aren't shipped, since `tools/` itself
370
+ architecture corpus), with 2,462 tests as of this writing (a public checkout runs 2,240: the
371
+ seven release-mechanics test files that read `tools/` aren't shipped, since `tools/` itself
372
372
  isn't shipped, and 3 internal-corpus calibration tests skip — they need a private design
373
373
  corpus not included here). Exact counts drift as tests are added; the `tests` badge above
374
374
  tracks the suite passing, not a frozen number.
@@ -108,9 +108,6 @@ install above is all it needs.
108
108
  uv tool install sidegraph # from PyPI — puts sidegraph-init / sidegraph-mcp / … on PATH
109
109
  sidegraph-init
110
110
 
111
- # Optional day-one seeding: import the rationale already sitting in your docstrings
112
- sidegraph-import --dry-run
113
-
114
111
  # Prefer the latest unreleased build straight from git instead of PyPI? Swap step 3 for:
115
112
  # uvx --from git+https://github.com/SantyagoSeaman/sidegraph.git@main sidegraph-init
116
113
  ```
@@ -162,9 +159,11 @@ commoditize: better models make derivable knowledge cheaper, not the non-derivab
162
159
 
163
160
  **For the process** — a sidecar, not a reform: it sits beside whatever spec/ADR flow you
164
161
  already run, capture is a byproduct of ordinary sessions, and the single ritual is a
165
- ratification gate — human by default, or a stamped auto-ratification policy where no human is
166
- in the loop. Provenance on every record (who decided, when, on what evidence)
167
- is a ready audit trail for the era of agent-made decisions.
162
+ ratification gate, human by default, or `auto-low-risk`: lessons, gotchas, and standalone
163
+ facts self-ratify at write time, while `adr`/`constraint` decisions and domains still wait
164
+ for a human either way. `sidegraph-init` asks which you want (default answer: yes) and
165
+ commits the choice to `.claude/settings.json`. Provenance on every record (who decided,
166
+ when, on what evidence) is a ready audit trail for the era of agent-made decisions.
168
167
 
169
168
  One honest boundary, stated up front: this is not "cheaper agents in general." Memory
170
169
  pays off where it replaces reading prose and where the answer isn't in the code at all;
@@ -192,7 +191,7 @@ real code graph, with temporal history.
192
191
  | Knows *what was tried and rejected* | ✗ | ✗ | sometimes | ✗ | ✗ | ✓ first-class `rejected` field |
193
192
  | Anchored to the code it concerns | ✗ | ✗ | ✗ | ✓ | partially — concept links, not code | ✓ and survives refactors ([how](docs/guides/surviving-refactors.md)) |
194
193
  | Temporal validity & supersession | ✗ edit-in-place | ✗ | sometimes a status header | ✗ | ✗ | ✓ append-only: `valid_from`/`valid_to`, `supersedes` chains |
195
- | Human gate on what enters memory | ✓ | ✗ | ✓ | ✗ | ✓ curated like code | ✓ ratification loop |
194
+ | Human gate on what enters memory | ✓ | ✗ | ✓ | ✗ | ✓ curated like code | ✓ gated for `adr`/`constraint`/domains, auto for low-risk kinds |
196
195
  | Lives in your repo, merges like code | ✓ | ✗ opaque store | ✓ | ✗ per-tool cache | ✓ | ✓ file-per-record log, ratified in the PR diff |
197
196
  | Health is CI-gateable | ✗ | ✗ | ✗ | ✗ | ✓ `okf validate` | ✓ `sidegraph-verify` + `sidegraph-doctor` exit codes |
198
197
 
@@ -283,24 +282,23 @@ in its own `## Known facts` block — never displacing a mistake line. Details:
283
282
 
284
283
  CLIs: `sidegraph-bootstrap` (reviewed cold-start import and production proof),
285
284
  `sidegraph-init` (initialize the store), `sidegraph-domains` (bootstrap/name domains),
286
- `sidegraph-import` (seed from existing rationale or ADR/spec markdown), `sidegraph-ratify`
287
- (gate drafts), `sidegraph-sync` (re-anchor after a rebuild), `sidegraph-compact` (archive
288
- closed decisions/domains), `sidegraph-verify` (lint store integrity; `--against <git-ref>`
289
- for CI). See [docs/guides/ci-cd-maintenance.md](docs/guides/ci-cd-maintenance.md) for
290
- GitHub Actions recipes built on `sidegraph-sync --check`/`sidegraph-verify`.
285
+ `sidegraph-ratify` (gate drafts), `sidegraph-sync` (re-anchor after a rebuild),
286
+ `sidegraph-compact` (archive closed decisions/domains), `sidegraph-verify` (lint store
287
+ integrity; `--against <git-ref>` for CI). See
288
+ [docs/guides/ci-cd-maintenance.md](docs/guides/ci-cd-maintenance.md) for GitHub Actions
289
+ recipes built on `sidegraph-sync --check`/`sidegraph-verify`.
291
290
  Reference: [docs/reference/](docs/reference/mcp-tools.md).
292
291
 
293
292
  ## Works on code and on docs
294
293
 
295
294
  Anchor decisions to functions and classes — or to **headings in your architecture
296
- markdown** (LLM-free graph build, non-git folders supported). `sidegraph-import`
297
- seeds the store from rationale already sitting in your sources: docstrings with zero
298
- extra setup, and — via `--docs` — your existing ADRs and design specs, parsed into
299
- anchored decisions deterministically, no LLM.
295
+ markdown** (LLM-free graph build, non-git folders supported). Already have ADRs or
296
+ design specs? `sidegraph-bootstrap` parses them into anchored decisions deterministically,
297
+ no LLM. See the [Bootstrap guide](docs/getting-started/bootstrap.md).
300
298
 
301
299
  An optional **semantic pass** (`graphify extract`, one API key, cached per file) goes a
302
- layer deeper on documentation: prose becomes `concept` nodes and thematic clusters, and
303
- import picks up rationale from the documents themselves. Walkthrough:
300
+ layer deeper on documentation: prose becomes `concept` nodes and thematic clusters, giving
301
+ retrieval a richer graph to anchor against. Walkthrough:
304
302
  [docs/guides/semantic-docs.md](docs/guides/semantic-docs.md).
305
303
 
306
304
  ## Trust & privacy
@@ -313,8 +311,10 @@ import picks up rationale from the documents themselves. Walkthrough:
313
311
  session touched afterwards) so you can tell which memory is earning its keep; they never
314
312
  travel, and `SIDEGRAPH_TELEMETRY=off` disables them.
315
313
  - **Secrets don't enter memory.** Proposed decisions and facts pass redaction before they
316
- are stored; a ratification gate — human by default, or an opt-in stamped policy — controls
317
- what the agent's drafts can persist.
314
+ are stored. A ratification gate controls what the agent's drafts can persist: human for
315
+ `adr`/`constraint` decisions and domains always, and, if you answer yes to `sidegraph-init`'s
316
+ question (or set `SIDEGRAPH_RATIFY_POLICY` yourself), an auto-ratification stamp for lessons,
317
+ gotchas, and standalone facts instead of a person's review.
318
318
  - **Nothing is silently rewritten.** The store is append-only; every change of mind is
319
319
  recorded as a supersession with its reason.
320
320
 
@@ -331,7 +331,7 @@ and permanent. That split is the design: **own the memory, rent the graph.**
331
331
 
332
332
  ## Status
333
333
 
334
- v0.1.0, on PyPI as [`sidegraph`](https://pypi.org/project/sidegraph/) (`pip install sidegraph`)
334
+ v0.2.0, on PyPI as [`sidegraph`](https://pypi.org/project/sidegraph/) (`pip install sidegraph`)
335
335
  — also installable via the Claude Code plugin or directly from git (see Quickstart).
336
336
  Published by a tag-triggered GitHub Actions workflow that gates on the full test suite
337
337
  (trusted publishing, no stored token). Interfaces may still move before 1.0. The full loop — capture, ratification,
@@ -339,8 +339,8 @@ mistakes-first retrieval, refactor-surviving re-anchoring, semantic docs layer,
339
339
  mind-model layer (named domains, `SessionStart` table of contents, `drill_down`), and now the
340
340
  facts layer (evidence attached to a decision or anchored standalone) — is exercised
341
341
  end-to-end on real code and ADR corpora (a 4,700-node Python trading system and a 15-document
342
- architecture corpus), with 2,339 tests as of this writing (a public checkout runs 2,196: the
343
- four release-mechanics test files that read `tools/` aren't shipped, since `tools/` itself
342
+ architecture corpus), with 2,462 tests as of this writing (a public checkout runs 2,240: the
343
+ seven release-mechanics test files that read `tools/` aren't shipped, since `tools/` itself
344
344
  isn't shipped, and 3 internal-corpus calibration tests skip — they need a private design
345
345
  corpus not included here). Exact counts drift as tests are added; the `tests` badge above
346
346
  tracks the suite passing, not a frozen number.
@@ -35,6 +35,14 @@ It runs everything via `uvx --from git+https://github.com/SantyagoSeaman/sidegra
35
35
  under the hood, so it builds straight from this repository, no PyPI publish needed. See
36
36
  [the plugin install path](../integrations/codex.md#plugin-install-path) for exactly what
37
37
  gets registered and the cwd-pinning details, and what has and hasn't been verified live.
38
+
39
+ 1. Trust the hooks: start an interactive `codex` session in the repo. Codex detects the two
40
+ new Sidegraph hook definitions (`SessionStart`, `Stop`) and prompts you in the terminal to
41
+ trust them. Approve to complete it. Skip or decline and the MCP tools still work, but
42
+ retrieval at session start and the capture reminder at session end stay silent. A hook
43
+ definition change in a later release needs a fresh approval. Review or re-approve anytime
44
+ with `/hooks`.
45
+
38
46
  Skip to [Verify](#verify) once installed.
39
47
 
40
48
  ## Option B: manual registration
@@ -2,8 +2,14 @@
2
2
 
3
3
  Two ways a decision enters the store: the agent writes it **directly** mid-session
4
4
  (`add_decision`), or the session gets **distilled and proposed** at the end and is ratified
5
- later — by a human by default (`propose_decisions` → `sidegraph-ratify`), or at write time by
6
- an opt-in [auto-ratification policy](#5-auto-ratification-policy-opt-in). Both paths write into the same
5
+ later, by a human (`propose_decisions` → `sidegraph-ratify`) or at write time by an
6
+ [auto-ratification policy](#5-auto-ratification-policy-opt-in). The library default is
7
+ `manual`; `sidegraph-init` asks, in an interactive terminal, whether a fresh project should
8
+ auto-ratify instead, defaulting the answer to yes (`auto-low-risk`); a person's choice is
9
+ committed to `.claude/settings.json` either way, and a non-interactive run (CI, a script, an
10
+ agent-driven session) changes nothing. Under `auto-low-risk`, eligible `lesson`/`gotcha`
11
+ decisions and standalone facts self-ratify at write time; `adr`/`constraint` decisions and
12
+ domains still wait for a human regardless of policy. Both paths write into the same
7
13
  append-only store; see [`reference/mcp-tools.md`](../reference/mcp-tools.md) for exact tool
8
14
  signatures. Three plugin skills carry this guide's discipline into the session itself:
9
15
  [`sidegraph:record-decision`](../../plugin/sidegraph/skills/record-decision/SKILL.md) (the
@@ -53,7 +53,8 @@ deterministic ladder, one rung at a time, and the first rung that fires wins:
53
53
  |---|---|---|
54
54
  | `unchanged` | Exact `name`+`file_path` match, same node id as last sync | Leaf binding stays `live`; still checks for community re-pointing (below). |
55
55
  | `rebound` | Exact `name`+`file_path` match, but the node id changed | Leaf binding stays/returns to `live`, mapping refreshed to the new node id. |
56
- | `moved` | No exact match, but a *unique* name-only match exists **in a file of the same suffix**, **and the entity's old `file_path` is confirmed gone from disk** | The entity's `descriptor.file_path` is updated to follow it; leaf binding heals to `live`. A same-name hit in a file of a *different* suffix (e.g. a vanished code symbol colliding with an unrelated doc heading) is treated as a collision, not a move, and falls through to orphaned instead — as does any hit whose old path is still on disk (below). |
56
+ | `moved` | No exact match, but a *unique* name-only match exists **in a file of the same suffix**, **the entity's old `file_path` is confirmed gone from disk**, AND that same move is **independently confirmed by committed git history** (old path absent, new path tracked — both at `HEAD`) | The entity's `descriptor.file_path` is updated to follow it; leaf binding heals to `live`. A same-name hit in a file of a *different* suffix (e.g. a vanished code symbol colliding with an unrelated doc heading) is treated as a collision, not a move, and falls through to orphaned instead — as does any hit whose old path is still on disk (below). |
57
+ | `moved_uncommitted` | Same disk-level evidence as `moved` (unique same-suffix hit, old path gone from disk), but git's committed history at `HEAD` does not yet confirm it — an uncommitted delete, rename, or stash on this one working tree | Nothing is touched — the binding, descriptor, and node mapping are all left exactly as they were. Commit the move (or set `SIDEGRAPH_TRUST_DIRTY_TREE=on`, see below) and re-sync. |
57
58
  | `ambiguous` | More than one node now matches | Leaf binding flips to `degraded` (not deleted). If every candidate shares one community, that community is still used for re-pointing. |
58
59
  | `orphaned` | No match at all, exact or loose | Leaf binding flips to `orphaned`. If the entity's file still exists and its nodes agree on a single community, that community is used for re-pointing (see below) — Sidegraph is not guessing which node the entity *became*, only where its code still lives. |
59
60
 
@@ -78,6 +79,21 @@ for the whole pass: nothing is adopted, and every candidate that would have move
78
79
  and repairable with [`sidegraph:heal-anchors`](../../plugin/sidegraph/skills/heal-anchors/SKILL.md);
79
80
  a wrong adoption is silent, and silence is the worse failure.
80
81
 
82
+ The disk check alone is not enough, though: it reflects whatever this one working tree
83
+ looks like *right now*, and an uncommitted `rm`/`git mv`/`git stash` makes the old path
84
+ disappear from disk just as convincingly as a real, shared move. Since `moved` rewrites the
85
+ entity's canonical, **repo-committed** `descriptor` — the same file every other clone reads —
86
+ trusting a purely local, unshared change there would let one person's dirty tree silently
87
+ corrupt the team's memory. So the rung requires a *third* signal before it adopts: the same
88
+ move confirmed by **committed** history, via `git cat-file -e HEAD:<path>` — the old path
89
+ absent from `HEAD`'s tree, and the new path present in it. When the disk-level evidence looks
90
+ like a move but git's `HEAD` doesn't yet back it up, the rung reports `moved_uncommitted` and
91
+ leaves everything untouched instead of guessing; committing the move (or, on a fresh
92
+ repository with no commits yet, making one) and re-running sync heals it the normal way, no
93
+ different from any other rung. For the rare case of someone who has verified their own
94
+ working tree and wants the old, disk-only behavior back, `SIDEGRAPH_TRUST_DIRTY_TREE=on`
95
+ is a documented, off-by-default escape hatch scoped to exactly this one check.
96
+
81
97
  ## Community re-pointing
82
98
 
83
99
  Leiden community ids are **snapshot labels, not identities** — a rebuild can renumber every
@@ -171,9 +187,11 @@ needing another sync pass.
171
187
 
172
188
  Nothing in the rebind ladder silently re-anchors a decision to a *different* entity that
173
189
  merely looks plausible. `moved` only fires on a **unique** name-only hit within the same file
174
- type **whose old path is confirmed gone from disk** (see [why `moved` checks the
175
- disk](#why-moved-checks-the-disk)); anything with more than one candidate is `ambiguous`, not
176
- resolved, and anything unverifiable stays `orphaned`. An `ambiguous` or
190
+ type **whose old path is confirmed gone from disk AND confirmed by committed git history**
191
+ (see [why `moved` checks the disk](#why-moved-checks-the-disk)); anything with more than one
192
+ candidate is `ambiguous`, not resolved; anything unverifiable stays `orphaned`; and disk-level
193
+ evidence git's `HEAD` doesn't yet back up reports `moved_uncommitted` rather than adopting on
194
+ a dirty tree. An `ambiguous` or
177
195
  `orphaned` entity's `last_seen_node_id` is **never** touched by the community re-pointing
178
196
  path — only community/Tier-1 bindings move, never the leaf's node mapping. If Sidegraph can't
179
197
  say for certain "this is the same thing," it says so (`ambiguous`/`orphaned`) instead of
@@ -121,6 +121,13 @@ Sidegraph also ships a Codex plugin, the same one-line install as the Claude Cod
121
121
  /plugin install sidegraph@sidegraph
122
122
  ```
123
123
 
124
+ 1. Trust the hooks: start an interactive `codex` session in the repo. Codex detects the two
125
+ new Sidegraph hook definitions (`SessionStart`, `Stop`) and prompts you in the terminal to
126
+ trust them. Approve to complete it. Skip or decline and the MCP tools still work, but
127
+ retrieval at session start and the capture reminder at session end stay silent (see why
128
+ below). A hook definition change in a later release needs a fresh approval. Review or
129
+ re-approve anytime with `/hooks`.
130
+
124
131
  This is the same repo-committed manifest set the Claude Code plugin uses, in Codex's own
125
132
  shape: `.agents/plugins/marketplace.json` at the repo root, and
126
133
  `plugin/sidegraph/.codex-plugin/plugin.json` naming the MCP config
@@ -140,14 +147,37 @@ plugin-provided variable, is what keeps `SIDEGRAPH_DIR`/`SIDEGRAPH_GRAPH` pointe
140
147
  repo.
141
148
 
142
149
  What was verified live (codex-cli 0.154.0, a throwaway `CODEX_HOME`): `codex plugin
143
- marketplace add` parses `.agents/plugins/marketplace.json` and resolves the plugin at
150
+ marketplace add SantyagoSeaman/sidegraph` fetches the published repository by the
151
+ `owner/repo` shorthand, parses `.agents/plugins/marketplace.json` and resolves the plugin at
144
152
  `./plugin/sidegraph`. `codex plugin add sidegraph@sidegraph` installs it, copying
145
153
  `.codex-plugin/plugin.json`, `codex/mcp.json`, `codex/hooks.json`, and every skill's
146
154
  `agents/openai.yaml` into the plugin cache unchanged. `codex mcp list --json` shows the
147
- `sidegraph` server registered with the exact command from `codex/mcp.json`. What was **not**
148
- independently verified: an actual `SessionStart`/`Stop` hook firing end to end inside a real,
149
- authenticated Codex session. The CLI exposes no "list installed hooks" introspection command
150
- this checkout could use to confirm it short of a live session. Also unverified against the
155
+ `sidegraph` server registered with the exact command from `codex/mcp.json`, and a
156
+ non-interactive `codex exec` session with that server registered called the Sidegraph tools
157
+ (`retrieve_decisions`, `list_proposed`, `query_decisions`, `find_entity`) and got real
158
+ records back. `SessionStart` and `Stop` did not fire in that session, and that is expected,
159
+ not a bug. Codex gates hooks with two independent checks. Project trust (`trust_level` in
160
+ `config.toml`) is one. Hook trust is separate and hash-based: Codex records trust against a
161
+ hook definition's current hash and refuses to run a hook it has not seen approved at that
162
+ hash. Installing or enabling a plugin does not grant hook trust. Per the [Codex hooks
163
+ docs](https://learn.chatgpt.com/codex/hooks), Codex skips plugin-bundled hooks until the user
164
+ reviews and trusts the current hook definition. Observed on a real machine running codex-cli
165
+ 0.154.0, not documented as a guarantee: after `codex plugin add sidegraph@sidegraph`, the
166
+ first interactive `codex` session detects the two new hook definitions and prompts in the
167
+ terminal to trust them, and answering yes completes the approval. No `/hooks` visit is needed
168
+ for that normal path. A non-interactive `codex exec` session never shows the prompt at all,
169
+ which is exactly why automation needs the bypass below. `/hooks` is the surface for reviewing
170
+ what is trusted and for re-approving after a hook definition changes, since trust is recorded
171
+ per-hash. There is no config-file way to pre-approve it. The only bypass is `codex exec
172
+ --dangerously-bypass-hook-trust`, which the docs themselves flag as dangerous and intended for
173
+ automation that already vets its hook sources, not as the normal path. So after `/plugin
174
+ install sidegraph@sidegraph`, the MCP server works immediately but `SessionStart` and `Stop`
175
+ stay silent until that one-time approval. What was verified without
176
+ a live, trusted Codex session: the hook entry points themselves honor the Codex JSON contract.
177
+ Fed Codex-shaped payloads on stdin, `sidegraph-session-start` wrote the session telemetry row
178
+ and returned `hookSpecificOutput.additionalContext`; `sidegraph-stop` wrote a
179
+ `capture_sessions` row and returned its reminder when the transcript passed the substance
180
+ gate, and correctly wrote nothing when it did not. Also unverified against the
151
181
  published docs: the top-level `mcpServers`/`hooks` fields in `.codex-plugin/plugin.json` are
152
182
  not documented on `developers.openai.com/plugins/build/plugins` as of this writing, which
153
183
  instead sketches an `extensions.com.openai` nesting. The live install above is the evidence