sidegraph 0.4.0__tar.gz → 0.6.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.
- {sidegraph-0.4.0 → sidegraph-0.6.0}/.github/workflows/ci.yml +0 -40
- sidegraph-0.6.0/.github/workflows/session-link-gate.yml +76 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/.gitleaks.toml +1 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/.pre-commit-config.yaml +13 -12
- {sidegraph-0.4.0 → sidegraph-0.6.0}/CHANGELOG.md +300 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/CLAUDE.md +6 -5
- {sidegraph-0.4.0 → sidegraph-0.6.0}/PKG-INFO +5 -4
- {sidegraph-0.4.0 → sidegraph-0.6.0}/README.md +4 -3
- {sidegraph-0.4.0 → sidegraph-0.6.0}/SECURITY.md +13 -5
- {sidegraph-0.4.0 → sidegraph-0.6.0}/docs/concepts/anchoring.md +19 -11
- {sidegraph-0.4.0 → sidegraph-0.6.0}/docs/concepts/data-model.md +3 -2
- {sidegraph-0.4.0 → sidegraph-0.6.0}/docs/concepts/retrieval.md +2 -1
- {sidegraph-0.4.0 → sidegraph-0.6.0}/docs/getting-started/bootstrap.md +5 -1
- {sidegraph-0.4.0 → sidegraph-0.6.0}/docs/getting-started/installation.md +8 -5
- {sidegraph-0.4.0 → sidegraph-0.6.0}/docs/guides/capturing-decisions.md +2 -1
- {sidegraph-0.4.0 → sidegraph-0.6.0}/docs/guides/retrieval-in-sessions.md +2 -2
- {sidegraph-0.4.0 → sidegraph-0.6.0}/docs/guides/semantic-docs.md +2 -2
- {sidegraph-0.4.0 → sidegraph-0.6.0}/docs/guides/surviving-refactors.md +18 -9
- {sidegraph-0.4.0 → sidegraph-0.6.0}/docs/integrations/claude-code.md +9 -5
- {sidegraph-0.4.0 → sidegraph-0.6.0}/docs/integrations/graphify.md +13 -8
- {sidegraph-0.4.0 → sidegraph-0.6.0}/docs/reference/cli.md +185 -70
- {sidegraph-0.4.0 → sidegraph-0.6.0}/docs/reference/configuration.md +37 -10
- {sidegraph-0.4.0 → sidegraph-0.6.0}/docs/reference/hooks.md +23 -13
- {sidegraph-0.4.0 → sidegraph-0.6.0}/docs/reference/mcp-tools.md +69 -21
- {sidegraph-0.4.0 → sidegraph-0.6.0}/docs/reference/releasing.md +30 -4
- {sidegraph-0.4.0 → sidegraph-0.6.0}/docs/reference/store-format.md +64 -4
- {sidegraph-0.4.0 → sidegraph-0.6.0}/plugin/sidegraph/.claude-plugin/plugin.json +1 -1
- {sidegraph-0.4.0 → sidegraph-0.6.0}/plugin/sidegraph/.codex-plugin/plugin.json +1 -1
- {sidegraph-0.4.0 → sidegraph-0.6.0}/plugin/sidegraph/skills/heal-anchors/SKILL.md +4 -2
- {sidegraph-0.4.0 → sidegraph-0.6.0}/plugin/sidegraph/skills/import-adrs/SKILL.md +23 -7
- {sidegraph-0.4.0 → sidegraph-0.6.0}/plugin/sidegraph/skills/record-decision/SKILL.md +3 -2
- {sidegraph-0.4.0 → sidegraph-0.6.0}/plugin/sidegraph/skills/record-fact/SKILL.md +4 -2
- {sidegraph-0.4.0 → sidegraph-0.6.0}/plugin/sidegraph/skills/stats/SKILL.md +6 -5
- {sidegraph-0.4.0 → sidegraph-0.6.0}/pyproject.toml +1 -1
- {sidegraph-0.4.0 → sidegraph-0.6.0}/src/sidegraph/__init__.py +1 -1
- {sidegraph-0.4.0 → sidegraph-0.6.0}/src/sidegraph/anchoring.py +3 -20
- {sidegraph-0.4.0 → sidegraph-0.6.0}/src/sidegraph/bootstrap/catalog.py +44 -9
- {sidegraph-0.4.0 → sidegraph-0.6.0}/src/sidegraph/bootstrap/cli.py +68 -29
- {sidegraph-0.4.0 → sidegraph-0.6.0}/src/sidegraph/bootstrap/integrations.py +23 -5
- {sidegraph-0.4.0 → sidegraph-0.6.0}/src/sidegraph/capture.py +532 -303
- {sidegraph-0.4.0 → sidegraph-0.6.0}/src/sidegraph/cli.py +263 -126
- {sidegraph-0.4.0 → sidegraph-0.6.0}/src/sidegraph/config.py +108 -5
- {sidegraph-0.4.0 → sidegraph-0.6.0}/src/sidegraph/doc_import.py +202 -43
- {sidegraph-0.4.0 → sidegraph-0.6.0}/src/sidegraph/doctor.py +5 -3
- {sidegraph-0.4.0 → sidegraph-0.6.0}/src/sidegraph/domains.py +2 -1
- {sidegraph-0.4.0 → sidegraph-0.6.0}/src/sidegraph/engine/reader.py +2 -0
- sidegraph-0.6.0/src/sidegraph/gitenv.py +41 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/src/sidegraph/gitio.py +2 -1
- sidegraph-0.6.0/src/sidegraph/host/claude_settings.py +244 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/src/sidegraph/host/hooks.py +32 -4
- {sidegraph-0.4.0 → sidegraph-0.6.0}/src/sidegraph/importer.py +15 -3
- {sidegraph-0.4.0 → sidegraph-0.6.0}/src/sidegraph/okf.py +260 -23
- {sidegraph-0.4.0 → sidegraph-0.6.0}/src/sidegraph/schema.py +11 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/src/sidegraph/server.py +157 -47
- {sidegraph-0.4.0 → sidegraph-0.6.0}/src/sidegraph/stats/model.py +7 -1
- {sidegraph-0.4.0 → sidegraph-0.6.0}/src/sidegraph/store.py +464 -55
- {sidegraph-0.4.0 → sidegraph-0.6.0}/src/sidegraph/sync.py +472 -57
- {sidegraph-0.4.0 → sidegraph-0.6.0}/src/sidegraph/verify.py +183 -26
- {sidegraph-0.4.0 → sidegraph-0.6.0}/tests/conftest.py +36 -7
- {sidegraph-0.4.0 → sidegraph-0.6.0}/tests/test_anchoring.py +2 -14
- {sidegraph-0.4.0 → sidegraph-0.6.0}/tests/test_bootstrap_catalog.py +91 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/tests/test_bootstrap_cli.py +257 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/tests/test_capture_auto_accept.py +0 -8
- {sidegraph-0.4.0 → sidegraph-0.6.0}/tests/test_capture_facts.py +0 -14
- sidegraph-0.6.0/tests/test_capture_initiative.py +185 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/tests/test_capture_neighbors.py +0 -7
- sidegraph-0.6.0/tests/test_capture_propose.py +802 -0
- sidegraph-0.6.0/tests/test_capture_redact.py +184 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/tests/test_cli_domains.py +39 -0
- sidegraph-0.6.0/tests/test_cli_graph_paths.py +535 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/tests/test_cli_import.py +283 -25
- {sidegraph-0.4.0 → sidegraph-0.6.0}/tests/test_cli_init.py +180 -0
- sidegraph-0.6.0/tests/test_cli_okf.py +819 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/tests/test_cli_stats.py +16 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/tests/test_cli_sync.py +12 -0
- sidegraph-0.6.0/tests/test_cli_unreadable_paths.py +261 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/tests/test_config.py +45 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/tests/test_doc_corpus_integration.py +0 -7
- {sidegraph-0.4.0 → sidegraph-0.6.0}/tests/test_doc_import.py +496 -6
- {sidegraph-0.4.0 → sidegraph-0.6.0}/tests/test_doctor.py +102 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/tests/test_env_isolation.py +3 -1
- sidegraph-0.6.0/tests/test_git_env.py +138 -0
- sidegraph-0.6.0/tests/test_host_claude_settings.py +554 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/tests/test_host_session_start.py +40 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/tests/test_host_stop.py +99 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/tests/test_importer.py +42 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/tests/test_okf.py +29 -1
- {sidegraph-0.4.0 → sidegraph-0.6.0}/tests/test_ratify_policy.py +32 -41
- {sidegraph-0.4.0 → sidegraph-0.6.0}/tests/test_repoint_integration.py +0 -7
- sidegraph-0.6.0/tests/test_sandbox_hygiene.py +328 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/tests/test_server_capture.py +115 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/tests/test_server_domains.py +40 -0
- sidegraph-0.6.0/tests/test_server_graph_path.py +268 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/tests/test_server_telemetry.py +20 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/tests/test_stats_model.py +17 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/tests/test_store_meta.py +12 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/tests/test_store_migration.py +404 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/tests/test_store_mutation_guard.py +6 -0
- sidegraph-0.6.0/tests/test_store_record_identity.py +407 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/tests/test_store_stamping_marker.py +6 -4
- sidegraph-0.6.0/tests/test_store_symlinks.py +79 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/tests/test_sync_clean.py +0 -7
- {sidegraph-0.4.0 → sidegraph-0.6.0}/tests/test_sync_fresh_clone.py +0 -7
- {sidegraph-0.4.0 → sidegraph-0.6.0}/tests/test_sync_integration.py +0 -7
- sidegraph-0.6.0/tests/test_sync_rebind.py +1310 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/tests/test_sync_repoint.py +170 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/tests/test_verify_snapshot.py +109 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/tests/test_verify_transitions.py +368 -0
- sidegraph-0.6.0/tools/check_no_session_links.py +167 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/uv.lock +5 -4
- sidegraph-0.4.0/src/sidegraph/host/claude_settings.py +0 -130
- sidegraph-0.4.0/tests/test_capture_propose.py +0 -417
- sidegraph-0.4.0/tests/test_capture_redact.py +0 -58
- sidegraph-0.4.0/tests/test_cli_okf.py +0 -230
- sidegraph-0.4.0/tests/test_host_claude_settings.py +0 -141
- sidegraph-0.4.0/tests/test_sandbox_hygiene.py +0 -133
- sidegraph-0.4.0/tests/test_sync_rebind.py +0 -457
- {sidegraph-0.4.0 → sidegraph-0.6.0}/.agents/plugins/marketplace.json +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/.claude-plugin/marketplace.json +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/.github/CODEOWNERS +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/.github/ISSUE_TEMPLATE/bug_report.yml +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/.github/ISSUE_TEMPLATE/config.yml +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/.github/ISSUE_TEMPLATE/feature_request.yml +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/.github/secret_scanning.yml +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/.github/workflows/publish.yml +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/.github/workflows/scorecard.yml +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/.gitignore +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/.python-version +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/AGENTS.md +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/CODE_OF_CONDUCT.md +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/CONTRIBUTING.md +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/LICENSE +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/docs/README.md +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/docs/concepts/decision-memory.md +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/docs/concepts/mind-model.md +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/docs/getting-started/claude-code-setup.md +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/docs/getting-started/codex-setup.md +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/docs/getting-started/quickstart.md +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/docs/guides/ci-cd-maintenance.md +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/docs/guides/naming-your-domains.md +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/docs/guides/team-workflow.md +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/docs/guides/verifying-your-setup.md +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/docs/integrations/codex.md +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/docs/llms.txt +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/docs/pilot-kit/README.md +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/docs/pilot-kit/corpus_fit.py +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/docs/pilot-kit/judge-prompt.md +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/docs/pilot-kit/questions-prompt.md +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/docs/pilot-kit/rubric-template.md +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/docs/reference/git-bindings.md +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/docs/reference/operations.md +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/docs/reference/stability.md +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/docs/whitepaper/index.md +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/plugin/sidegraph/.mcp.json +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/plugin/sidegraph/codex/hooks.json +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/plugin/sidegraph/codex/mcp.json +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/plugin/sidegraph/hooks/hooks.json +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/plugin/sidegraph/skills/check-plan/SKILL.md +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/plugin/sidegraph/skills/check-plan/agents/openai.yaml +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/plugin/sidegraph/skills/explain-why/SKILL.md +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/plugin/sidegraph/skills/explain-why/agents/openai.yaml +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/plugin/sidegraph/skills/heal-anchors/agents/openai.yaml +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/plugin/sidegraph/skills/import-adrs/agents/openai.yaml +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/plugin/sidegraph/skills/manage-domains/SKILL.md +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/plugin/sidegraph/skills/manage-domains/agents/openai.yaml +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/plugin/sidegraph/skills/name-domains/SKILL.md +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/plugin/sidegraph/skills/name-domains/agents/openai.yaml +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/plugin/sidegraph/skills/ratify-decisions/SKILL.md +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/plugin/sidegraph/skills/ratify-decisions/agents/openai.yaml +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/plugin/sidegraph/skills/record-decision/agents/openai.yaml +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/plugin/sidegraph/skills/record-fact/agents/openai.yaml +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/plugin/sidegraph/skills/setup/SKILL.md +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/plugin/sidegraph/skills/setup/agents/openai.yaml +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/plugin/sidegraph/skills/stats/agents/openai.yaml +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/plugin/sidegraph/skills/triage-drift/SKILL.md +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/plugin/sidegraph/skills/triage-drift/agents/openai.yaml +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/src/sidegraph/bootstrap/__init__.py +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/src/sidegraph/bootstrap/apply.py +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/src/sidegraph/bootstrap/model.py +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/src/sidegraph/bootstrap/planner.py +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/src/sidegraph/bootstrap/proof.py +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/src/sidegraph/bootstrap/review.py +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/src/sidegraph/bootstrap/scan.py +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/src/sidegraph/engine/__init__.py +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/src/sidegraph/host/__init__.py +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/src/sidegraph/profiles.py +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/src/sidegraph/retrieval.py +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/src/sidegraph/stats/__init__.py +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/src/sidegraph/stats/render.py +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/src/sidegraph/viz/__init__.py +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/src/sidegraph/viz/assets/vis-network.min.js +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/src/sidegraph/viz/model.py +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/src/sidegraph/viz/render.py +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/src/sidegraph/viz/template.html +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/tests/__init__.py +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/tests/fixtures/auto_policy/parity_goldens.json +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/tests/fixtures/bitfinex_slice.json +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/tests/fixtures/bootstrap/flows/bmad/_bmad-output/planning-artifacts/architecture/cache/ARCHITECTURE-SPINE.md +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/tests/fixtures/bootstrap/flows/generic-adr/docs/adr/001-retry.md +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/tests/fixtures/bootstrap/flows/genkovich-sdd/docs/features/cache/adr/001.md +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/tests/fixtures/bootstrap/flows/spec-kit/specs/cache/plan.md +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/tests/fixtures/bootstrap/flows/superpowers/docs/superpowers/specs/2026-07-01-cache-design.md +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/tests/fixtures/bootstrap/graph.json +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/tests/fixtures/bootstrap/hosts/claude/.claude/settings.json +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/tests/fixtures/bootstrap/hosts/claude/.mcp.json +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/tests/fixtures/bootstrap/hosts/codex/.codex/config.toml +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/tests/fixtures/bootstrap/hosts/codex/.codex/hooks/hooks.json +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/tests/fixtures/bootstrap/scan/docs/adr/001-safe.md +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/tests/fixtures/corpus/PUBLIC_CORPORA.txt +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/tests/fixtures/corpus/openspec/_provenance.json +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/tests/fixtures/corpus/openspec/graph.json +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/tests/fixtures/corpus/self-corpus/_provenance.json +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/tests/fixtures/corpus/self-corpus/expected/retrieval-engine-reader.md +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/tests/fixtures/corpus/self-corpus/graph.json +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/tests/fixtures/flows/adr/0001-use-sessions.md +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/tests/fixtures/flows/bmad/ARCHITECTURE-SPINE.md +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/tests/fixtures/flows/bmad/tree/_bmad-output/planning-artifacts/architecture/architecture-payments-2026-07-30/.memlog.md +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/tests/fixtures/flows/bmad/tree/_bmad-output/planning-artifacts/architecture/architecture-payments-2026-07-30/ARCHITECTURE-SPINE.md +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/tests/fixtures/flows/bmad/tree/_bmad-output/planning-artifacts/prds/prd-payments-2026-07-30/prd.md +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/tests/fixtures/flows/genkovich/0001-queue-backpressure.md +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/tests/fixtures/flows/genkovich/sad.md +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/tests/fixtures/flows/genkovich/tree/docs/features/payments/adr/0001-queue-backpressure.md +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/tests/fixtures/flows/genkovich/tree/docs/features/payments/sad.md +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/tests/fixtures/flows/genkovich/tree/docs/features/payments/spec.md +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/tests/fixtures/flows/openspec/design-empty.md +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/tests/fixtures/flows/openspec/design-h3-split.md +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/tests/fixtures/flows/openspec/design-with-summary.md +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/tests/fixtures/flows/openspec/design.md +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/tests/fixtures/flows/openspec/proposal-alternatives.md +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/tests/fixtures/flows/openspec/proposal.md +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/tests/fixtures/flows/openspec/tree/openspec/changes/add-thing/design.md +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/tests/fixtures/flows/openspec/tree/openspec/changes/add-thing/proposal.md +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/tests/fixtures/flows/openspec/tree/openspec/changes/add-thing/specs/cap/spec.md +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/tests/fixtures/flows/openspec/tree/openspec/changes/add-thing/tasks.md +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/tests/fixtures/flows/openspec/tree/openspec/changes/archive/2026-01-01-add-thing/design.md +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/tests/fixtures/flows/openspec/tree/openspec/changes/archive/2026-01-01-add-thing/proposal.md +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/tests/fixtures/flows/openspec/tree/openspec/config.yaml +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/tests/fixtures/flows/openspec/tree/openspec/specs/cap/spec.md +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/tests/fixtures/flows/spec-kit/plan.md +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/tests/fixtures/flows/spec-kit/tree/specs/003-payment-retries/plan.md +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/tests/fixtures/flows/spec-kit/tree/specs/003-payment-retries/spec.md +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/tests/fixtures/flows/superpowers/2026-07-01-example-design.md +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/tests/fixtures/flows/superpowers/2026-07-01-thin-design.md +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/tests/fixtures/mini_graph.json +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/tests/test_anchoring_mapping_refresh.py +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/tests/test_bootstrap_apply.py +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/tests/test_bootstrap_integrations.py +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/tests/test_bootstrap_model.py +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/tests/test_bootstrap_planner.py +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/tests/test_bootstrap_proof.py +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/tests/test_bootstrap_review.py +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/tests/test_bootstrap_scan.py +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/tests/test_capture_integration.py +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/tests/test_cli_compact.py +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/tests/test_cli_doctor.py +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/tests/test_cli_ratify.py +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/tests/test_cli_ratify_facts.py +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/tests/test_cli_sync_check.py +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/tests/test_cli_viz.py +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/tests/test_codex_plugin.py +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/tests/test_community_baseline.py +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/tests/test_corpus_expected_renders.py +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/tests/test_corpus_self_corpus.py +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/tests/test_coverage_telemetry_e2e.py +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/tests/test_digest_integrity.py +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/tests/test_docs_claims.py +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/tests/test_doctor_auto_share.py +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/tests/test_doctor_code_drift.py +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/tests/test_doctor_dangling_supports.py +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/tests/test_doctor_duplicate_entity.py +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/tests/test_doctor_graph_root_mismatch.py +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/tests/test_doctor_never_surfaced.py +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/tests/test_doctor_scan.py +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/tests/test_doctor_stale_instructions.py +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/tests/test_doctor_unratified_accept.py +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/tests/test_domains.py +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/tests/test_entity_duplicate_resolution.py +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/tests/test_entity_get_or_create_race.py +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/tests/test_fact_reachability_gate.py +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/tests/test_flow_profile.py +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/tests/test_git_bindings_blame.py +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/tests/test_git_bindings_hook.py +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/tests/test_git_bindings_provenance.py +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/tests/test_host_drift_nudge.py +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/tests/test_host_pretool.py +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/tests/test_host_session_key.py +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/tests/test_host_touch_events.py +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/tests/test_mind_model_additive_fields.py +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/tests/test_openspec_profile.py +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/tests/test_pathless_descriptor_adoption.py +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/tests/test_pilot_kit_corpus_fit.py +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/tests/test_proposal_lifecycle.py +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/tests/test_ratify_listing_gone_dark.py +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/tests/test_reader_community_labels.py +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/tests/test_reader_doc_nodes.py +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/tests/test_reader_graph.py +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/tests/test_reader_integration.py +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/tests/test_reader_nodes_in_file.py +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/tests/test_reader_perf.py +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/tests/test_reader_rationale.py +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/tests/test_reader_read.py +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/tests/test_reader_resolve.py +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/tests/test_reader_subdir_mismatch.py +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/tests/test_reader_version.py +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/tests/test_redaction_seeded.py +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/tests/test_retrieval_budget_counters.py +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/tests/test_retrieval_context.py +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/tests/test_retrieval_drift_marker.py +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/tests/test_retrieval_drilldown.py +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/tests/test_retrieval_facts.py +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/tests/test_retrieval_ids.py +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/tests/test_retrieval_integration.py +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/tests/test_retrieval_rank.py +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/tests/test_retrieval_seeds.py +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/tests/test_retrieval_shown_ids.py +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/tests/test_retrieval_terminal_evidence.py +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/tests/test_retrieval_thin_tools.py +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/tests/test_retrieval_toc.py +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/tests/test_retrieval_toptier.py +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/tests/test_retrieval_unratified.py +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/tests/test_schema_descriptor.py +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/tests/test_schema_domain.py +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/tests/test_schema_fact.py +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/tests/test_server_add_anchors.py +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/tests/test_server_anchoring.py +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/tests/test_server_coverage_events.py +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/tests/test_server_drilldown.py +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/tests/test_server_facts.py +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/tests/test_server_find_entity.py +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/tests/test_server_get_store.py +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/tests/test_server_get_task_context.py +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/tests/test_server_import.py +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/tests/test_server_mcp_smoke.py +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/tests/test_server_prewrite_anchor_validation.py +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/tests/test_server_ratify_facts.py +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/tests/test_server_redaction.py +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/tests/test_server_render_events.py +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/tests/test_server_supersede.py +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/tests/test_server_sync_anchors.py +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/tests/test_server_thin_tools.py +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/tests/test_server_verify.py +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/tests/test_stats_graph.py +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/tests/test_stats_render.py +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/tests/test_stats_skill.py +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/tests/test_stats_snapshot.py +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/tests/test_store.py +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/tests/test_store_atomic_write_tmp_names.py +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/tests/test_store_canonical_stat.py +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/tests/test_store_compact.py +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/tests/test_store_compact_review.py +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/tests/test_store_concurrent_open.py +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/tests/test_store_coverage_telemetry.py +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/tests/test_store_derived_community.py +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/tests/test_store_domains.py +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/tests/test_store_entities.py +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/tests/test_store_fact_cascade.py +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/tests/test_store_facts.py +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/tests/test_store_mutation_immediate.py +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/tests/test_store_opens_with_merged_duplicate.py +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/tests/test_store_persistence.py +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/tests/test_store_ratification.py +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/tests/test_store_rebuild_atomicity.py +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/tests/test_store_render_events.py +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/tests/test_store_retrieval.py +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/tests/test_store_slug_conflicts.py +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/tests/test_store_telemetry.py +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/tests/test_store_threading.py +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/tests/test_store_tmp_sweep_age.py +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/tests/test_sync_domains.py +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/tests/test_sync_drift_cache.py +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/tests/test_sync_report_has_findings.py +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/tests/test_sync_run.py +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/tests/test_sync_toc_cache.py +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/tests/test_sync_volatile_heal.py +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/tests/test_sync_wiring.py +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/tests/test_telemetry_retention.py +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/tests/test_viz_asset_packaged.py +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/tests/test_viz_model.py +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/tests/test_viz_render_html.py +0 -0
- {sidegraph-0.4.0 → sidegraph-0.6.0}/tests/test_viz_render_json.py +0 -0
|
@@ -105,49 +105,9 @@ jobs:
|
|
|
105
105
|
exit 0
|
|
106
106
|
fi
|
|
107
107
|
uv sync --locked
|
|
108
|
-
git fetch origin "$GITHUB_BASE_REF"
|
|
109
108
|
base="$(git merge-base "origin/$GITHUB_BASE_REF" HEAD)"
|
|
110
109
|
uv run sidegraph-verify --against "$base" --json
|
|
111
110
|
|
|
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
|
-
|
|
151
111
|
# Recipe 1 self-applied: rebuild the graph from scratch and fail on attention findings
|
|
152
112
|
# (stale decisions, empty/overbroad domains, slug conflicts, refresh failures). A
|
|
153
113
|
# cache-less rebuild was verified label-identical to the local cached graph and the
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
# The PR half of the owner ruling "never publish an external session link", shared with the
|
|
2
|
+
# `no-session-links` commit-msg hook (.pre-commit-config.yaml) through
|
|
3
|
+
# tools/check_no_session_links.py, so the rule cannot drift between them. A commit-msg hook
|
|
4
|
+
# cannot see a pull request's title or description, and a commit made without the hook never
|
|
5
|
+
# passes through it, so this checks all three places text gets published:
|
|
6
|
+
# - the PR title and description, verbatim (lines starting with `#` are markdown headings
|
|
7
|
+
# there, not comments), and the title again because the default merge commit carries it;
|
|
8
|
+
# - the PR's recorded commit messages, exactly as they sit in history.
|
|
9
|
+
# Its own workflow file, not a job in ci.yml, so `edited` can re-run it without re-running
|
|
10
|
+
# the whole CI on every description edit. Every event for an open PR runs both steps: an
|
|
11
|
+
# `edited` run that skipped the commit check would go green on the same head SHA and replace
|
|
12
|
+
# a red run in the checks view. Edits to a closed or merged PR skip the commit check, so old
|
|
13
|
+
# history is not re-checked. No `concurrency` block: with one, a later run could cancel an
|
|
14
|
+
# in-flight `synchronize` run and leave the commits unchecked. The job takes seconds.
|
|
15
|
+
# Fails closed: the checker ships in the public snapshot too, and a run without it fails
|
|
16
|
+
# instead of skipping, so deleting or moving it cannot turn the gate green.
|
|
17
|
+
# Actions are pinned to commit SHAs (the tag comment records the version).
|
|
18
|
+
name: session-link-gate
|
|
19
|
+
|
|
20
|
+
on:
|
|
21
|
+
pull_request:
|
|
22
|
+
types: [opened, edited, reopened, synchronize]
|
|
23
|
+
|
|
24
|
+
permissions:
|
|
25
|
+
contents: read
|
|
26
|
+
|
|
27
|
+
jobs:
|
|
28
|
+
pr-description-link-gate:
|
|
29
|
+
runs-on: ubuntu-latest
|
|
30
|
+
timeout-minutes: 5
|
|
31
|
+
steps:
|
|
32
|
+
# zizmor artipacked: this job never pushes; do not persist git credentials past checkout.
|
|
33
|
+
# fetch-depth 0: the commit step needs the whole base..head range.
|
|
34
|
+
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
|
|
35
|
+
with:
|
|
36
|
+
persist-credentials: false
|
|
37
|
+
fetch-depth: 0
|
|
38
|
+
|
|
39
|
+
- name: Check PR title and description for forbidden session links
|
|
40
|
+
# Title and body are untrusted (attacker-controlled on a fork PR), so they go through
|
|
41
|
+
# env vars rather than `${{ }}` in the script text, which would be a script-injection
|
|
42
|
+
# hole. `github.event.pull_request.body` is `null` for an empty description; GitHub
|
|
43
|
+
# renders that as an empty env var. Reported line numbers run two higher than in the
|
|
44
|
+
# body: the title and a blank line come first.
|
|
45
|
+
env:
|
|
46
|
+
PR_TITLE: ${{ github.event.pull_request.title }}
|
|
47
|
+
PR_BODY: ${{ github.event.pull_request.body }}
|
|
48
|
+
run: |
|
|
49
|
+
if [ ! -f tools/check_no_session_links.py ]; then
|
|
50
|
+
echo "::error::tools/check_no_session_links.py is missing; the session-link gate cannot run"
|
|
51
|
+
exit 1
|
|
52
|
+
fi
|
|
53
|
+
printf '%s\n\n%s\n' "$PR_TITLE" "$PR_BODY" > "$RUNNER_TEMP/pr-text.txt"
|
|
54
|
+
python3 tools/check_no_session_links.py --published "$RUNNER_TEMP/pr-text.txt"
|
|
55
|
+
|
|
56
|
+
- name: Check the PR's commit messages for forbidden session links
|
|
57
|
+
# Runs on every event for an open PR, description edits included: a green run with
|
|
58
|
+
# this step skipped would replace a red one on the same head SHA. A closed or merged
|
|
59
|
+
# PR (its commits predate this gate) is not re-checked. A SHA matches no pattern, so
|
|
60
|
+
# each reported line points into the commit named above it; on failure the step lists
|
|
61
|
+
# the `commit` start lines (SHAs and line numbers only, never the offending text).
|
|
62
|
+
if: github.event.pull_request.state == 'open'
|
|
63
|
+
env:
|
|
64
|
+
BASE_SHA: ${{ github.event.pull_request.base.sha }}
|
|
65
|
+
HEAD_SHA: ${{ github.event.pull_request.head.sha }}
|
|
66
|
+
run: |
|
|
67
|
+
if [ ! -f tools/check_no_session_links.py ]; then
|
|
68
|
+
echo "::error::tools/check_no_session_links.py is missing; the session-link gate cannot run"
|
|
69
|
+
exit 1
|
|
70
|
+
fi
|
|
71
|
+
git log --format='commit %H%n%B' "$BASE_SHA..$HEAD_SHA" > "$RUNNER_TEMP/pr-commits.txt"
|
|
72
|
+
python3 tools/check_no_session_links.py --published "$RUNNER_TEMP/pr-commits.txt" || {
|
|
73
|
+
echo "commit start lines in the checked log:"
|
|
74
|
+
grep -n '^commit ' "$RUNNER_TEMP/pr-commits.txt"
|
|
75
|
+
exit 1
|
|
76
|
+
}
|
|
@@ -28,5 +28,6 @@ paths = [
|
|
|
28
28
|
'''^tests/test_server_redaction\.py$''',
|
|
29
29
|
'''^design/superpowers/plans/2026-07-06-capture-ratification\.md$''',
|
|
30
30
|
'''^design/superpowers/plans/2026-07-10-facts-layer\.md$''',
|
|
31
|
+
'''^design/superpowers/reviews/2026-09-28-grok-whole-repo-review\.md$''',
|
|
31
32
|
'''^src/sidegraph/viz/assets/vis-network\.min\.js$''',
|
|
32
33
|
]
|
|
@@ -115,10 +115,11 @@ repos:
|
|
|
115
115
|
# nothing and would couple the gate to uv project discovery — which fails outright in a
|
|
116
116
|
# tree whose pyproject uv cannot parse (the release script's own test fixtures).
|
|
117
117
|
# The `test -f` guard exists because THIS FILE SHIPS: .pre-commit-config.yaml is in the
|
|
118
|
-
# release ALLOWLIST while tools/
|
|
119
|
-
# running `pre-commit run --all-files` inside it.
|
|
120
|
-
# would look for a checker that by design does
|
|
121
|
-
# the public repo's CI, and every public
|
|
118
|
+
# release ALLOWLIST while tools/ ships only the session-link checker, and the release
|
|
119
|
+
# script verifies the snapshot by running `pre-commit run --all-files` inside it.
|
|
120
|
+
# Without the guard, an always_run hook would look for a checker that by design does
|
|
121
|
+
# not exist there and fail every release, the public repo's CI, and every public
|
|
122
|
+
# contributor's first commit.
|
|
122
123
|
entry: bash -c 'test ! -f tools/corpus_leak.py || exec python3 tools/corpus_leak.py'
|
|
123
124
|
language: system
|
|
124
125
|
pass_filenames: false
|
|
@@ -139,8 +140,8 @@ repos:
|
|
|
139
140
|
# AGENTS.public.md) with no base counterpart, or a plugin manifest that still points
|
|
140
141
|
# at the working tree instead of the released package, would otherwise ship broken
|
|
141
142
|
# and surface only when a consumer's install fails. Self-guarded like
|
|
142
|
-
# corpus-leak-gate: tools/
|
|
143
|
-
# exist in the public snapshot or its CI.
|
|
143
|
+
# corpus-leak-gate: tools/ ships only the session-link checker, so this checker does
|
|
144
|
+
# not exist in the public snapshot or its CI.
|
|
144
145
|
entry: bash -c 'test ! -f tools/check_public_twins.py || exec python3 tools/check_public_twins.py'
|
|
145
146
|
language: system
|
|
146
147
|
pass_filenames: false
|
|
@@ -150,8 +151,8 @@ repos:
|
|
|
150
151
|
name: shipped-docs link check
|
|
151
152
|
# A relative Markdown link that resolves in THIS repo can still 404 once the release
|
|
152
153
|
# mapping is applied (design/whitepaper/draft.md -> docs/whitepaper/index.md, `.public.`
|
|
153
|
-
# twins renamed onto their base names, design/
|
|
154
|
-
# before the commit lands. Self-guarded: tools/
|
|
154
|
+
# twins renamed onto their base names, design/ absent, tools/ reduced to the
|
|
155
|
+
# session-link checker) — this catches that before the commit lands. Self-guarded: tools/ ships only the session-link checker.
|
|
155
156
|
entry: bash -c 'test ! -f tools/check_shipped_links.py || exec python3 tools/check_shipped_links.py'
|
|
156
157
|
language: system
|
|
157
158
|
pass_filenames: false
|
|
@@ -161,15 +162,15 @@ repos:
|
|
|
161
162
|
name: no session links in commit message
|
|
162
163
|
# Reads the commit message file git passes a commit-msg hook, never the changed
|
|
163
164
|
# files — the forbidden patterns are tools/check_no_session_links.py's four
|
|
164
|
-
# session-link shapes, the same ones .github/workflows/
|
|
165
|
-
#
|
|
165
|
+
# session-link shapes, the same ones .github/workflows/session-link-gate.yml
|
|
166
|
+
# checks against a PR's title, body and recorded commit messages.
|
|
166
167
|
# `stages: [commit-msg]` is load-bearing, not decoration: a hook with no explicit
|
|
167
168
|
# `stages` inherits EVERY stage, and `pre-commit run --all-files` (CI's lint job, and
|
|
168
169
|
# a developer's own habit) defaults to `--hook-stage pre-commit` — without this pin,
|
|
169
170
|
# that plain run would try to execute this hook anyway, with no COMMIT_EDITMSG file
|
|
170
171
|
# to check, and fail every lint run for a reason that has nothing to do with lint.
|
|
171
|
-
# Self-guarded like corpus-leak-gate
|
|
172
|
-
#
|
|
172
|
+
# Self-guarded like corpus-leak-gate, though the checker does ship: the guard only covers a
|
|
173
|
+
# deleted checker, and the session-link-gate workflow is the gate that fails then.
|
|
173
174
|
entry: bash -c 'test ! -f tools/check_no_session_links.py || exec python3 tools/check_no_session_links.py "$@"' --
|
|
174
175
|
language: system
|
|
175
176
|
stages: [commit-msg]
|
|
@@ -7,6 +7,306 @@ interfaces, exactly, and what each one promises: [`docs/reference/stability.md`]
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [0.6.0] — 2026-10-01
|
|
11
|
+
|
|
12
|
+
### Added
|
|
13
|
+
|
|
14
|
+
- **`sidegraph-verify` reports `unsafe-record-id`.** A record file, `bindings/` file or
|
|
15
|
+
archive line whose id is not a single safe path segment is now a finding, and a
|
|
16
|
+
non-string id in a record or archive file no longer crashes the run with `unhashable type`.
|
|
17
|
+
- **`sidegraph-verify` reports a symlinked store entry as `symlinked-store-entry`.** One
|
|
18
|
+
violation per store-owned directory or file that is a symlink, so a committed link fails the
|
|
19
|
+
CI gate; `sidegraph-doctor` inherits it.
|
|
20
|
+
|
|
21
|
+
### Changed
|
|
22
|
+
|
|
23
|
+
- **A `--graph` typed as a relative path resolves against the shell in `sidegraph-ratify`
|
|
24
|
+
and `sidegraph-stats`.** It used to resolve against the store's project. The default and
|
|
25
|
+
`$SIDEGRAPH_GRAPH` still follow the store. The same holds in every command that reads a
|
|
26
|
+
graph, so the copy-and-sync workflow works with `--graph graphify-out/graph.json` typed from
|
|
27
|
+
the repository.
|
|
28
|
+
- **A store in a nested directory needs an absolute `SIDEGRAPH_GRAPH`.** With
|
|
29
|
+
`SIDEGRAPH_DIR=.config/sidegraph` and a relative `SIDEGRAPH_GRAPH`, the CLI now looks for the
|
|
30
|
+
graph under `.config/` (the store's project) instead of using the shell's copy. A command
|
|
31
|
+
that needs the graph fails with a hint; `init`, `ratify`, `doctor` and `stats`, for which it
|
|
32
|
+
is optional, continue and print the hint (`stats` reports its graph metrics as unavailable). Set an absolute `SIDEGRAPH_GRAPH` or pass `--graph`. The MCP server now
|
|
33
|
+
follows the same rule (next entry); the hooks are unaffected.
|
|
34
|
+
- **The MCP server reads the graph that belongs to its store.** A relative `SIDEGRAPH_GRAPH`
|
|
35
|
+
(or the default `graphify-out/graph.json`) used to resolve against the server's working
|
|
36
|
+
directory, so a store reached by an absolute `SIDEGRAPH_DIR`, or a store in a nested directory,
|
|
37
|
+
could be synced against one project's graph by the CLI and another's by `sync_anchors` and the
|
|
38
|
+
retrieval tools, and the store's graph version flipped back and forth. It now resolves against
|
|
39
|
+
the store's project, the same rule the CLI uses, and an empty `SIDEGRAPH_GRAPH` counts as unset.
|
|
40
|
+
With the default layout (`.sidegraph` in the project, the server started there) nothing changes.
|
|
41
|
+
A nested store needs an absolute `SIDEGRAPH_GRAPH`; `sync_anchors` reports `graph not readable`
|
|
42
|
+
with the path and names the graph it found beside the working directory, when there is one.
|
|
43
|
+
- **A document is imported again once, if its `provenance.ref` changes.** A document
|
|
44
|
+
imported before this release from a subdirectory or by an absolute path is imported
|
|
45
|
+
again under its repository path. The old record stays. A leftover that is still `proposed` can be dropped with
|
|
46
|
+
`sidegraph-ratify --drop <id>`. An `accepted` leftover has no one-step retirement: leave
|
|
47
|
+
it, or supersede it by hand with `supersede_decision`, which writes a new record.
|
|
48
|
+
- **`sidegraph-import --path` (and domain `--paths`) match on directory boundaries.**
|
|
49
|
+
`--path payments` no longer imports `payments_v2/b.py`, and a partial-name prefix such as
|
|
50
|
+
`--path docs/adr/00` matches nothing; a prefix matches a file under that directory or
|
|
51
|
+
that exact file. `--path ""` still matches everything, and mixed with a real prefix it is
|
|
52
|
+
ignored. The domain `--paths` help already behaved this way and now says so.
|
|
53
|
+
- **The Stop hook skips the transcript of a session that is already captured.** It now peeks
|
|
54
|
+
at the capture ledger read-only before parsing the transcript, so every Stop after the
|
|
55
|
+
capturing one no longer re-reads the whole file.
|
|
56
|
+
|
|
57
|
+
### Fixed
|
|
58
|
+
|
|
59
|
+
- **The derived initiative names the store's repository branch.** It used to come from the
|
|
60
|
+
branch of whatever directory the MCP server or CLI ran in. An inherited `GIT_DIR` or
|
|
61
|
+
`GIT_WORK_TREE` no longer redirects either the derived initiative or the captured commit.
|
|
62
|
+
- **A timestamp in the future no longer counts as fresh.** The capture session-id fallback and
|
|
63
|
+
the session attribution of retrieval telemetry treated a marker stamped ahead of the clock
|
|
64
|
+
as current; they now ignore it. The SessionStart dedupe still treats a same-session stamp
|
|
65
|
+
less than 60 seconds ahead as a duplicate (a parallel hook can write one), but a stamp
|
|
66
|
+
further ahead no longer suppresses the map until the clock catches up.
|
|
67
|
+
- **Every CLI command that takes a store and a `--graph` pairs the store with its own
|
|
68
|
+
project's graph by default.** `sidegraph-sync`, `sidegraph-import` (both modes),
|
|
69
|
+
`sidegraph-domains bootstrap`, `sidegraph-doctor` and `sidegraph-init` (whose found/missing
|
|
70
|
+
line used the shell's path) read the default graph relative to the
|
|
71
|
+
shell, so `--db A/.sidegraph` run from project B stamped A's store with B's graph version
|
|
72
|
+
and could rewrite A's anchors, import decisions, or bootstrap domains from B's graph. The
|
|
73
|
+
default and `$SIDEGRAPH_GRAPH` (an empty value counts as unset) now resolve against the
|
|
74
|
+
store's project, as `sidegraph-ratify` and `sidegraph-stats` already did; a store reached
|
|
75
|
+
through a symlinked `.sidegraph` keeps the link's project. When the store's project has no
|
|
76
|
+
graph but the same path exists beside the shell (a store copied elsewhere), one stderr hint
|
|
77
|
+
names `--graph <path>`; when both exist, a note says which was used. Error lines name the
|
|
78
|
+
resolved path.
|
|
79
|
+
- **`SIDEGRAPH_DB` naming a missing path no longer scaffolds its parent.** A missing
|
|
80
|
+
`SIDEGRAPH_DB=/proj/.sidegraph`, or a dangling link, resolved to `/proj` and a store was
|
|
81
|
+
created in the project root. Only a path ending in `.db` is rescued to its parent now; any
|
|
82
|
+
other missing path is used as given, and a dangling link fails to open without creating
|
|
83
|
+
anything.
|
|
84
|
+
- **`sidegraph-sync --check` documents domain-refresh failures.** The help and the module
|
|
85
|
+
docstring omitted the finding that already makes `--check` exit 2.
|
|
86
|
+
- **A move left `moved_uncommitted` is now re-verified after you commit it, even when the
|
|
87
|
+
graph was not rebuilt.** Committing a rename does not change `graph.json`, so the version
|
|
88
|
+
gate skipped every later sync and the leaf kept its old path until `--force`. Sync now
|
|
89
|
+
remembers such entities with the git `HEAD` it saw, and the first sync after `HEAD` moves
|
|
90
|
+
re-verifies just them (a narrow pass that leaves domain membership alone). The comment that
|
|
91
|
+
promised the next sync would heal it was wrong, and is corrected.
|
|
92
|
+
- **A decision with two leaves in one community no longer loses that community's binding when
|
|
93
|
+
one leaf leaves it.** Both leaves share one Tier-1 `community:*` row, and a renumber that
|
|
94
|
+
moved one leaf orphaned the row the other still held, so the decision stopped surfacing for
|
|
95
|
+
that community. Sync now settles a record's community rows after every leaf has been
|
|
96
|
+
rebound, and a new row carries the moved leaf's relation instead of `affects`. Damage from
|
|
97
|
+
earlier syncs is repaired when a later repoint touches the record, or when the index is
|
|
98
|
+
next rebuilt from the committed files.
|
|
99
|
+
- **Secret redaction covers quoted values and quoted keys.** `password: "one two"`,
|
|
100
|
+
`` token: `abc def` `` and `password = 'a b c'` were cut at the first space, leaving the rest
|
|
101
|
+
of the secret in the store, and `{"password": "hunter2 two"}` was not matched at all. A
|
|
102
|
+
quoted value is now taken whole, with any text glued to its closing quote, and a quoted
|
|
103
|
+
key matches too. JSON keys such as `"token_count"` now redact like the unquoted
|
|
104
|
+
`token_count:` already did. An escaped quote (`"alpha\" beta"`) does not end a quoted
|
|
105
|
+
value, and a quoted key stops at the next JSON field, so `{"password":"x y","reason":"z"}`
|
|
106
|
+
keeps `reason`.
|
|
107
|
+
- **A decision whose attached fact failed is left proposed under an auto-ratify policy,** and
|
|
108
|
+
an auto-accepted fact's write-guard message points to `add_anchors` instead of a drop that
|
|
109
|
+
the store refuses.
|
|
110
|
+
- **An initiative name is redacted before it becomes an entity, on every write path.** A
|
|
111
|
+
secret in `initiative`, or in a branch name the propose path derives one from, used to land
|
|
112
|
+
in the canonical `initiative:<name>` entity file. A blank or all-secret initiative now binds
|
|
113
|
+
nothing, and a padded name is trimmed (`" proj "` keys as `initiative:proj`).
|
|
114
|
+
- **`add_decision` binds its initiative with no graph or no anchors.** The Tier-0 binding was
|
|
115
|
+
made only inside the per-anchor loop, so a call without a reader or without an anchor
|
|
116
|
+
dropped it silently.
|
|
117
|
+
- **`add_domain`, `supersede_domain` and `sidegraph-domains add` redact the title and
|
|
118
|
+
summary.** Only `propose_domains` and the bootstrap did. The MCP results now carry
|
|
119
|
+
`redactions`, and the CLI prints a count line when it redacted something.
|
|
120
|
+
- **`propose_decisions` dedups a decision on its redacted title.** A title that held a secret
|
|
121
|
+
was compared raw against the stored, redacted one, so proposing it twice wrote it twice.
|
|
122
|
+
- **One failing draft no longer aborts a propose batch.** A step after the write (anchors,
|
|
123
|
+
initiative, tags, attached facts, auto-ratify) now leaves the result `written` with a
|
|
124
|
+
`reason`; an error before the write makes that draft `rejected`; each attached fact and each
|
|
125
|
+
domain is isolated the same way, and a failed TOC rebuild after `propose_domains` is
|
|
126
|
+
reported as a `toc:` warning. `KeyboardInterrupt` still propagates.
|
|
127
|
+
- **A record id can no longer become a path outside the store.** Every canonical writer built
|
|
128
|
+
`<dir>/<id>.json` from the id as given, so an id like `../../x` wrote outside the store.
|
|
129
|
+
The store now refuses to write an id that is not a single path segment, and the OKF export
|
|
130
|
+
skips such a decision, fact or entity with a warning.
|
|
131
|
+
- **A canonical file whose JSON id does not match its filename is skipped on reload, with a
|
|
132
|
+
warning on every open.** A file with a crafted id was indexed under that id, so one later
|
|
133
|
+
ratify could write outside the store. Duplicate ids let the later file silently win, and a
|
|
134
|
+
file with no id got a fresh ULID on every rebuild. Such files are now left out of the index
|
|
135
|
+
and named in a warning until they are fixed or removed. An existing index reloads once to
|
|
136
|
+
apply the rule. An archive line with an unsafe or non-string id is skipped instead of
|
|
137
|
+
making `Store()` fail.
|
|
138
|
+
- **An interrupted legacy migration no longer loses its staged work.** The legacy file is
|
|
139
|
+
renamed to its backup only after the staged directories have moved in, so an interruption
|
|
140
|
+
leaves it in place and the next open migrates again. A bare-file migration, which has to
|
|
141
|
+
rename first, keeps its staging directory and leaves a sentinel so the next open says what
|
|
142
|
+
to do. A sentinel younger than 60 seconds means a migration is running now: the open
|
|
143
|
+
refuses with "retry in a minute" and touches nothing, and deleting that sentinel early is
|
|
144
|
+
unsafe. A legacy row with an unsafe id fails the migration before anything is written, and
|
|
145
|
+
a row whose JSON omits its id takes its SQL primary key instead of a fresh one per retry.
|
|
146
|
+
- **The bootstrap catalog applies the same identity rule.** A record file with no id was
|
|
147
|
+
given a fresh ULID on every load, so the catalog fingerprint changed between two loads of
|
|
148
|
+
one store. Such files are now skipped with a warning.
|
|
149
|
+
- **The store refuses a symlinked directory or store file inside itself.** A symlinked
|
|
150
|
+
`decisions/` sent every record write, from the MCP server, the hooks and bootstrap alike, to
|
|
151
|
+
the link's target, and a symlinked `index.db` made SQLite write there. `Store()` now raises
|
|
152
|
+
before any migration or write, naming the entry, and `sidegraph-bootstrap` refuses before
|
|
153
|
+
the review prompts. A symlinked store root stays allowed. Bootstrap's action summary now
|
|
154
|
+
names the store path and any symlink between the repository root and it.
|
|
155
|
+
- **`sidegraph-bootstrap --report` no longer overwrites a file it is hard-linked to, and
|
|
156
|
+
protects the Codex hooks file the verifier really reads.** The guard compared resolved
|
|
157
|
+
paths, so a hard link to a host config passed it and the report truncated the shared file.
|
|
158
|
+
It also protected only the legacy `.codex/hooks/hooks.json`, not `.codex/hooks.json`. The
|
|
159
|
+
report is now published by replace, and one list of host-config paths feeds both the
|
|
160
|
+
verifier and the guard. The guard covers every host's config file, whichever `--host` is
|
|
161
|
+
selected.
|
|
162
|
+
- **`sidegraph-import --docs` keys a document inside the repository by its repository path,
|
|
163
|
+
whatever directory it runs from.** Run from a subdirectory or given an absolute path, a
|
|
164
|
+
document used to miss its file node in the graph, skip as unanchorable, and get a
|
|
165
|
+
different `provenance.ref` from the same document imported at the root. Profile discovery
|
|
166
|
+
also finds the profile's documents from any directory in the repository, and the
|
|
167
|
+
unanchorable warning now fires only outside a git work tree, where the current directory
|
|
168
|
+
stands in for the root. Build the graph from the repository root: a graph built from a
|
|
169
|
+
subdirectory leaves documents unanchorable.
|
|
170
|
+
- **`--docs` refuses a markdown file that is a symlink to a target outside the repository.**
|
|
171
|
+
It used to read the target under `--any-doc`. The document is counted as `refused: a symlink
|
|
172
|
+
pointing outside the repository`, and so is a profile-discovery hit that resolves outside
|
|
173
|
+
the repository (for example through a symlinked directory). A symlinked directory inside
|
|
174
|
+
the repository that points inside it imports under the path you named, and one that points
|
|
175
|
+
outside the repository is refused. A symlink to a file inside the repository imports under
|
|
176
|
+
its link path.
|
|
177
|
+
- **A re-import repairs a record that has no anchors.** A document whose record was written
|
|
178
|
+
but whose bindings never landed (a run that stopped in between, leaving no anchor other
|
|
179
|
+
than `tag:` bindings) used to be skipped as existing for good. It is now bound on the next import and reported as `had their anchors
|
|
180
|
+
repaired`.
|
|
181
|
+
- **The `import_docs` docstring describes what it does:** the five compared fields, the
|
|
182
|
+
statuses it matches, the repair and the refusal.
|
|
183
|
+
- **`sidegraph-init` no longer writes `.claude/settings.json` through a symlink, and no
|
|
184
|
+
longer prints a traceback when the write fails.** A symlinked `.claude/` or `settings.json`
|
|
185
|
+
(live or dangling) is left untouched and the `env` line to add by hand is printed. A merge
|
|
186
|
+
into an existing file is now published by replacing it atomically, so an interruption
|
|
187
|
+
cannot leave a truncated file, and any write failure (a read-only `.claude/`, for example)
|
|
188
|
+
is reported the same way instead of raising. An `env` block that is `null` or not an
|
|
189
|
+
object, and a settings file that changes while init runs, are skipped the same way, not
|
|
190
|
+
raised, and a link swapped in just before the write is refused. A write-protected file is
|
|
191
|
+
respected when init runs as root too.
|
|
192
|
+
- **`sidegraph-doctor`, the drift refresh the session hooks run, and `sidegraph-stats` now
|
|
193
|
+
open the index correctly when the store's path contains `#`, `?`, or `%` followed by two
|
|
194
|
+
hex digits.** Their read-only SQLite URI was built from the unquoted path.
|
|
195
|
+
**Doctor reported its index checks as skipped**, blaming a missing index and suggesting
|
|
196
|
+
`sidegraph-sync`, which could not help. **The session drift refresh silently stopped
|
|
197
|
+
excluding orphaned bindings.** **Stats failed.** For `#` and `?`, an empty file was also
|
|
198
|
+
created at the store path cut short at that character, and an unrelated database there
|
|
199
|
+
could be read instead.
|
|
200
|
+
- **The session-link gate checks every line that gets published.** Lines starting with `#` in
|
|
201
|
+
a PR description, and in commit messages made with `git commit -m`/`-F`, which git records,
|
|
202
|
+
are now checked. The PR title and the PR's recorded commit messages are checked too. The
|
|
203
|
+
check re-runs when a PR description is edited. The public repository runs the check too:
|
|
204
|
+
the release snapshot ships the checker, and the workflow fails when the checker is missing
|
|
205
|
+
instead of skipping.
|
|
206
|
+
- **`sidegraph-export-okf` refuses a symlinked `--out`, and a failed export no longer
|
|
207
|
+
destroys the previous one.** A symlinked output directory used to be written through, or
|
|
208
|
+
cleared, wherever it pointed, and a write that failed midway left a partial bundle after
|
|
209
|
+
the old export was already deleted. The new bundle is now built beside `--out` and
|
|
210
|
+
swapped in only when complete, except for a mount point, a `--out` that is the current
|
|
211
|
+
directory, an unwritable or non-directory parent, or a previous export that cannot be
|
|
212
|
+
renamed aside, which are written in place as before (a write failure there can leave a
|
|
213
|
+
partial export). The in-place write goes to the validated, resolved directory.
|
|
214
|
+
- **An unreadable store or graph directory no longer ends in a traceback.** On Python 3.13 a store or
|
|
215
|
+
graph whose directory could not be read (permission denied) made `sidegraph-sync`,
|
|
216
|
+
`sidegraph-import`, `sidegraph-domains bootstrap`, `sidegraph-init`, `sidegraph-stats` and
|
|
217
|
+
`sidegraph-ratify` (on a domain accept) exit with an uncaught `PermissionError`. An unreadable
|
|
218
|
+
store is now reported on the command's error line (exit 1; 2 for `sidegraph-stats`). An
|
|
219
|
+
unreadable graph is treated as a missing one: `sidegraph-sync`, `sidegraph-import` and
|
|
220
|
+
`sidegraph-domains bootstrap` stop with `graph not readable`, and the other commands carry on
|
|
221
|
+
without a graph.
|
|
222
|
+
A working directory that cannot be read skips the graph hint and the `sync_anchors` hint instead of
|
|
223
|
+
raising; other code that resolves a relative path against it may still raise.
|
|
224
|
+
- **A retried Tier-1 reconcile that could not run is no longer reported as done.** A
|
|
225
|
+
remembered community reconcile whose record still has a live or degraded Tier-2 anchor
|
|
226
|
+
with no recorded community kept being treated as a success: the key was cleared, the sync
|
|
227
|
+
said `moved`, and the stale row stayed live. It is now kept, and retried silently on every
|
|
228
|
+
sync.
|
|
229
|
+
- **Sync, verify and doctor ask git about the repository their own files are in.**
|
|
230
|
+
`sidegraph-sync` (the graph's directory), `sidegraph-verify --against` and
|
|
231
|
+
`sidegraph-doctor` (the store's, and its graph-root check's) no longer inherit an ambient `GIT_DIR` or
|
|
232
|
+
`GIT_WORK_TREE`, which could make sync read another repository's `HEAD` and adopt a rename
|
|
233
|
+
that was never committed. The lazy sync run by `SessionStart` and retrieval, and the
|
|
234
|
+
`SessionStart` drift cache, are fixed too. `sidegraph-init` and `sidegraph-import` resolve
|
|
235
|
+
the repository root from the current directory the same way. A work tree whose repository
|
|
236
|
+
is found only through `GIT_DIR` now needs a `.git` file containing `gitdir: <path>`, and
|
|
237
|
+
`core.bare=false` in that repository.
|
|
238
|
+
- **The sync docs list every condition that prevents a skip.** A remembered Tier-1
|
|
239
|
+
reconcile that is repaired or fails again also makes a plain sync report instead of
|
|
240
|
+
skipping.
|
|
241
|
+
- **Documentation and help text match what the code does.** The PreToolUse docs name the
|
|
242
|
+
real `Read|Grep|Edit|Write` matcher and the two nudge forms, each at most once per session.
|
|
243
|
+
The `add_decision`, `supersede_decision`, `add_fact`, `supersede_fact` and
|
|
244
|
+
`propose_decisions` tool descriptions list `anchors_orphaned`. `sidegraph-ratify --help`
|
|
245
|
+
says `--all` also accepts standalone facts, and `--help` for `sidegraph-verify`,
|
|
246
|
+
`-doctor` and `-blame` no longer promises a legacy `*.db` migration they never perform.
|
|
247
|
+
`SECURITY.md` states local retrieval telemetry and the output paths commands write to.
|
|
248
|
+
|
|
249
|
+
## [0.5.0] — 2026-09-23
|
|
250
|
+
|
|
251
|
+
### Changed
|
|
252
|
+
|
|
253
|
+
- **The public `main`, which the plugin manifests install from, moves only at releases.**
|
|
254
|
+
The plugin runs whatever `main` holds, so a snapshot pushed between releases used to reach
|
|
255
|
+
every plugin user at once. The release script now pushes `main` only for a release: it
|
|
256
|
+
refuses unless the version it carries is untagged in the public repository and
|
|
257
|
+
`CHANGELOG.md` dates it.
|
|
258
|
+
|
|
259
|
+
### Fixed
|
|
260
|
+
|
|
261
|
+
- **`sidegraph-init` now says to restart the Claude Code session after it writes
|
|
262
|
+
`SIDEGRAPH_RATIFY_POLICY`.** The Sidegraph MCP server reads the policy from the
|
|
263
|
+
environment it started with, so a server started before `sidegraph-init` kept proposing
|
|
264
|
+
under the old policy until the session restarted, and nothing said so.
|
|
265
|
+
- **`sidegraph-verify --against` no longer flags a ratification of an already-committed
|
|
266
|
+
proposal, or a supersede/drop that touches a record written before a later schema addition
|
|
267
|
+
(`Provenance.commit`, `Domain.seed_anchors`/`path_prefixes`) existed.** Ratifying a
|
|
268
|
+
decision, fact, or domain stamps `ratified_at`/`ratified_by`, and neither field was on the
|
|
269
|
+
transition layer's mutable allow-list, so the stamp alone was reported as an illegal field
|
|
270
|
+
change. Separately, rewriting an old record that predates a field added to its schema
|
|
271
|
+
serializes that field back in as its default, which a plain top-level or whole-list
|
|
272
|
+
comparison also read as a change. The ratifier stamp may now be set once, from a proposed
|
|
273
|
+
record, landing on any state reached through accepted within the diffed range; an absent
|
|
274
|
+
field now counts as the same value as an explicit `null` or an empty list/object, at every
|
|
275
|
+
nesting depth and inside list items. A field whose default is a non-empty value is not
|
|
276
|
+
covered by this.
|
|
277
|
+
- **`sidegraph-import --docs` no longer aborts on a file that is not valid UTF-8.** It
|
|
278
|
+
decoded every document as strict UTF-8 with no handler, so one document saved in
|
|
279
|
+
`cp1251` (or carrying a stray non-UTF-8 byte) raised and stopped the whole run, with
|
|
280
|
+
nothing after it imported and no report printed. The file is now a named skip
|
|
281
|
+
(`skipped_undecodable`) instead: the run continues, and both the real run and
|
|
282
|
+
`--dry-run` print the skipped path(s), last.
|
|
283
|
+
- **`sidegraph-import --docs` now reads a UTF-8 document that starts with a byte-order mark
|
|
284
|
+
(BOM).** The BOM used to survive into the parsed text, so the H1 and any frontmatter never
|
|
285
|
+
matched, and a real decision document was silently counted `skipped_not_decision`. It is
|
|
286
|
+
now stripped before parsing. `sidegraph-bootstrap` still reads such a file without
|
|
287
|
+
stripping it.
|
|
288
|
+
|
|
289
|
+
Re-importing a BOM document that an earlier version did import can change its record,
|
|
290
|
+
once:
|
|
291
|
+
- On the `openspec` profile, a BOM `proposal.md` had imported under a title built from its
|
|
292
|
+
path. The re-import supersedes it with the real H1 title.
|
|
293
|
+
- Frontmatter the BOM hid is now honoured. A document marked `status: superseded` now
|
|
294
|
+
counts `skipped_superseded_frontmatter`, and its earlier live record stays as it is.
|
|
295
|
+
- A document marked as a draft, proposed, pending or under review keeps its earlier
|
|
296
|
+
`accepted` record: a re-import compares content, not status, and the content is
|
|
297
|
+
unchanged.
|
|
298
|
+
|
|
299
|
+
Retiring or re-proposing such a record is manual.
|
|
300
|
+
|
|
301
|
+
### Security
|
|
302
|
+
|
|
303
|
+
- **The lockfile moves `anyio` from 4.14.1 to 4.15.1**, past three advisories fixed in
|
|
304
|
+
4.14.2: TLS certificate spoofing through IDNA 2003 host-name encoding (critical),
|
|
305
|
+
`run_process` keeping the parent's supplementary groups (high), and process-pool workers
|
|
306
|
+
blocking on undrained stderr (moderate). The published package does not pin `anyio`, so
|
|
307
|
+
this changes development and CI environments and installs made from `uv.lock`; a fresh
|
|
308
|
+
install already resolves a fixed version.
|
|
309
|
+
|
|
10
310
|
## [0.4.0] — 2026-09-22
|
|
11
311
|
|
|
12
312
|
### Fixed
|
|
@@ -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.
|
|
16
|
+
Sidegraph is pre-1.0 (v0.6.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
|
|
@@ -30,10 +30,11 @@ away for convenience.
|
|
|
30
30
|
2. **The store is append-only — and sync-clean.** Never hard-delete a `Decision`, `Fact`, or
|
|
31
31
|
`Domain`. Reversal = set `valid_to`/flip status on the old record + create a new one with
|
|
32
32
|
`supersedes`. Superseded records stay retrievable as "tried before, abandoned because…" —
|
|
33
|
-
that history *is* the product. A graph rebuild (`sidegraph-sync`) must
|
|
34
|
-
diff: it only ever touches derived, gitignored state (the local
|
|
35
|
-
binding status, the TOC cache), never a committed record file
|
|
36
|
-
derived state, never committed).
|
|
33
|
+
that history *is* the product. A graph rebuild (`sidegraph-sync`) must not produce a git
|
|
34
|
+
diff from regenerable state: it only ever touches derived, gitignored state (the local
|
|
35
|
+
index, entity mappings, binding status, the TOC cache), never a committed record file
|
|
36
|
+
(community labels are derived state, never committed). The one exception: a confirmed
|
|
37
|
+
leaf-file move may update that entity's committed descriptor.
|
|
37
38
|
3. **The store format is a public contract.** File-per-record JSON, a stamped
|
|
38
39
|
`schema_version`, and the append-only/merge rules are specified in
|
|
39
40
|
[`docs/reference/store-format.md`](docs/reference/store-format.md) — that page is the
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: sidegraph
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.6.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
|
|
@@ -84,9 +84,10 @@ only ever reads `graph.json`, so the plain install above is all it needs.
|
|
|
84
84
|
uv tool install sidegraph # from PyPI — puts sidegraph-init / sidegraph-mcp / … on PATH
|
|
85
85
|
sidegraph-init
|
|
86
86
|
|
|
87
|
-
# Prefer
|
|
87
|
+
# Prefer running straight from git instead of PyPI? Swap step 3 for:
|
|
88
88
|
# uvx --from git+https://github.com/SantyagoSeaman/sidegraph.git@main sidegraph-init
|
|
89
|
-
# `@main`
|
|
89
|
+
# `@main` moves only when a release is cut. It is still a mutable ref: a later cache refresh can
|
|
90
|
+
# install a newer one. Pin a tag or a SHA for CI.
|
|
90
91
|
```
|
|
91
92
|
|
|
92
93
|
4. **Name your domains** — turns the graph's communities into a described table of
|
|
@@ -166,7 +167,7 @@ projects the full store, history included, into an OKF v0.1 bundle any OKF consu
|
|
|
166
167
|
next session ◀── SessionStart TOC anchored to entities in the
|
|
167
168
|
of named domains ◀── get_task_context ◀────── engine's graph (read-only);
|
|
168
169
|
mistakes first drill_down re-anchored after refactors
|
|
169
|
-
blind Read/Grep ──▶ nudged back to get_task_context (once per session)
|
|
170
|
+
blind Read/Grep ──▶ nudged back to get_task_context (each form once per session)
|
|
170
171
|
```
|
|
171
172
|
|
|
172
173
|
Two layers age differently: the **structure** layer (the code graph — entities,
|
|
@@ -56,9 +56,10 @@ only ever reads `graph.json`, so the plain install above is all it needs.
|
|
|
56
56
|
uv tool install sidegraph # from PyPI — puts sidegraph-init / sidegraph-mcp / … on PATH
|
|
57
57
|
sidegraph-init
|
|
58
58
|
|
|
59
|
-
# Prefer
|
|
59
|
+
# Prefer running straight from git instead of PyPI? Swap step 3 for:
|
|
60
60
|
# uvx --from git+https://github.com/SantyagoSeaman/sidegraph.git@main sidegraph-init
|
|
61
|
-
# `@main`
|
|
61
|
+
# `@main` moves only when a release is cut. It is still a mutable ref: a later cache refresh can
|
|
62
|
+
# install a newer one. Pin a tag or a SHA for CI.
|
|
62
63
|
```
|
|
63
64
|
|
|
64
65
|
4. **Name your domains** — turns the graph's communities into a described table of
|
|
@@ -138,7 +139,7 @@ projects the full store, history included, into an OKF v0.1 bundle any OKF consu
|
|
|
138
139
|
next session ◀── SessionStart TOC anchored to entities in the
|
|
139
140
|
of named domains ◀── get_task_context ◀────── engine's graph (read-only);
|
|
140
141
|
mistakes first drill_down re-anchored after refactors
|
|
141
|
-
blind Read/Grep ──▶ nudged back to get_task_context (once per session)
|
|
142
|
+
blind Read/Grep ──▶ nudged back to get_task_context (each form once per session)
|
|
142
143
|
```
|
|
143
144
|
|
|
144
145
|
Two layers age differently: the **structure** layer (the code graph — entities,
|
|
@@ -20,11 +20,19 @@ Sidegraph is a local-only tool. Its entire data surface:
|
|
|
20
20
|
store (`decisions.db`, from before store schema 0.4.0) triggers a one-time migration
|
|
21
21
|
that renames the legacy file to `decisions.db.migrated-backup` (kept, never deleted)
|
|
22
22
|
alongside writing the new
|
|
23
|
-
directory layout.
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
23
|
+
directory layout. The store is the default persistence location, not the only one:
|
|
24
|
+
`sidegraph-init` can write `.claude/settings.json` (the ratification-policy env entry);
|
|
25
|
+
the visualization, OKF export and bootstrap-report commands write to the output paths you
|
|
26
|
+
give them; and the optional `sidegraph-prepare-commit-msg` git hook, once you install it,
|
|
27
|
+
adds commented decision trailers to the commit message file git hands it
|
|
28
|
+
(normally `.git/COMMIT_EDITMSG`). Beyond those, the only filesystem writes are the standard config
|
|
29
|
+
snippets you install yourself (`.mcp.json`, hook entries) — Sidegraph touches nothing
|
|
30
|
+
else. See [`docs/reference/store-format.md`](docs/reference/store-format.md) for the full
|
|
31
|
+
layout.
|
|
32
|
+
- **Network:** none. No remote telemetry, no phone-home, nothing leaves your machine. Local
|
|
33
|
+
retrieval telemetry is recorded in the gitignored `index.db` by default (which records
|
|
34
|
+
were shown and which files were touched, never uploaded); set `SIDEGRAPH_TELEMETRY=off` to
|
|
35
|
+
stop new recording. The only
|
|
28
36
|
network-using feature is the *optional* semantic documentation pass, which is executed
|
|
29
37
|
by the separate Graphify CLI against the LLM provider you configure — not by Sidegraph.
|
|
30
38
|
|