sidegraph 0.19.0__tar.gz → 0.20.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.19.0 → sidegraph-0.20.0}/CHANGELOG.md +38 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/CLAUDE.md +1 -1
- {sidegraph-0.19.0 → sidegraph-0.20.0}/PKG-INFO +2 -1
- {sidegraph-0.19.0 → sidegraph-0.20.0}/docs/concepts/anchoring.md +3 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/docs/concepts/data-model.md +24 -1
- {sidegraph-0.19.0 → sidegraph-0.20.0}/docs/getting-started/installation.md +2 -1
- {sidegraph-0.19.0 → sidegraph-0.20.0}/docs/guides/capturing-decisions.md +3 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/docs/guides/retrieval-in-sessions.md +5 -2
- {sidegraph-0.19.0 → sidegraph-0.20.0}/docs/guides/troubleshooting.md +2 -1
- {sidegraph-0.19.0 → sidegraph-0.20.0}/docs/reference/cli.md +6 -4
- {sidegraph-0.19.0 → sidegraph-0.20.0}/docs/reference/configuration.md +1 -1
- {sidegraph-0.19.0 → sidegraph-0.20.0}/docs/reference/hooks.md +9 -1
- {sidegraph-0.19.0 → sidegraph-0.20.0}/docs/reference/mcp-tools.md +51 -3
- {sidegraph-0.19.0 → sidegraph-0.20.0}/docs/reference/stability.md +3 -3
- {sidegraph-0.19.0 → sidegraph-0.20.0}/docs/reference/store-format.md +21 -2
- {sidegraph-0.19.0 → sidegraph-0.20.0}/package.json +1 -1
- {sidegraph-0.19.0 → sidegraph-0.20.0}/plugin/sidegraph/.claude-plugin/plugin.json +1 -1
- {sidegraph-0.19.0 → sidegraph-0.20.0}/plugin/sidegraph/.codex-plugin/plugin.json +1 -1
- {sidegraph-0.19.0 → sidegraph-0.20.0}/plugin/sidegraph/.muse-plugin/plugin.json +1 -1
- {sidegraph-0.19.0 → sidegraph-0.20.0}/plugin/sidegraph/skills/record-decision/SKILL.md +2 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/plugin/sidegraph/skills/record-fact/SKILL.md +2 -1
- {sidegraph-0.19.0 → sidegraph-0.20.0}/plugin/sidegraph/skills/triage-drift/SKILL.md +59 -6
- {sidegraph-0.19.0 → sidegraph-0.20.0}/pyproject.toml +4 -1
- {sidegraph-0.19.0 → sidegraph-0.20.0}/src/sidegraph/__init__.py +1 -1
- {sidegraph-0.19.0 → sidegraph-0.20.0}/src/sidegraph/cli.py +49 -24
- {sidegraph-0.19.0 → sidegraph-0.20.0}/src/sidegraph/doctor.py +254 -21
- sidegraph-0.20.0/src/sidegraph/drift_checks.py +490 -0
- sidegraph-0.20.0/src/sidegraph/drift_groups.py +773 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/src/sidegraph/host/hooks.py +5 -1
- {sidegraph-0.19.0 → sidegraph-0.20.0}/src/sidegraph/integrity.py +13 -5
- sidegraph-0.20.0/src/sidegraph/md_sections.py +218 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/src/sidegraph/retrieval.py +43 -3
- {sidegraph-0.19.0 → sidegraph-0.20.0}/src/sidegraph/schema.py +62 -3
- {sidegraph-0.19.0 → sidegraph-0.20.0}/src/sidegraph/server.py +205 -9
- {sidegraph-0.19.0 → sidegraph-0.20.0}/src/sidegraph/store.py +44 -4
- {sidegraph-0.19.0 → sidegraph-0.20.0}/src/sidegraph/store_layout.py +117 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/src/sidegraph/sync.py +113 -41
- {sidegraph-0.19.0 → sidegraph-0.20.0}/src/sidegraph/validation_errors.py +51 -0
- sidegraph-0.20.0/tests/drift_groups_support.py +153 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_cli_doctor.py +52 -1
- sidegraph-0.20.0/tests/test_declared_sections_docs.py +54 -0
- sidegraph-0.20.0/tests/test_declared_sections_schema.py +136 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_doctor_code_drift.py +214 -0
- sidegraph-0.20.0/tests/test_doctor_declared_sections.py +499 -0
- sidegraph-0.20.0/tests/test_doctor_grouped_drift.py +515 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_doctor_record_identity.py +6 -1
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_drift_checks.py +303 -0
- sidegraph-0.20.0/tests/test_drift_checks_blobs.py +150 -0
- sidegraph-0.20.0/tests/test_drift_groups.py +1040 -0
- sidegraph-0.20.0/tests/test_drift_recency.py +127 -0
- sidegraph-0.20.0/tests/test_drift_stamp_cache.py +205 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_host_drift_nudge.py +79 -4
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_host_integrity.py +1 -1
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_hot_index.py +7 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_integrity.py +29 -0
- sidegraph-0.20.0/tests/test_markdown_it_dependency.py +13 -0
- sidegraph-0.20.0/tests/test_md_sections.py +560 -0
- sidegraph-0.20.0/tests/test_record_drift_check_sections.py +464 -0
- sidegraph-0.20.0/tests/test_record_drift_check_sections_input.py +82 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_security_validation_errors.py +1 -0
- sidegraph-0.20.0/tests/test_sync_drift_stamps.py +709 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/uv.lock +3 -1
- sidegraph-0.19.0/src/sidegraph/drift_checks.py +0 -209
- {sidegraph-0.19.0 → sidegraph-0.20.0}/.agents/plugins/marketplace.json +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/.claude-plugin/marketplace.json +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/.github/CODEOWNERS +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/.github/ISSUE_TEMPLATE/bug_report.yml +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/.github/ISSUE_TEMPLATE/config.yml +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/.github/ISSUE_TEMPLATE/feature_request.yml +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/.github/secret_scanning.yml +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/.github/workflows/ci.yml +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/.github/workflows/publish.yml +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/.github/workflows/scorecard.yml +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/.github/workflows/session-link-gate.yml +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/.gitignore +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/.gitleaks.toml +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/.opencode/INSTALL.md +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/.pre-commit-config.yaml +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/.python-version +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/AGENTS.md +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/CODE_OF_CONDUCT.md +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/CONTRIBUTING.md +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/LICENSE +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/README.md +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/SECURITY.md +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/docs/README.md +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/docs/concepts/decision-memory.md +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/docs/concepts/mind-model.md +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/docs/concepts/retrieval.md +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/docs/getting-started/bootstrap.md +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/docs/getting-started/claude-code-setup.md +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/docs/getting-started/codex-setup.md +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/docs/getting-started/quickstart.md +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/docs/guides/adr-export.md +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/docs/guides/ci-cd-maintenance.md +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/docs/guides/health-check.md +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/docs/guides/migrating-to-0.14.md +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/docs/guides/migrating-to-0.17.md +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/docs/guides/naming-your-domains.md +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/docs/guides/semantic-docs.md +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/docs/guides/surviving-refactors.md +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/docs/guides/team-workflow.md +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/docs/guides/using-0.15.md +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/docs/guides/using-0.16.md +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/docs/guides/verifying-your-setup.md +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/docs/integrations/claude-code.md +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/docs/integrations/codex.md +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/docs/integrations/graphify.md +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/docs/integrations/grok.md +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/docs/integrations/muse.md +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/docs/integrations/opencode.md +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/docs/llms.txt +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/docs/pilot-kit/README.md +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/docs/pilot-kit/corpus_fit.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/docs/pilot-kit/judge-prompt.md +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/docs/pilot-kit/questions-prompt.md +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/docs/pilot-kit/rubric-template.md +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/docs/reference/git-bindings.md +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/docs/reference/operations.md +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/docs/reference/releasing.md +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/docs/whitepaper/index.md +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/index.js +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/plugin/sidegraph/.mcp.json +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/plugin/sidegraph/codex/hooks.json +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/plugin/sidegraph/codex/mcp.json +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/plugin/sidegraph/hooks/hooks.json +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/plugin/sidegraph/skills/check-plan/SKILL.md +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/plugin/sidegraph/skills/check-plan/agents/openai.yaml +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/plugin/sidegraph/skills/compact/SKILL.md +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/plugin/sidegraph/skills/compact/agents/openai.yaml +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/plugin/sidegraph/skills/explain-why/SKILL.md +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/plugin/sidegraph/skills/explain-why/agents/openai.yaml +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/plugin/sidegraph/skills/heal-anchors/SKILL.md +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/plugin/sidegraph/skills/heal-anchors/agents/openai.yaml +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/plugin/sidegraph/skills/health-check/SKILL.md +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/plugin/sidegraph/skills/health-check/agents/openai.yaml +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/plugin/sidegraph/skills/health-check/scripts/collect.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/plugin/sidegraph/skills/import-adrs/SKILL.md +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/plugin/sidegraph/skills/import-adrs/agents/openai.yaml +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/plugin/sidegraph/skills/manage-domains/SKILL.md +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/plugin/sidegraph/skills/manage-domains/agents/openai.yaml +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/plugin/sidegraph/skills/name-domains/SKILL.md +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/plugin/sidegraph/skills/name-domains/agents/openai.yaml +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/plugin/sidegraph/skills/ratify-decisions/SKILL.md +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/plugin/sidegraph/skills/ratify-decisions/agents/openai.yaml +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/plugin/sidegraph/skills/record-decision/agents/openai.yaml +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/plugin/sidegraph/skills/record-fact/agents/openai.yaml +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/plugin/sidegraph/skills/setup/SKILL.md +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/plugin/sidegraph/skills/setup/agents/openai.yaml +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/plugin/sidegraph/skills/stats/SKILL.md +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/plugin/sidegraph/skills/stats/agents/openai.yaml +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/plugin/sidegraph/skills/triage-drift/agents/openai.yaml +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/src/sidegraph/adr.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/src/sidegraph/adr_cli.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/src/sidegraph/adr_files.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/src/sidegraph/adr_identity.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/src/sidegraph/anchoring.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/src/sidegraph/bash_paths.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/src/sidegraph/bootstrap/__init__.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/src/sidegraph/bootstrap/apply.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/src/sidegraph/bootstrap/catalog.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/src/sidegraph/bootstrap/cli.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/src/sidegraph/bootstrap/integrations.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/src/sidegraph/bootstrap/model.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/src/sidegraph/bootstrap/planner.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/src/sidegraph/bootstrap/proof.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/src/sidegraph/bootstrap/review.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/src/sidegraph/bootstrap/scan.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/src/sidegraph/capture.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/src/sidegraph/config.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/src/sidegraph/delivery.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/src/sidegraph/doc_import.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/src/sidegraph/domain_snapshot.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/src/sidegraph/domains.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/src/sidegraph/engine/__init__.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/src/sidegraph/engine/rationale.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/src/sidegraph/engine/reader.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/src/sidegraph/freshness.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/src/sidegraph/gitenv.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/src/sidegraph/githooks.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/src/sidegraph/gitio.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/src/sidegraph/host/__init__.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/src/sidegraph/host/claude_settings.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/src/sidegraph/host/diagnostics.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/src/sidegraph/host/launch.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/src/sidegraph/host/mcp_entry.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/src/sidegraph/host/session_identity.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/src/sidegraph/host/subagent.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/src/sidegraph/hot_index.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/src/sidegraph/importer.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/src/sidegraph/input_limits.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/src/sidegraph/maintenance.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/src/sidegraph/maintenance_clock.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/src/sidegraph/migrate.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/src/sidegraph/nearest_anchored.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/src/sidegraph/okf.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/src/sidegraph/profiles.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/src/sidegraph/redaction_scan.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/src/sidegraph/redaction_tokens.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/src/sidegraph/seed_ladder.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/src/sidegraph/stats/__init__.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/src/sidegraph/stats/model.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/src/sidegraph/stats/render.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/src/sidegraph/store_format.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/src/sidegraph/store_rules.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/src/sidegraph/store_view.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/src/sidegraph/text_paths.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/src/sidegraph/tool_rate_limit.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/src/sidegraph/verify.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/src/sidegraph/viz/__init__.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/src/sidegraph/viz/assets/vis-network.min.js +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/src/sidegraph/viz/model.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/src/sidegraph/viz/render.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/src/sidegraph/viz/template.html +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/src/sidegraph/worktree_seeds.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/src/sidegraph/write_boundary.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/__init__.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/bounded_listings_support.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/conftest.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/drift_checks_support.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/fixtures/auto_policy/parity_goldens.json +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/fixtures/bitfinex_slice.json +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/fixtures/bootstrap/flows/bmad/_bmad-output/planning-artifacts/architecture/cache/ARCHITECTURE-SPINE.md +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/fixtures/bootstrap/flows/generic-adr/docs/adr/001-retry.md +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/fixtures/bootstrap/flows/genkovich-sdd/docs/features/cache/adr/001.md +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/fixtures/bootstrap/flows/spec-kit/specs/cache/plan.md +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/fixtures/bootstrap/flows/superpowers/docs/superpowers/specs/2026-07-01-cache-design.md +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/fixtures/bootstrap/graph.json +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/fixtures/bootstrap/hosts/claude/.claude/settings.json +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/fixtures/bootstrap/hosts/claude/.mcp.json +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/fixtures/bootstrap/hosts/codex/.codex/config.toml +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/fixtures/bootstrap/hosts/codex/.codex/hooks/hooks.json +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/fixtures/bootstrap/scan/docs/adr/001-safe.md +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/fixtures/corpus/PUBLIC_CORPORA.txt +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/fixtures/corpus/openspec/_provenance.json +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/fixtures/corpus/openspec/graph.json +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/fixtures/corpus/self-corpus/_provenance.json +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/fixtures/corpus/self-corpus/expected/retrieval-engine-reader.md +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/fixtures/corpus/self-corpus/graph.json +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/fixtures/flows/adr/0001-use-sessions.md +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/fixtures/flows/bmad/ARCHITECTURE-SPINE.md +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/fixtures/flows/bmad/tree/_bmad-output/planning-artifacts/architecture/architecture-payments-2026-07-30/.memlog.md +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/fixtures/flows/bmad/tree/_bmad-output/planning-artifacts/architecture/architecture-payments-2026-07-30/ARCHITECTURE-SPINE.md +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/fixtures/flows/bmad/tree/_bmad-output/planning-artifacts/prds/prd-payments-2026-07-30/prd.md +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/fixtures/flows/genkovich/0001-queue-backpressure.md +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/fixtures/flows/genkovich/sad.md +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/fixtures/flows/genkovich/tree/docs/features/payments/adr/0001-queue-backpressure.md +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/fixtures/flows/genkovich/tree/docs/features/payments/sad.md +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/fixtures/flows/genkovich/tree/docs/features/payments/spec.md +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/fixtures/flows/openspec/design-empty.md +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/fixtures/flows/openspec/design-h3-split.md +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/fixtures/flows/openspec/design-with-summary.md +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/fixtures/flows/openspec/design.md +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/fixtures/flows/openspec/proposal-alternatives.md +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/fixtures/flows/openspec/proposal.md +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/fixtures/flows/openspec/tree/openspec/changes/add-thing/design.md +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/fixtures/flows/openspec/tree/openspec/changes/add-thing/proposal.md +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/fixtures/flows/openspec/tree/openspec/changes/add-thing/specs/cap/spec.md +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/fixtures/flows/openspec/tree/openspec/changes/add-thing/tasks.md +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/fixtures/flows/openspec/tree/openspec/changes/archive/2026-01-01-add-thing/design.md +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/fixtures/flows/openspec/tree/openspec/changes/archive/2026-01-01-add-thing/proposal.md +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/fixtures/flows/openspec/tree/openspec/config.yaml +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/fixtures/flows/openspec/tree/openspec/specs/cap/spec.md +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/fixtures/flows/spec-kit/plan.md +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/fixtures/flows/spec-kit/tree/specs/003-payment-retries/plan.md +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/fixtures/flows/spec-kit/tree/specs/003-payment-retries/spec.md +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/fixtures/flows/superpowers/2026-07-01-example-design.md +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/fixtures/flows/superpowers/2026-07-01-thin-design.md +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/fixtures/member_names_python_graph.json +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/fixtures/member_names_swift_graph.json +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/fixtures/mini_graph.json +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/githooks_legacy_helper.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/githooks_support.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/graph_fixtures.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/graph_repo_support.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/membership_support.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/moved_adoption_support.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/opencode_plugin_runner.mjs +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/snapshot_support.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/store_format2_support.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/store_non_file_support.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/store_record_support.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_adr.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_adr_files.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_adr_identity.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_agent_brief_manifests.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_anchor_descriptor.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_anchor_paths.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_anchoring.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_anchoring_mapping_refresh.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_anchoring_membership.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_bash_paths.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_batch_panel_fixes.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_bootstrap_apply.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_bootstrap_catalog.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_bootstrap_cli.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_bootstrap_descriptor_cleanup.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_bootstrap_integrations.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_bootstrap_model.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_bootstrap_planner.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_bootstrap_proof.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_bootstrap_review.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_bootstrap_scan.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_bootstrap_scan_regular.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_bootstrap_unanchored.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_bounded_listings.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_capture_auto_accept.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_capture_facts.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_capture_initiative.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_capture_integration.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_capture_neighbors.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_capture_propose.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_capture_redact.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_cli_adr.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_cli_compact.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_cli_compact_format2.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_cli_domains.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_cli_domains_snapshot.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_cli_graph_paths.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_cli_import.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_cli_init.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_cli_init_hooks.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_cli_okf.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_cli_ratify.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_cli_ratify_facts.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_cli_stats.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_cli_store_precedence.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_cli_sync.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_cli_sync_check.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_cli_unreadable_paths.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_cli_viz.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_codex_plugin.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_command_windows.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_community_baseline.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_compact_skill.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_config.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_config_ancestor_lookup.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_config_borrowed_graph.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_corpus_expected_renders.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_corpus_self_corpus.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_coverage_telemetry_e2e.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_delivery_evidence.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_delivery_stats.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_delivery_surfaces.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_digest_integrity.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_doc_corpus_integration.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_doc_import.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_docs_claims.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_doctor.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_doctor_auto_share.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_doctor_dangling_supports.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_doctor_duplicate_entity.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_doctor_graph_root_mismatch.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_doctor_graph_stale.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_doctor_integrity.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_doctor_never_surfaced.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_doctor_scan.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_doctor_stale_instructions.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_doctor_unhashable_payload.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_doctor_unratified_accept.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_domain_seed_names.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_domain_snapshot_format.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_domain_snapshot_notices.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_domains.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_engine_build.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_entity_duplicate_resolution.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_entity_get_or_create_race.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_entity_twins.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_entry_point_arguments.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_env_isolation.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_fact_reachability_gate.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_file_bound_retrieval.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_flow_profile.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_format2_notices.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_format2_windows.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_git_bindings_blame.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_git_bindings_hook.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_git_bindings_provenance.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_git_env.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_git_output_utf8.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_githooks.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_githooks_atomic_lock.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_graph_freshness.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_graphify_pin.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_health_check_skill.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_hook_body_compaction.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_hook_contention.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_hook_failure_diagnostics.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_hook_payload_encoding.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_hook_showings.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_hook_spawn_guard.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_host_agent_brief.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_host_agent_state.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_host_borrowed_graph.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_host_claude_settings.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_host_launch.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_host_pretool.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_host_pretool_records.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_host_session_key.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_host_session_start.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_host_session_start_concurrent.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_host_stop.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_host_subagent_start.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_host_subdirectory_launch.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_host_touch_events.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_host_wiring_checks.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_hot_index_facts.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_hot_index_hook.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_hot_path_imports.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_import_dry_run_preview.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_importer.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_index_journal_mode.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_integrity_engine_version.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_integrity_refresh_hook.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_integrity_replay.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_integrity_stranded.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_lazy_root.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_maintenance_clock.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_maintenance_dry_run_parity.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_maintenance_plan.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_maintenance_publish.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_mcp_entry_ratify_policy.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_mcp_entry_repo_root.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_member_anchor_wiring.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_merge_matrix_format2.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_migrate.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_mind_model_additive_fields.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_muse_plugin.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_nearest_anchored.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_okf.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_opencode_plugin.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_openspec_profile.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_pathless_descriptor_adoption.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_pilot_kit_corpus_fit.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_portable_json.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_private_tests_isolation.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_proposal_lifecycle.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_public_hook_launch.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_ratify_listing_gone_dark.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_ratify_policy.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_rationale_compatibility.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_reader_community_labels.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_reader_doc_nodes.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_reader_engine_version.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_reader_file_labels.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_reader_graph.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_reader_integration.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_reader_label_conventions.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_reader_member_name_lookup.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_reader_member_names.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_reader_nodes_in_file.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_reader_perf.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_reader_rationale.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_reader_read.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_reader_resolve.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_reader_stub_collapse.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_reader_subdir_mismatch.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_reader_type_split.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_reader_version.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_readers_format2.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_rebuild_instruction.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_redaction_scan.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_redaction_seeded.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_redaction_tokens.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_repo_relative_paths_portable.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_repoint_integration.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_retrieval_budget_counters.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_retrieval_context.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_retrieval_drift_marker.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_retrieval_drilldown.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_retrieval_facts.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_retrieval_guessed.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_retrieval_ids.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_retrieval_integration.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_retrieval_membership_generations.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_retrieval_membership_index.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_retrieval_rank.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_retrieval_related_cap.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_retrieval_seeds.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_retrieval_shown_ids.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_retrieval_terminal_evidence.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_retrieval_thin_tools.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_retrieval_toc.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_retrieval_toptier.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_retrieval_unratified.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_schema_descriptor.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_schema_domain.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_schema_fact.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_security_capture_diagnostics.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_security_capture_limits.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_security_cli_diagnostics.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_security_doc_limits.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_security_input_limits.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_security_mcp_write_diagnostics.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_security_numeric_enums.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_security_python_shapes.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_security_redaction_cursor.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_security_write_boundary.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_seed_ladder.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_seed_paths_portable.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_server_add_anchors.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_server_anchoring.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_server_annotations.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_server_argument_names.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_server_borrowed_graph.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_server_capture.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_server_commit_hint.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_server_coverage_events.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_server_decision_listing.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_server_domains.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_server_drilldown.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_server_facts.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_server_find_entity.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_server_get_store.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_server_get_task_context.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_server_graph_freshness.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_server_graph_path.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_server_import.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_server_invocation_policy.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_server_mcp_smoke.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_server_nearest_anchored.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_server_prewrite_anchor_validation.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_server_ratify_facts.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_server_record_types.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_server_redaction.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_server_refresh.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_server_render_events.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_server_result_contract.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_server_supersede.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_server_sync_anchors.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_server_telemetry.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_server_thin_tools.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_server_tolerant_seeds.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_server_verify.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_session_attribution.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_skill_frontmatter.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_stats_graph.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_stats_health.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_stats_model.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_stats_render.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_stats_skill.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_stats_snapshot.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_stop_hot_path.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_stop_rearm.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_store.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_store_agent_state.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_store_atomic_write_tmp_names.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_store_bad_file.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_store_binding_index.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_store_canonical_stat.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_store_compact.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_store_coverage_telemetry.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_store_cross_process_mutations.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_store_derived_community.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_store_domain_members.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_store_domains.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_store_entities.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_store_fact_cascade.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_store_facts.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_store_file_anchor_names.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_store_format.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_store_format2_load.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_store_format2_marker.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_store_format2_writes.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_store_git_root_symlink.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_store_inventory.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_store_junctions.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_store_meta.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_store_migration.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_store_mutation_guard.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_store_mutation_immediate.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_store_non_file_entries.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_store_opens_with_merged_duplicate.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_store_persistence.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_store_ratification.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_store_rebuild_atomicity.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_store_record_identity.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_store_record_types.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_store_render_events.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_store_requirement.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_store_retrieval.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_store_rules.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_store_rules_legacy_defaults.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_store_slug_conflicts.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_store_snapshot_wiring.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_store_stamping_marker.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_store_symlinks.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_store_telemetry.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_store_threading.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_store_tmp_sweep_age.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_store_update_meta_if.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_subagent_start_manifests.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_subprocess_text_encoding.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_sync_canonical_writes.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_sync_clean.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_sync_domains.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_sync_drift_cache.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_sync_fresh_clone.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_sync_integration.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_sync_membership.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_sync_moved_adoption.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_sync_rebind.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_sync_repoint.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_sync_report_has_findings.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_sync_run.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_sync_snapshot_membership.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_sync_toc_cache.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_sync_volatile_heal.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_sync_wiring.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_telemetry_retention.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_text_paths.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_verify_domain_snapshot.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_verify_format2_against.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_verify_format2_snapshot.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_verify_git_framing.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_verify_git_revisions.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_verify_git_stdin.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_verify_snapshot.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_verify_transitions.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_viz_asset_packaged.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_viz_model.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_viz_render_html.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_viz_render_json.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/test_worktree_seeds.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/wheel_server_trace.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tests/wheel_smoke.py +0 -0
- {sidegraph-0.19.0 → sidegraph-0.20.0}/tools/check_no_session_links.py +0 -0
|
@@ -7,6 +7,44 @@ interfaces, exactly, and what each one promises: [`docs/reference/stability.md`]
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [0.20.0] — 2026-10-28
|
|
11
|
+
|
|
12
|
+
### Added
|
|
13
|
+
|
|
14
|
+
- **Contract change:** `record_drift_check` takes an optional `sections` argument for
|
|
15
|
+
markdown files: the sections you read, plus sections to also watch. The record then
|
|
16
|
+
re-arms on that file only when one of them, or the file's link reference definitions,
|
|
17
|
+
changes. The result echoes `declared_sections` (`first_line`, `lines`) and eleven new
|
|
18
|
+
fixed error codes name each refusal. The capsule gains an optional `declared_sections`
|
|
19
|
+
field inside `schema_version` 1 (hashes only, no heading text); plain capsules write an
|
|
20
|
+
empty list. An older release ignores the field, compares whole blobs and warns more,
|
|
21
|
+
never less. An unknown scheme or role, or a file whose structure cannot be bounded, still
|
|
22
|
+
compares by whole blob, and so does a partial clone on Git older than 2.45, where reading
|
|
23
|
+
section text could fetch objects.
|
|
24
|
+
- `sidegraph-doctor` groups per-record `code-drift` by the drifted file. Each record names the
|
|
25
|
+
blob it was compared against (a capture, check or scope baseline, with its mode) and shares
|
|
26
|
+
one `git diff <old blob> <new blob>` per distinct change; a mode-only or type change says so.
|
|
27
|
+
A record whose anchored Python function or Markdown section is identical at both ends carries
|
|
28
|
+
`anchored region unchanged; sibling sections of the file may still matter`, a reading aid
|
|
29
|
+
that never clears or reorders anything. `--json` gains a `drift_groups` key; `findings` is
|
|
30
|
+
unchanged. `--flat` restores one line per record and skips the grouping.
|
|
31
|
+
- `markdown-it-py>=4,<5` is a direct dependency (Markdown heading spans for the hint and for
|
|
32
|
+
declared sections).
|
|
33
|
+
|
|
34
|
+
### Changed
|
|
35
|
+
|
|
36
|
+
- The SessionStart drift line says how many of the records needing review are recent:
|
|
37
|
+
`Sidegraph: 190 record(s) need content review (12 new in the last 7 days): …`, or
|
|
38
|
+
`(none new in the last 7 days)`. A record without a recorded first-seen time counts as
|
|
39
|
+
unknown age, never as new. An index built before this version prints the line without the
|
|
40
|
+
clause on its first day, `(none new since <date>)` while its stamping is younger than
|
|
41
|
+
7 days, and `(none new in the last 7 days)` from then on, until a record newly drifts.
|
|
42
|
+
`SIDEGRAPH_DRIFT_NUDGE=off` silences it with the rest of the line.
|
|
43
|
+
- `sidegraph-doctor --json` findings carry `first_seen`: the ISO time a `code-drift`
|
|
44
|
+
record was first seen drifted, otherwise `null`.
|
|
45
|
+
- The default `sidegraph-doctor` text for per-record `code-drift` is the grouped block above
|
|
46
|
+
instead of one line per record. The summary count, `--check` and the exit codes are unchanged.
|
|
47
|
+
|
|
10
48
|
## [0.19.0] — 2026-10-27
|
|
11
49
|
|
|
12
50
|
### Changed
|
|
@@ -13,7 +13,7 @@ task-aware retrieval + decision memory riding on the engine's entity graph.
|
|
|
13
13
|
continuing participant in the project. A core feature must preserve, organize, or deliver
|
|
14
14
|
accumulated project understanding. Document search by itself is not the product.
|
|
15
15
|
|
|
16
|
-
Sidegraph is pre-1.0 (v0.
|
|
16
|
+
Sidegraph is pre-1.0 (v0.20.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
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: sidegraph
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.20.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
|
|
@@ -24,6 +24,7 @@ Requires-Python: >=3.13
|
|
|
24
24
|
Requires-Dist: anyio>=4
|
|
25
25
|
Requires-Dist: certifi>=2026.10.19
|
|
26
26
|
Requires-Dist: fastmcp<4,>=3.4.10
|
|
27
|
+
Requires-Dist: markdown-it-py<5,>=4
|
|
27
28
|
Requires-Dist: mcp<2,>=1.30
|
|
28
29
|
Requires-Dist: opentelemetry-api>=1.45.1
|
|
29
30
|
Requires-Dist: pydantic>=2.9
|
|
@@ -133,6 +133,9 @@ Anchoring and sync collapse the stubs; what agents read keeps the ambiguous answ
|
|
|
133
133
|
|
|
134
134
|
## Why multi-anchor matters for doc corpora
|
|
135
135
|
|
|
136
|
+
Anchoring decides where a record surfaces. Which sections of a long document a later
|
|
137
|
+
`record_drift_check` must watch is declared when the record is checked, not anchored.
|
|
138
|
+
|
|
136
139
|
On a docs corpus (ADRs/SAD), both a heading and its containing file are anchorable nodes
|
|
137
140
|
(`file_type` in `{code, document, concept, rationale}` — an allowlist that also keeps
|
|
138
141
|
unanchorable types like `image` out, per the same never-guess principle; `concept` and
|
|
@@ -314,8 +314,9 @@ the shared canonical digest/index record tables. See
|
|
|
314
314
|
| `required_files` | list[str] | Exact current required anchor-file set, separate from optional inspected dependencies. |
|
|
315
315
|
| `checked_files` | list[`CheckedCodeFile`] | Explicit inspected regular-file snapshots, covering every required file; 1–256 unique safe paths. |
|
|
316
316
|
| `subject_digest` | str | SHA-256 of fixed immutable decision/provenance fields and durable leaf descriptors; excludes lifecycle and volatile mapping/status fields. |
|
|
317
|
+
| `declared_sections` | list[`DeclaredSectionFile`] | Optional per-file section scope for markdown files, `[]` for a plain whole-file check; at most 64 entries, each path one of `checked_files`. |
|
|
317
318
|
|
|
318
|
-
Changed inspected files/modes or required scope re-arm review. A matching snapshot after
|
|
319
|
+
Changed inspected files/modes or required scope re-arm review; for a file with declared sections, a change to a declared or also-watched section, or to the file's link definitions, re-arms instead of any change to the file. A matching snapshot after
|
|
319
320
|
an unrelated commit remains covered. A mistaken semantic assertion cannot be detected
|
|
320
321
|
from these hashes; a genuine successor corrects the decision and preserves the check as
|
|
321
322
|
history. Optional comparison failure has the bounded behavior described in store-format.
|
|
@@ -330,3 +331,25 @@ mappings. The total checked-path budget is 16384 UTF-8 bytes.
|
|
|
330
331
|
| `path` | str | Safe repository-relative forward-slash path, at most 1024 UTF-8 bytes. |
|
|
331
332
|
| `blob_id` | str | Full Git content address of the inspected file. |
|
|
332
333
|
| `mode` | `100644` \| `100755` | Regular-file Git mode; mode changes participate in applicability. |
|
|
334
|
+
|
|
335
|
+
## `DeclaredSectionFile` — declared sections of one checked file
|
|
336
|
+
|
|
337
|
+
Nested in `DriftCheck`; this stores locators and digests, never heading text or source
|
|
338
|
+
bodies. A scheme or role this release does not know is accepted and compared by whole blob.
|
|
339
|
+
|
|
340
|
+
| Field | Type | Meaning |
|
|
341
|
+
|---|---|---|
|
|
342
|
+
| `path` | str | One of the check's `checked_files`; unique across entries. |
|
|
343
|
+
| `scheme` | token | How sections are located; `md1` (markdown block structure) is the one scheme this release resolves. |
|
|
344
|
+
| `refs_hash` | hex \| `null` | `md1`: digest of the file's link reference definitions. |
|
|
345
|
+
| `sections` | list[`DeclaredSection`] | 1–256 sections; at most 1024 across the check. |
|
|
346
|
+
|
|
347
|
+
## `DeclaredSection` — one declared or also-watched section
|
|
348
|
+
|
|
349
|
+
Nested in `DeclaredSectionFile`.
|
|
350
|
+
|
|
351
|
+
| Field | Type | Meaning |
|
|
352
|
+
|---|---|---|
|
|
353
|
+
| `heading_hash` | hex | `md1`: digest of the heading chain that locates the section. |
|
|
354
|
+
| `role` | token | `declared` (the checker read it) or `watch` (a sibling the claim depends on). |
|
|
355
|
+
| `text_hash` | hex | `md1`: digest of the section's text, subsections included. |
|
|
@@ -45,7 +45,8 @@ with Git for Windows installed; they do not establish support for Windows hosts
|
|
|
45
45
|
remains outside these checks.
|
|
46
46
|
See [Windows](#windows) before installing a host plugin.
|
|
47
47
|
|
|
48
|
-
Package dependencies support `fastmcp>=3.4.10,<4
|
|
48
|
+
Package dependencies support `fastmcp>=3.4.10,<4`, `mcp>=1.30,<2` and `markdown-it-py>=4,<5`
|
|
49
|
+
(markdown section scope for drift checks). Runtime security
|
|
49
50
|
floors also require `certifi>=2026.10.19` and
|
|
50
51
|
`opentelemetry-api>=1.45.1`, including standalone wheel installations. Major SDK upgrades
|
|
51
52
|
require a separate compatibility review; an unlocked package install may resolve newer
|
|
@@ -42,6 +42,9 @@ named, is a separate decision-level Tier-0 binding made by the write path, not p
|
|
|
42
42
|
`name` is a **heading text** or the **file name itself**; for code, a **function/class name**
|
|
43
43
|
or the file — all valid entity names in a Graphify graph.
|
|
44
44
|
|
|
45
|
+
For a long document, section scope is declared when the record is checked (see
|
|
46
|
+
[`record_drift_check`](../reference/mcp-tools.md#record_drift_check)), not when it is anchored.
|
|
47
|
+
|
|
45
48
|
**Always add the containing file as a second anchor — for code symbols and doc headings
|
|
46
49
|
alike.** A heading rename or symbol move orphans the precise anchor on the next sync; the
|
|
47
50
|
file anchor survives and keeps the decision retrievable (and its community fallback intact).
|
|
@@ -297,5 +297,8 @@ Use `sidegraph:triage-drift` to read the claim and current code. If the claim st
|
|
|
297
297
|
`record_drift_check` can append a justified inspection of the current clean committed
|
|
298
298
|
files without changing the decision. If it no longer holds, propose a real successor.
|
|
299
299
|
The [tool reference](../reference/mcp-tools.md#record_drift_check) describes refusal cases
|
|
300
|
-
and coverage. Changed inspected files or scope re-arm the warning
|
|
301
|
-
|
|
300
|
+
and coverage. Changed inspected files or scope re-arm the warning, and for a markdown file
|
|
301
|
+
checked with declared sections only a change to a declared or also-watched section or to the
|
|
302
|
+
file's link definitions does; unrelated commits do not. The check is an attributed assertion and can be wrong. `sidegraph-doctor` groups the
|
|
303
|
+
records by drifted file and may note `anchored region unchanged; sibling sections of the file
|
|
304
|
+
may still matter`: that shortens the reading, it does not replace it.
|
|
@@ -134,7 +134,8 @@ notice.
|
|
|
134
134
|
Records needing content review after code changed or a prior scoped check stopped applying.
|
|
135
135
|
The line says how many. Inspect current code: record an explicit `record_drift_check` if the
|
|
136
136
|
claim still holds, or propose a real successor if it does not. There is no user notice.
|
|
137
|
-
`sidegraph-doctor` lists them as `code-drift` findings,
|
|
137
|
+
`sidegraph-doctor` lists them as `code-drift` findings, grouped by the drifted file with one `git diff` per distinct
|
|
138
|
+
change (`sidegraph-doctor --flat` prints one line per record instead), and the `sidegraph:triage-drift` skill walks them.
|
|
138
139
|
`SIDEGRAPH_DRIFT_NUDGE=off` silences the line.
|
|
139
140
|
|
|
140
141
|
### graph-borrowed
|
|
@@ -1515,7 +1515,7 @@ Once any record, hot or archived, carries an `auto:` stamp, two more information
|
|
|
1515
1515
|
When an entity is named by a path, full or partial, of its file (`src/sidegraph/store.py`, `sidegraph/store.py`) beside one named by that file's basename (`store.py`), a `spelling twins: N …` line follows, then one line per such entity: `<id> '<path name>' (K binding(s)) → <id> '<basename>' (M binding(s))`. Lookups and new anchors use the basename entity, and retrieval reaches both, so there is nothing to fix. Like the lines above, these are never findings, never change the exit code, and never appear in `--json`.
|
|
1516
1516
|
|
|
1517
1517
|
```
|
|
1518
|
-
sidegraph-doctor [--db PATH] [--against GIT_REF] [--check] [--stale-days N] [--json] [--graph PATH]
|
|
1518
|
+
sidegraph-doctor [--db PATH] [--against GIT_REF] [--check] [--stale-days N] [--json] [--flat] [--graph PATH]
|
|
1519
1519
|
```
|
|
1520
1520
|
|
|
1521
1521
|
| Flag | Default | Meaning |
|
|
@@ -1524,7 +1524,8 @@ sidegraph-doctor [--db PATH] [--against GIT_REF] [--check] [--stale-days N] [--j
|
|
|
1524
1524
|
| `--against GIT_REF` | none | also run `sidegraph-verify`'s transition layer vs `GIT_REF` (identical semantics — same operational-error rules) |
|
|
1525
1525
|
| `--check` | off | advisory findings also exit `2`, except `maintenance-due` (default: report only; a *skipped* check never fails, even with `--check`) |
|
|
1526
1526
|
| `--stale-days N` | `30` | flag a proposed decision/domain whose id timestamp is strictly older than `N` days; must be `>= 0` |
|
|
1527
|
-
| `--json` | off | print `{"clean", "violations", "findings", "skipped"}` as one JSON object to stdout (nothing else) |
|
|
1527
|
+
| `--json` | off | print `{"clean", "violations", "findings", "skipped"}`, plus `drift_groups` when per-record `code-drift` is grouped, as one JSON object to stdout (nothing else) |
|
|
1528
|
+
| `--flat` | off | one `code-drift` line per record, as before: restores the flat listing and skips the grouping by file |
|
|
1528
1529
|
| `--graph` | `$SIDEGRAPH_GRAPH` or `graphify-out/graph.json`, in the store's project | read-only input used for the `graph-root-mismatch` and `graph-stale` checks below; missing or unreadable skips both and says so (see *Skipped checks* below) |
|
|
1529
1530
|
|
|
1530
1531
|
One-stop store health: composes `sidegraph-verify`'s strict snapshot (+ optional
|
|
@@ -1554,7 +1555,7 @@ plain-text line):
|
|
|
1554
1555
|
| `stale-proposal` | a proposed decision/domain whose ULID timestamp is strictly older than `--stale-days` |
|
|
1555
1556
|
| `unreferenced-entity` | a hot entity no committed anchor set references (structural `domain:*`/`community:*` entities are exempt) |
|
|
1556
1557
|
| `expired-open-validity` | a decision's `valid_to` is strictly past but its status is still open (`proposed`/`accepted`) |
|
|
1557
|
-
| `code-drift` | an open (`proposed`/`accepted`) decision's anchored file(s) changed since capture, or an earlier scoped check no longer applies; `record_drift_check` can record an explicit current inspection without rewriting the decision (MCP only); when binding statuses are uncomputed or unavailable, excludes committed deletions and says "binding status unknown"; also carries the "N record(s) predate commit stamping — not checkable" and git-unavailable notes, in place, when either applies |
|
|
1558
|
+
| `code-drift` | an open (`proposed`/`accepted`) decision's anchored file(s) changed since capture, or an earlier scoped check (including its declared sections) no longer applies; `record_drift_check` can record an explicit current inspection without rewriting the decision (MCP only); when binding statuses are uncomputed or unavailable, excludes committed deletions and says "binding status unknown"; also carries the "N record(s) predate commit stamping — not checkable" and git-unavailable notes, in place, when either applies. The default text groups the per-record lines by drifted file (`code-drift: N record(s) in M file group(s)`), numbers each distinct `git diff <old blob> <new blob>` once, and may add `anchored region unchanged; sibling sections of the file may still matter` to a record whose anchored Python function or Markdown section is textually identical at both ends; `--flat` restores one line per record. The hint is a reading aid, never a verdict: it changes no count and no exit code. `--json` adds a sibling `drift_groups` key (`partial`, `notes`, `groups[].records[]` with `basis`, `reason`, `diff` and `hint`); `findings` is unchanged |
|
|
1558
1559
|
| `never-surfaced` | an accepted decision has `0` shows against `N > 0` queries on its anchored file(s) — anchored where people repeatedly work, never once rendered or injected by a hook |
|
|
1559
1560
|
| `stale-instructions` | an auto-injected agent-instructions file beside the store (`CLAUDE.md`, `AGENTS.md`, `GEMINI.md`, `.cursorrules`) still carries the distinctive wording of a **superseded** decision — that file reaches the agent at turn zero, before retrieval, so an abandoned rule surviving there outranks the store's correction by default. Verbatim-ish match on normalized text with length/word floors; superseded records only; no git call. Advisory: it reports a quotation, not a proven contradiction — the file may be narrating history |
|
|
1560
1561
|
| `unratified-accept` | an **accepted** record whose provenance says `agent` and which carries no ratifier stamp — the signature `SIDEGRAPH_AUTO_ACCEPT=on` leaves in a shared store (one environment's setting bypassing the ratification gate for everyone). Scoped to records created at/after the EARLIER of the store's earliest ratifier stamp and its creation marker (`.sidegraph/stamping_live_since`, written once when a store is genuinely new — never backfilled onto an existing one), so a store predating both reports nothing rather than everything; a store that has never ratified anything but was created by a marker-writing version is still in scope from its own creation, closing the blind window an unratified store would otherwise sit in forever. A stamped record — including one stamped `auto:<policy>` by an auto-ratification policy — and a human-sourced one are never flagged. A **supersession successor** (`supersedes` set — `supersede_decision`/`supersede_fact`) is never flagged either: reversal has no ratification queue to bypass and lands accepted immediately by design, so it reproduces the signature with no relation to the env var this check hunts. Narrowed exception: a `supersedes`-bearing record IS still flagged if it carries a `layer`, a `provenance.ref`, or a tier-0 `tag:`/`initiative:` binding absent from its predecessor — neither `supersede_decision` nor `supersede_fact` can produce any of the three, so one present proves the `propose_decisions`/auto-accept path wrote it. (The fact half is defensive only: `supersede_fact` always stamps `source="human"`, so a fact successor never reaches this agent-sourced check, and no draft shape carries `supersedes` on a fact.) Only a MINIMAL superseding draft (none of the three) is indistinguishable from a legitimate successor by the record's own fields, and stays excluded — a known, accepted, narrower trade-off than treating every supersession alike. Advisory: the signature is not proof — verify before concluding |
|
|
@@ -1620,7 +1621,8 @@ neither flagged nor cleared. `drill_down` does record a `domain:<slug>` seed, bu
|
|
|
1620
1621
|
consumes it yet; its *shows* count normally, so surfacing only through a domain drill-down
|
|
1621
1622
|
still protects a decision from a false flag.
|
|
1622
1623
|
|
|
1623
|
-
Each JSON finding has `code`, `path`, `detail`, `record_id` and `
|
|
1624
|
+
Each JSON finding has `code`, `path`, `detail`, `record_id`, `record_type` and `first_seen`
|
|
1625
|
+
(the ISO time Sidegraph first saw a `code-drift` finding's record drifted, otherwise `null`).
|
|
1624
1626
|
Per-record findings carry their logical identity (`decision`, `fact`, `entity`, `domain`,
|
|
1625
1627
|
or `bindings`); global notes have null record fields. A malformed raw record whose id
|
|
1626
1628
|
cannot be read also has a null subject; use its violation and physical path for repair. `path` retains the physical source,
|
|
@@ -15,7 +15,7 @@ a per-call parameter, not an environment/config setting.
|
|
|
15
15
|
| `SIDEGRAPH_CAPTURE_NUDGE` | unset | `host/hooks.py` (`stop` only). Set to `off` to disable the `Stop` block-to-distill nudge entirely — no other value has any effect. See [`reference/hooks.md`](hooks.md#sidegraph-stop). |
|
|
16
16
|
| `SIDEGRAPH_RATIFY_NUDGE` | unset | `host/hooks.py` (`session_start` only). Set to `off` to disable the pending-ratification line entirely — no other value has any effect. See [`reference/hooks.md`](hooks.md#sidegraph-session-start). |
|
|
17
17
|
| `SIDEGRAPH_SUBAGENT_BRIEF` | unset | `host/subagent.py` (`subagent_start` only). Set to `off` to stop the `SubagentStart` hook from giving each subagent the memory brief — no other value has any effect. See [`reference/hooks.md`](hooks.md#sidegraph-subagent-start). |
|
|
18
|
-
| `SIDEGRAPH_DRIFT_NUDGE` | unset | `host/hooks.py` (`session_start` and `stop`). Set to `off` to suppress the two drift PROSE surfaces — the SessionStart "N record(s) need content review" line and the Stop-nudge drift clause. **The code-drift cache refresh still runs either way** (it is what keeps the `[drifted]` retrieval markers fresh — gating it would freeze markers at their last pre-`off` state), and the `[drifted]` tags in `get_task_context`/`query_decisions`/`drill_down` output are retrieval content, not gated by this switch. No other value has any effect. See [`reference/hooks.md`](hooks.md#sidegraph-session-start). |
|
|
18
|
+
| `SIDEGRAPH_DRIFT_NUDGE` | unset | `host/hooks.py` (`session_start` and `stop`). Set to `off` to suppress the two drift PROSE surfaces — the SessionStart "N record(s) need content review" line (its recency clause included) and the Stop-nudge drift clause. **The code-drift cache refresh still runs either way** (it is what keeps the `[drifted]` retrieval markers fresh — gating it would freeze markers at their last pre-`off` state), and the `[drifted]` tags in `get_task_context`/`query_decisions`/`drill_down` output are retrieval content, not gated by this switch. No other value has any effect. See [`reference/hooks.md`](hooks.md#sidegraph-session-start). |
|
|
19
19
|
| `SIDEGRAPH_AUTO_ACCEPT` | unset | `server.py` (`propose_decisions`'s tool shell, read at point of use via `_auto_accept()`). Set to `on` to land agent-proposed decisions and facts as `status="accepted"` directly, bypassing the ratification queue — no other value has any effect, and `propose_domains` is never affected by this flag (domains always land `proposed` under it; only `SIDEGRAPH_RATIFY_POLICY=auto-all` can ratify an eligible domain, with a stamp). Detectable after the fact: `sidegraph-doctor`'s `unratified-accept` finding reports accepted agent-sourced records carrying no ratifier stamp, so a shared store can assert the gate in CI rather than trust it. See [`guides/capturing-decisions.md#4-auto-accept-opt-in`](../guides/capturing-decisions.md#4-auto-accept-opt-in). |
|
|
20
20
|
| `SIDEGRAPH_RATIFY_POLICY` | unset (`"manual"`) | `server.py` (`_ratify_policy()`, read at point of use inside the `propose_decisions` and `propose_domains` tool shells) and `cli.py` (each of the doc-import, rationale-import, and domain-bootstrap commands, read once immediately before its batch call). Parsed by the pure `capture.parse_ratify_policy`, which never reads the environment itself — every reader above resolves the raw value and threads the parsed policy down as a keyword, so one batch samples a single value throughout. `manual` (default) introduces no new transition and leaves every existing write path's semantics exactly as they are — it does not mean every write lands `proposed`; some paths already land `accepted` under their own pre-existing flags (e.g. `importer.py`'s `propose=False`), unaffected by this knob. `auto-low-risk` lets eligible `lesson`/`gotcha` decisions and standalone facts self-ratify at write time (never `adr`/`constraint` decisions or domains). `auto-all` additionally admits `adr`/`constraint` decisions and domains. Eligibility is deterministic and conjunctive: the policy admits the shape (under `auto-low-risk` a draft that `supersedes` another is never eligible); the record has at least one live Tier-1/Tier-2 anchor binding (a domain instead needs a graph reader, a clean `path_prefixes` lint, and a resolving seed anchor or non-empty prefixes); the write was clean and not a dry run; provenance is present. An attached fact never ratifies itself — it rides its decision's cascade, and one ineligible attached fact keeps the decision proposed. Scope: `propose_decisions` (decisions and standalone facts), `propose_domains` (`auto-all` only), `sidegraph-import` rationale mode only with `--propose`, `sidegraph-import --docs` only for `--propose` writes that land as a new `proposed` record (status-derived drafts, `superseded` re-imports and `status: rejected` documents never auto-ratify), and `sidegraph-domains bootstrap` (`auto-all` only; a candidate whose derived `path_prefixes` is empty stays proposed); `--dry-run` never transitions, and `add_domain`, `sidegraph-domains add`, `supersede_domain` successors and `sidegraph-bootstrap` are never affected. Under either auto policy a superseding proposal's predecessor stays open until the successor is ratified — automatically, or later by a human. Outcomes are always reported: `ratified_by`/`auto_ratify_error` on each propose result; under a non-`manual` policy the three CLI batch summaries append `, auto-ratified N` and print each failure on stderr as `auto-ratify failure: <id>: <reason>`; `sidegraph-doctor` adds two informational lines (see [`cli.md`](cli.md#sidegraph-doctor)). Matching is exact after trimming surrounding whitespace — `AUTO-ALL` falls back to `manual`. `sidegraph-init` never writes this value silently: in an interactive terminal it asks one question, defaulting to `auto-low-risk` on a bare Enter, and writes whichever answer the person gave (`auto-low-risk` or `manual`) into the project's `.claude/settings.json` `env` block explicitly; outside a terminal (CI, a script, an agent-driven session) it asks nothing and writes nothing, printing the line to add by hand instead; either way it never overwrites an existing value there. `--ratify-policy VALUE` sets it with no prompt, and `--no-settings` skips the whole step (see [`cli.md`](cli.md#sidegraph-init)). `manual` remains the library's own default when the variable is unset with no committed override, and is also what a freshly initialized project gets unless a person answers yes to the prompt (or passes `--ratify-policy auto-low-risk`/`auto-all`); `adr`/`constraint` decisions and domains still wait for a human under both `manual` and `auto-low-risk`. For a committed, CI-checkable setting, pin it in the repository's `.claude/settings.json` `env` block. Claude Code applies that block to the MCP server; under any other host the `sidegraph-mcp` entry point reads the committed value from the selected store's project when its environment sets none (an explicit environment value wins), so the policy also applies under Codex. Any unknown or empty value falls back to `manual` — fail-safe, never fail-open, the `SIDEGRAPH_PROPOSAL_WINDOW_DAYS` precedent. Auto-ratified records are stamped `ratified_by="auto:<policy>"`, distinguishing them from human review. When both knobs are set, legacy `SIDEGRAPH_AUTO_ACCEPT=on` wins over this policy — its direct-`ACCEPTED`, stamp-less write lands before any auto-ratify block runs, and `sidegraph-doctor`'s `unratified-accept` finding keeps flagging it regardless. |
|
|
21
21
|
| `SIDEGRAPH_UNRATIFIED` | unset (`"on"`) | `store_layout.py` (`proposal_surfaces`, read at point of use — the single proposal-surfacing policy every render surface funnels through: `retrieval.py` delegates to it, and so does the PreToolUse hook's index reader). Set to `off` for **regulated mode**: `proposed` records never surface as content — not in `get_task_context`, drill-down, the SessionStart TOC's unratified block, the PreToolUse records block, or the records appended to a subagent's brief on an `Agent` call — regardless of age. The `SubagentStart` brief's counts then include accepted decisions only. The SessionStart pending-ratification **counter stays** (it is queue metadata, not record content). No other value has any effect. For a committed, CI-checkable setting, pin it in the repository's `.claude/settings.json` `env` block. See [`hooks.md`](hooks.md#sidegraph-session-start). |
|
|
@@ -256,10 +256,18 @@ raises costs only its own line.
|
|
|
256
256
|
`$SIDEGRAPH_DRIFT_NUDGE != "off"`, one more line is appended (own `try/except`, same
|
|
257
257
|
never-cost-the-map guard as step 6). Verbatim, with `N` substituted:
|
|
258
258
|
|
|
259
|
-
> Sidegraph: N record(s) need content review: code changed or a prior check no longer applies —
|
|
259
|
+
> Sidegraph: N record(s) need content review (M new in the last 7 days): code changed or a prior check no longer applies —
|
|
260
260
|
> task-relevant ones carry a [drifted] tag in retrieval; full list: sidegraph-doctor;
|
|
261
261
|
> record_drift_check if still true, supersede if no longer true.
|
|
262
262
|
|
|
263
|
+
The parenthesised clause counts the records first seen drifted within the last 7 days; it
|
|
264
|
+
reads `(none new in the last 7 days)` when there are none and `(M new since YYYY-MM-DD)`
|
|
265
|
+
while the index is younger than 7 days. A record the store has not stamped counts as unknown
|
|
266
|
+
age, never as new, and the clause is left out whenever it cannot be certified. An index
|
|
267
|
+
built before this version prints no clause on its first day (a zero count that early says
|
|
268
|
+
nothing), `(none new since <date>)` while its stamping is younger than 7 days, and
|
|
269
|
+
`(none new in the last 7 days)` from then on, until a record newly drifts.
|
|
270
|
+
|
|
263
271
|
`N` counts the whole store; the `[drifted]` tags (see
|
|
264
272
|
[`concepts/retrieval.md`](../concepts/retrieval.md)) mark only the records a given
|
|
265
273
|
retrieval call actually surfaces — the line says where each lives. A duplicate
|
|
@@ -30,7 +30,8 @@ Git commands for provenance, initiative, ratification identity and graph checks
|
|
|
30
30
|
EOF on standard input, keeping subprocesses separate from the MCP protocol stream.
|
|
31
31
|
|
|
32
32
|
The development lockfile selects FastMCP 3.4.11 and MCP Python SDK 1.30.0. Supported package
|
|
33
|
-
dependencies are `fastmcp>=3.4.10,<4
|
|
33
|
+
dependencies are `fastmcp>=3.4.10,<4`, `mcp>=1.30,<2` and `markdown-it-py>=4,<5` (it reads
|
|
34
|
+
markdown structure for [declared-section drift checks](#record_drift_check)), with runtime security floors
|
|
34
35
|
`certifi>=2026.10.19` and `opentelemetry-api>=1.45.1`. The locked stack
|
|
35
36
|
uses the `initialize` / `notifications/initialized` lifecycle and negotiates protocol
|
|
36
37
|
versions through **2025-11-25**. The server reports Sidegraph's package version in
|
|
@@ -1816,6 +1817,7 @@ record_drift_check(
|
|
|
1816
1817
|
checked_commit: str, # current full inspected Git HEAD
|
|
1817
1818
|
files: list[str], # all required anchor files plus inspected dependencies
|
|
1818
1819
|
rationale: str, # nonblank, redacted before validation; at most 4000 characters
|
|
1820
|
+
sections: list[dict] | None = None, # optional: markdown sections you read
|
|
1819
1821
|
) -> dict
|
|
1820
1822
|
```
|
|
1821
1823
|
|
|
@@ -1840,8 +1842,49 @@ An unloadable required entity returns `unavailable_anchor_scope`; a failed initi
|
|
|
1840
1842
|
scope lookup returns `git_scope_unavailable`. Both refusals occur before check publication.
|
|
1841
1843
|
Write errors keep their bounded schema vocabulary and do not echo file names or raw causes.
|
|
1842
1844
|
|
|
1845
|
+
**Declared sections.** For a markdown file in `files`, `sections` narrows the check to the
|
|
1846
|
+
sections you read:
|
|
1847
|
+
|
|
1848
|
+
```python
|
|
1849
|
+
sections=[{"file": "docs/spec.md",
|
|
1850
|
+
"headings": [["55.2 Rules"]], # 1-32 declared, read at HEAD
|
|
1851
|
+
"also_watch": [["56. Echo", "56.4 Amendments"]]}] # 0-32 siblings the claim depends on
|
|
1852
|
+
```
|
|
1853
|
+
|
|
1854
|
+
Each chain is the trailing part of a heading chain, outermost first, 1-6 segments of 1-200
|
|
1855
|
+
characters; a suffix matching two sections is `ambiguous_section`. At most 16 files, 32
|
|
1856
|
+
sections per file and 64 per check; every `file` must be in `files` and end in `.md` or
|
|
1857
|
+
`.markdown`. The writer resolves each chain against the HEAD blob and stores hashes only: no
|
|
1858
|
+
heading text reaches the capsule. A section includes its subsections, up to the next heading
|
|
1859
|
+
of the same or a higher level. Never declare a section you did not read. Afterwards the record
|
|
1860
|
+
re-arms on that file only when a declared or also-watched section, or the file's link
|
|
1861
|
+
reference definitions, change; other checked files compare as before. A file whose structure
|
|
1862
|
+
cannot be bounded is compared whole, as are unknown schemes and roles. Section parsing uses
|
|
1863
|
+
`markdown-it-py` (CommonMark block structure, no inline pass).
|
|
1864
|
+
|
|
1865
|
+
The writer refuses with these fixed codes, before anything is published:
|
|
1866
|
+
|
|
1867
|
+
| Code | When |
|
|
1868
|
+
|---|---|
|
|
1869
|
+
| `section_file_not_in_files` | a `sections` file is not in `files` |
|
|
1870
|
+
| `section_file_not_markdown` | the extension is not `.md` or `.markdown` |
|
|
1871
|
+
| `section_file_too_large` | one declared blob is over 2 MiB or 20,000 lines |
|
|
1872
|
+
| `section_scope_too_large` | the distinct declared blobs together exceed 8 MiB or 20,000 lines |
|
|
1873
|
+
| `section_text_unavailable` | the text is not UTF-8, could not be read (including any read in a partial clone on Git older than 2.45, which could fetch), or the 3 s budget ran out |
|
|
1874
|
+
| `section_file_unsupported` | a heading sits inside a list item or quote, a footnote reference is in a declared span, or a parser cap was hit |
|
|
1875
|
+
| `unknown_section` | no heading chain ends with the given segments |
|
|
1876
|
+
| `ambiguous_section` | the suffix matches more than one section |
|
|
1877
|
+
| `duplicate_section` | the same section twice, or in both lists |
|
|
1878
|
+
| `duplicate_section_file` | a `file` appears twice |
|
|
1879
|
+
| `too_many_sections` | over 32 sections in a file or 64 in a check |
|
|
1880
|
+
|
|
1843
1881
|
The result names `id`, `decision_id`, `checked_commit`, `required_files`, `checked_files`,
|
|
1844
|
-
`provenance`, `cache_cleared` and `redactions`. `
|
|
1882
|
+
`provenance`, `cache_cleared` and `redactions`. With `sections` it also carries
|
|
1883
|
+
`declared_sections`: per file `{path, scheme, total_lines, sections: [{heading, role,
|
|
1884
|
+
first_line, lines}]}`, the readable chain you declared with its 1-based first line and length.
|
|
1885
|
+
Check it: a section spanning most of the file gains nothing, and a `first_line` that is not
|
|
1886
|
+
where the heading sits in your viewer means the parser disagrees with your renderer, so make a
|
|
1887
|
+
whole-file check. The echo is never stored. `cache_cleared` only says whether an existing
|
|
1845
1888
|
valid derived cache contained and removed this decision; other cached ids stay intact.
|
|
1846
1889
|
When additional anchor paths lie outside inspected coverage, pruning is deferred to the
|
|
1847
1890
|
normal refresh so a check cannot hide their capture warning.
|
|
@@ -1851,7 +1894,12 @@ retrying; SQLite rollback does not remove an already published immutable file.
|
|
|
1851
1894
|
|
|
1852
1895
|
A matching check compares current decision/leaf identity, exact required-file coverage,
|
|
1853
1896
|
and stored file blob ids plus modes. Changed checked dependencies, deletion, mode or
|
|
1854
|
-
subject/scope changes re-arm review even if capture's original files match again.
|
|
1897
|
+
subject/scope changes re-arm review even if capture's original files match again. For a
|
|
1898
|
+
file with declared sections, only a change to a declared or also-watched section or to the
|
|
1899
|
+
file's link reference definitions re-arms it; the reasons are `declared section changed`,
|
|
1900
|
+
`declared section not found`, `also-watched section changed` and `referenced link definition
|
|
1901
|
+
changed`, and `section scope unavailable; whole file compared` when the sections cannot be
|
|
1902
|
+
bounded (the whole file then re-arms on any change, as before).
|
|
1855
1903
|
Unrelated commits and identical bytes after squash/revert do not re-arm. The original
|
|
1856
1904
|
checked commit remains provenance and need not exist locally after a squash/clone.
|
|
1857
1905
|
Git/FS edits outside Sidegraph can race the final cleanliness/HEAD check and publication;
|
|
@@ -25,8 +25,8 @@ described a mode that had not existed for weeks, because no test looked there.
|
|
|
25
25
|
|
|
26
26
|
| Surface | What is fixed | What guards it |
|
|
27
27
|
|---|---|---|
|
|
28
|
-
| **The store on disk** — `.sidegraph/` layout (one JSON file per record, and from 0.17 optionally packed `shards/`), the `format` marker, `schema_version` | The current version is **0.6.0** (a format-2 store's index is stamped `0.7.0+format2`). `0.2.0`/`0.3.0` stores migrate automatically on first open (original kept as `*.migrated-backup`, never deleted). `0.4.0`/`0.5.0` reload in place. A future bump does one of those two or, as format 2 did, an explicit migration command (`sidegraph-migrate`) while the old format stays served — it never orphans a store. A store can require a minimum Sidegraph version (`sidegraph-require`): its marker becomes `sidegraph-store 1.0.0` plus `requires-sidegraph >= X.Y.Z`, and older versions refuse it. A packed store's marker is `sidegraph-store 2.0.0` plus a `requires-sidegraph` line and a `shards N` line; 0.14–0.16 refuse it, and the [0.17 migration guide](../guides/migrating-to-0.17.md) covers the switch. | `sidegraph-verify` lints every canonical file against the write-path invariants; `--against <ref>` classifies every changed file against the store's own transition rules |
|
|
29
|
-
| **CLI commands, flags, exit codes** | 22 entry points,
|
|
28
|
+
| **The store on disk** — `.sidegraph/` layout (one JSON file per record, and from 0.17 optionally packed `shards/`), the `format` marker, `schema_version` | The current version is **0.6.0** (a format-2 store's index is stamped `0.7.0+format2`). `0.2.0`/`0.3.0` stores migrate automatically on first open (original kept as `*.migrated-backup`, never deleted). `0.4.0`/`0.5.0` reload in place. A future bump does one of those two or, as format 2 did, an explicit migration command (`sidegraph-migrate`) while the old format stays served — it never orphans a store. A store can require a minimum Sidegraph version (`sidegraph-require`): its marker becomes `sidegraph-store 1.0.0` plus `requires-sidegraph >= X.Y.Z`, and older versions refuse it. A packed store's marker is `sidegraph-store 2.0.0` plus a `requires-sidegraph` line and a `shards N` line; 0.14–0.16 refuse it, and the [0.17 migration guide](../guides/migrating-to-0.17.md) covers the switch. | `sidegraph-verify` lints every canonical file against the write-path invariants; a drift-check capsule may carry an optional `declared_sections` field inside `schema_version` 1, which readers that do not know it ignore; `--against <ref>` classifies every changed file against the store's own transition rules |
|
|
29
|
+
| **CLI commands, flags, exit codes** | 22 entry points, 100 flags. A flag is not removed without a deprecation window; documented exit codes keep their meaning | every parser option must appear in its `cli.md` section (`tests/test_docs_claims.py`) |
|
|
30
30
|
| **Environment variables** | The 16 in [`configuration.md`](configuration.md), and the store-path precedence between them. `SIDEGRAPH_DB` stays honoured as the documented deprecated form. `SIDEGRAPH_RATIFY_POLICY`'s name and its `manual` default are committed; its auto values and their gates are Provisional (below). | bidirectional test: the documented set must equal what `src/` actually reads |
|
|
31
31
|
| **Hook process contract** | Read one JSON payload on stdin, write one JSON object on stdout, never block the host, never crash it — any internal failure exits normally, printing `{}`, or for SessionStart a store that cannot be opened prints a `systemMessage` naming the cause. Hosts call the hooks without arguments: `-h`/`--help` prints usage on stdout and exits `0`, and any other argument is a usage error on stderr that exits `2` (keep the `\|\| printf` guard on hand-written wiring) | the hook tests, and a live host run per release |
|
|
32
32
|
|
|
@@ -39,7 +39,7 @@ changes it, we follow the host; that is the point of keeping the host seam thin.
|
|
|
39
39
|
|---|---|
|
|
40
40
|
| **The MCP tool set and return shapes** (25 tools) | Fields and tools may still be added or deprecated; `ratify_decisions` is already a deprecated alias. Pin a version if a client depends on an exact shape. |
|
|
41
41
|
| **Flow profiles** — the seven names and their ingest globs, ADR output settings and templates | `spec-kit`'s glob reads `specs/*/plan.md`, while that flow writes its rejected alternatives to `research.md`, which nothing reads. Fixing that changes a glob. |
|
|
42
|
-
| **`doctor` finding codes** | Advisory lint; the set grows as checks are added. Guarded against the docs, not frozen. |
|
|
42
|
+
| **`doctor` finding codes** and the `drift_groups` key of `sidegraph-doctor --json` | Advisory lint; the set grows as checks are added. Guarded against the docs, not frozen. The `drift_groups` shape (and the grouped default text) may still change. |
|
|
43
43
|
| **Integrity check ids and severities** — `store-unreadable`, `graph-stale`, `orphaned-records` and the rest of the [troubleshooting](../guides/troubleshooting.md) table, as they appear in `sidegraph-stats --json`'s `health[].check` and in the `integrity_notice:` meta rows | Beside the doctor codes, for the same reason: the set grows as checks are added (the host-wiring checks `version-skew`, `path-skew` and `plugin-off-in-subdirectories` came before `refresh-helper-outdated` and `engine-version`), and a severity or a threshold (such as the age that makes orphaned records degraded) may move once it is measured. |
|
|
44
44
|
| **Auto-ratification policy** — `SIDEGRAPH_RATIFY_POLICY`'s `auto-low-risk`/`auto-all` values and eligibility gates, the `, auto-ratified N` CLI summary segment (and the dry run's `, would auto-ratify M` and `[auto]` marker), and `sidegraph-doctor`'s `auto share`/`auto supersede rate` lines | Eligibility and reporting may tighten. `manual` remains the committed default. |
|
|
45
45
|
|
|
@@ -108,7 +108,7 @@ an ordinary, human-readable git conflict in one small JSON file — not a corrup
|
|
|
108
108
|
| `Fact` — full row, incl. `status`/`valid_to` (non-derivable knowledge; falsification is supersession, same as a `Decision`) | — |
|
|
109
109
|
| `Domain` — everything except `communities` | `AnchorBinding.status` (`live`/`degraded`/`orphaned`) |
|
|
110
110
|
| `Entity` — `entity_id`/`canonical_name`/`kind`/`descriptor`, for every entity EXCEPT a `community:*` abstract entity (index-only — see below) | `Domain.communities` |
|
|
111
|
-
| `AnchorBinding` set per decision or fact — `entity_id`/`tier`/`relation`/`weight`, no `status`, EXCLUDING any binding whose entity is a `community:*` abstract entity | `toc_cache` (the `SessionStart` table-of-contents render) |
|
|
111
|
+
| `AnchorBinding` set per decision or fact — `entity_id`/`tier`/`relation`/`weight`, no `status`, EXCLUDING any binding whose entity is a `community:*` abstract entity | `toc_cache` (the `SessionStart` table-of-contents render), `code_drift_cache` (the drifted record ids per capture commit, with the `first_seen_since`, `first_seen` and `first_seen_absent` stamps and the `first_seen_checked` marks behind the SessionStart recency clause) |
|
|
112
112
|
| `Initiative` — full row | the per-session capture ledger (`capture_sessions`, dedup markers) |
|
|
113
113
|
| `archive/*.jsonl` segments (once compaction has run) | `last_synced_graph_version` (the graph version plus the resolver revision, `<graph version>:r<N>`; raising the revision reruns the first sync after an upgrade), `pending_uncommitted_moves` (the entities a sync left as `moved_uncommitted`, with the git `HEAD` it saw, so the next sync after `HEAD` moves re-verifies them), `pending_tier1_reconcile` (the `(record, vacated community)` pairs whose Tier-1 reconcile failed, as JSON; every sync retries them first; a pair is cleared once its reconcile completes, and kept, silently, while a live or degraded Tier-2 anchor of the record has no recorded community), `schema_version`, the canonical-digest freshness stamp, `skipped_canonical_files` (the files the last reload left out; see [Digest integrity](#digest-integrity)) |
|
|
114
114
|
| `domain-snapshot.json` (once `sidegraph-domains snapshot` has run) | `domain_members` (each accepted domain's effective membership: node id, file, community), with `domain_membership_stamp`, `domain_membership_failed`, `domain_membership_populated` and `domain_snapshot_signature` in `meta` |
|
|
@@ -1010,7 +1010,26 @@ revision, agent provenance, redacted rationale, exact `required_files`, inspecte
|
|
|
1010
1010
|
`checked_files` (path, Git blob id and regular-file mode), and a SHA-256 `subject_digest`.
|
|
1011
1011
|
No source text, engine mapping or binding status is stored. The versioned digest enumerates
|
|
1012
1012
|
immutable Decision/Provenance fields and durable leaf descriptors (`name`, `file_path`);
|
|
1013
|
-
ratification/lifecycle fields and volatile mappings are excluded.
|
|
1013
|
+
ratification/lifecycle fields and volatile mappings are excluded. Locators and section
|
|
1014
|
+
digests are hashes.
|
|
1015
|
+
|
|
1016
|
+
A capsule may also carry `declared_sections` (inside `schema_version` 1; plain capsules
|
|
1017
|
+
write `"declared_sections": []`). Each entry names one checked markdown file and the sections
|
|
1018
|
+
the checker read: `{path, scheme, refs_hash, sections: [{heading_hash, role, text_hash}]}`.
|
|
1019
|
+
Scheme `md1` is the block structure markdown-it-py reports in CommonMark mode (`>=4,<5`,
|
|
1020
|
+
inline pass off): `heading_hash` is a chained SHA-256 of the heading chain, `text_hash` the
|
|
1021
|
+
SHA-256 of the section's lines (CRLF and CR read as LF, nothing else normalised) and
|
|
1022
|
+
`refs_hash` the SHA-256 of the file's link reference definitions. Roles are `declared` and
|
|
1023
|
+
`watch`. No heading text is stored. A file with an entry is unchanged when its blob and mode
|
|
1024
|
+
match, or when its mode matches and every stored heading still resolves to exactly one
|
|
1025
|
+
heading with an equal `text_hash` and the `refs_hash` is equal. Everything else re-arms, with
|
|
1026
|
+
`checked files changed` for a mode or absence change, an unknown scheme or an unknown role;
|
|
1027
|
+
`section scope unavailable; whole file compared` when the file cannot be bounded (over 2 MiB
|
|
1028
|
+
or 20,000 lines, over 5,000 headings or 200,000 parser tokens, not UTF-8, a heading inside a
|
|
1029
|
+
list item or quote, nesting too deep, a read failure or an exhausted scan budget);
|
|
1030
|
+
`declared section not found`; `declared section changed`;
|
|
1031
|
+
`referenced link definition changed`; and `also-watched section changed`. A release that does not know the field ignores it, compares whole blobs and warns
|
|
1032
|
+
more, never less; an unknown future scheme or role is accepted and compared by whole blob.
|
|
1014
1033
|
|
|
1015
1034
|
Select the highest generated check id for each decision before validation. This is a
|
|
1016
1035
|
simple deterministic cross-branch ordering rule, not causal ordering or truth authority.
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "sidegraph",
|
|
3
3
|
"displayName": "Sidegraph",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.20.0",
|
|
5
5
|
"description": "Durable decision/lessons memory over your code graph — ADRs, gotchas, and constraints that survive refactors, retrieved mistakes-first.",
|
|
6
6
|
"author": { "name": "SantyagoSeaman", "url": "https://github.com/SantyagoSeaman" },
|
|
7
7
|
"homepage": "https://github.com/SantyagoSeaman/sidegraph",
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "sidegraph",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.20.0",
|
|
4
4
|
"description": "Durable decision/lessons memory over your code graph — ADRs, gotchas, and constraints that survive refactors, retrieved mistakes-first.",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"skills": "./skills/",
|
|
@@ -81,6 +81,8 @@ anchors resurface as noise in someone else's task context later.
|
|
|
81
81
|
{"name": "ADR-001.md", "file_path": "adr/ADR-001.md"}]`. In the first store maintenance
|
|
82
82
|
pass (2026-08-09), this one rule would have kept 7 of 10 fully-invisible records
|
|
83
83
|
reachable.
|
|
84
|
+
- For a long document, section scope is declared when the record is checked
|
|
85
|
+
(`record_drift_check` with `sections`), not when it is anchored.
|
|
84
86
|
- **Two name shapes need care.** A bare module-level constant
|
|
85
87
|
(`MEMORY_GUARD_LINE`) never resolves — the engine indexes functions/classes/files, not
|
|
86
88
|
constants; anchor the containing file or function and name the constant in prose. A
|
|
@@ -46,7 +46,8 @@ north star this razor guards.
|
|
|
46
46
|
existing `Decision` (any status) or the write is rejected before anything is committed —
|
|
47
47
|
never guessed, never left dangling.
|
|
48
48
|
- **Always pair the precise anchor with its containing file** — code symbol or doc heading
|
|
49
|
-
alike: a rename/move orphans one anchor, the file anchor keeps the fact retrievable.
|
|
49
|
+
alike: a rename/move orphans one anchor, the file anchor keeps the fact retrievable. For a
|
|
50
|
+
long document, section scope is declared when the record is checked, not when it is anchored.
|
|
50
51
|
Never anchor to a bare module-level constant (the engine indexes functions/classes/
|
|
51
52
|
files, not constants — anchor the file and name the constant in the statement), and
|
|
52
53
|
keep `name` bare (`store.py`, `_touch_digest`) — `file_path`, not the name, carries
|
|
@@ -25,16 +25,46 @@ the question is whether what the record says survived what the code became.
|
|
|
25
25
|
The CLI runs through uvx at the session's version, never the copy on `PATH` ([why](../../../../docs/reference/cli.md#running-the-clis-beside-the-plugin)).
|
|
26
26
|
|
|
27
27
|
```bash
|
|
28
|
-
uvx --from git+https://github.com/SantyagoSeaman/sidegraph.git@main sidegraph-doctor --json # findings[]
|
|
28
|
+
uvx --from git+https://github.com/SantyagoSeaman/sidegraph.git@main sidegraph-doctor --json # drift_groups.groups[] and findings[] with "code": "code-drift"
|
|
29
29
|
```
|
|
30
30
|
|
|
31
|
+
Read `drift_groups.groups` first: one group per drifted file, each listing the records whose
|
|
32
|
+
anchored files changed. Build one record list keyed by `record_id` across all groups. A record
|
|
33
|
+
anchored in several files appears in each of their groups with the same `files`; judge it
|
|
34
|
+
**once**, after every one of its `files` has been read. When the `drift_groups` key is absent
|
|
35
|
+
(an older doctor, `--flat`, or no per-record drift) fall back to the `findings[]` entries
|
|
36
|
+
with `"code": "code-drift"` and triage per record as before.
|
|
37
|
+
|
|
38
|
+
Per record entry:
|
|
39
|
+
|
|
40
|
+
- `diff.command` is `git diff <old blob> <new blob>`: read it once per file, not once per
|
|
41
|
+
record. A null `command` means read the file at HEAD and nothing more. `diff.unavailable`
|
|
42
|
+
says why no diff exists (for example the baseline object is not in this clone).
|
|
43
|
+
- `diff.change` says what kind of change it is. `mode` means the executable bit moved and the
|
|
44
|
+
content is identical. `type` means the entry kind changed (file, symlink, submodule or
|
|
45
|
+
directory) and the content may well differ: read the file at HEAD, do not assume nothing
|
|
46
|
+
changed. `submodule` means a submodule pointer moved (`<old8>→<new8>` in the text): read the
|
|
47
|
+
submodule's own log, there is no `git diff` here. `content` is a real blob diff; if
|
|
48
|
+
`old_mode` and `new_mode` differ it also changed the mode.
|
|
49
|
+
- `basis: "scope"` reads "scope changed; the file may also have changed". If a `command` is
|
|
50
|
+
present, read that diff; otherwise judge the record against the current anchored code.
|
|
51
|
+
- `hint: "region-unchanged"` (text: `anchored region unchanged; sibling sections of the file
|
|
52
|
+
may still matter`) shortens the reading, never the judging: still read the current
|
|
53
|
+
implementation and any sibling the claim leans on.
|
|
54
|
+
|
|
31
55
|
For a per-decision `code-drift` finding, use `record_id` and `record_type` ("decision")
|
|
32
56
|
to identify the subject. `path` is its physical source: several records may share one shard.
|
|
33
57
|
Never infer identity from the shard, capture commit or human-readable `detail`. Global notes
|
|
34
|
-
(commit stamping unavailable, Git unavailable, check skipped) have null record fields
|
|
35
|
-
are not records to triage. `detail` names changed files or
|
|
58
|
+
(commit stamping unavailable, Git unavailable, check skipped) have null record fields and
|
|
59
|
+
sit in `drift_groups.notes`; they are not records to triage. `detail` names changed files or
|
|
60
|
+
why a prior check no longer applies.
|
|
36
61
|
Original `provenance.commit` stays history. Doctor is a pure read.
|
|
37
62
|
|
|
63
|
+
Each `code-drift` entry in `findings[]` has `first_seen`: the time Sidegraph first saw the
|
|
64
|
+
record drifted, or `null` when its age is unknown. Group records carry no `first_seen`: look
|
|
65
|
+
each one up in `findings[]` by `record_id`. Triage the records whose `first_seen` is within
|
|
66
|
+
the last 7 days first, newest first, then the `null` ones in doctor order.
|
|
67
|
+
|
|
38
68
|
The SessionStart count and `[drifted]` tags in detailed formatted `get_task_context`,
|
|
39
69
|
`query_decisions` and `drill_down` output use the lazily refreshed drift cache. Budgets can
|
|
40
70
|
omit records, and compact related-record lines do not all show the marker. Raw
|
|
@@ -43,7 +73,9 @@ for the explicit current list.
|
|
|
43
73
|
|
|
44
74
|
Triage in batches — a 35-record queue does not need 35 interrupts. Group verdicts and
|
|
45
75
|
**put every question to the human into one message** (same discipline as
|
|
46
|
-
`sidegraph:heal-anchors`).
|
|
76
|
+
`sidegraph:heal-anchors`). Make exactly one `record_drift_check` or one supersession per
|
|
77
|
+
record, each with its own rationale and `files` scope: two records never share a rationale or
|
|
78
|
+
a call, even when one file change re-armed both.
|
|
47
79
|
|
|
48
80
|
## Per record: read both sides, then route
|
|
49
81
|
|
|
@@ -79,9 +111,30 @@ Triage in batches — a 35-record queue does not need 35 interrupts. Group verdi
|
|
|
79
111
|
|
|
80
112
|
This immutable agent assertion preserves the decision and its capture provenance.
|
|
81
113
|
It does not certify semantic truth, ratify a proposal, or permanently mute warnings.
|
|
82
|
-
Changed checked files or required scope re-arm review
|
|
83
|
-
|
|
114
|
+
Changed checked files or required scope re-arm review (for a markdown file checked with
|
|
115
|
+
declared sections, only a change to a declared or also-watched section or to the file's
|
|
116
|
+
link definitions); unchanged file bytes after unrelated commits remain covered. A known wrong claim belongs in route (b).
|
|
84
117
|
Never create a content-free successor just to refresh a stamp.
|
|
118
|
+
**Scoping a check on a document.** Pass `sections` to `record_drift_check` when:
|
|
119
|
+
|
|
120
|
+
- the file is markdown, the claim rests on identifiable sections, and you read those
|
|
121
|
+
sections in this session at the recorded HEAD. When unsure, make a plain whole-file check.
|
|
122
|
+
- Declare the narrowest sections that carry the claim (`[["55.2 Rules"]]`, not the
|
|
123
|
+
chapter). The result echoes each section's `first_line` and `lines` (and the file's
|
|
124
|
+
`total_lines`): a section spanning most of the file gains nothing, and a `first_line`
|
|
125
|
+
that is not where the heading sits in your viewer means the parser disagrees with your
|
|
126
|
+
renderer, so make a whole-file check.
|
|
127
|
+
- Add `also_watch` when the claim depends on content elsewhere in the same file, such as
|
|
128
|
+
a rule restated in another chapter, a table that must stay consistent or a "the only X"
|
|
129
|
+
statement. Read the watched section too.
|
|
130
|
+
- Never declare a section you did not read: the declaration is an attributed assertion,
|
|
131
|
+
and a wrong narrow scope hides a real change.
|
|
132
|
+
- Do not declare sections that transclude other files (include directives, snippets).
|
|
133
|
+
- Refusals are normal. `section_file_unsupported` means a heading sits inside a list
|
|
134
|
+
item or quote, or a footnote reference is in a declared span; a file over 20,000 lines
|
|
135
|
+
is `section_file_too_large`. Make a plain whole-file check.
|
|
136
|
+
- Not for code files. Declared sections are for markdown only.
|
|
137
|
+
- Report the declared sections per file in your summary line.
|
|
85
138
|
- **(b) Content now wrong or too broad.** The code change genuinely invalidated or
|
|
86
139
|
narrowed the record. Propose the successor — never write it directly on your own
|
|
87
140
|
initiative:
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "sidegraph"
|
|
3
|
-
version = "0.
|
|
3
|
+
version = "0.20.0"
|
|
4
4
|
description = "Own the memory, rent the graph — a durable decision/lessons layer as a sidecar over a code-graph engine."
|
|
5
5
|
readme = "README.md"
|
|
6
6
|
requires-python = ">=3.13"
|
|
@@ -43,6 +43,9 @@ dependencies = [
|
|
|
43
43
|
# GHSA-84m7-p3x7-pcfv / CVE-2026-59951: MCP 1.30.0 fixes stateful StreamableHTTP.
|
|
44
44
|
"anyio>=4",
|
|
45
45
|
"mcp>=1.30,<2",
|
|
46
|
+
# Imported directly by drift_groups.py (heading spans for the drift hint)
|
|
47
|
+
# and lazily by md_sections (declared-section drift scope).
|
|
48
|
+
"markdown-it-py>=4,<5",
|
|
46
49
|
]
|
|
47
50
|
|
|
48
51
|
[project.urls]
|