sidegraph 0.1.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.1.0/.agents/plugins/marketplace.json +14 -0
- sidegraph-0.1.0/.claude-plugin/marketplace.json +13 -0
- sidegraph-0.1.0/.github/CODEOWNERS +2 -0
- sidegraph-0.1.0/.github/ISSUE_TEMPLATE/bug_report.yml +37 -0
- sidegraph-0.1.0/.github/ISSUE_TEMPLATE/config.yml +5 -0
- sidegraph-0.1.0/.github/ISSUE_TEMPLATE/feature_request.yml +26 -0
- sidegraph-0.1.0/.github/PULL_REQUEST_TEMPLATE.md +20 -0
- sidegraph-0.1.0/.github/workflows/ci.yml +144 -0
- sidegraph-0.1.0/.github/workflows/publish.yml +84 -0
- sidegraph-0.1.0/.github/workflows/scorecard.yml +46 -0
- sidegraph-0.1.0/.gitignore +64 -0
- sidegraph-0.1.0/.gitleaks.toml +32 -0
- sidegraph-0.1.0/.pre-commit-config.yaml +162 -0
- sidegraph-0.1.0/.python-version +1 -0
- sidegraph-0.1.0/AGENTS.md +73 -0
- sidegraph-0.1.0/CHANGELOG.md +669 -0
- sidegraph-0.1.0/CLAUDE.md +111 -0
- sidegraph-0.1.0/CODE_OF_CONDUCT.md +89 -0
- sidegraph-0.1.0/CONTRIBUTING.md +54 -0
- sidegraph-0.1.0/LICENSE +201 -0
- sidegraph-0.1.0/PKG-INFO +392 -0
- sidegraph-0.1.0/README.md +364 -0
- sidegraph-0.1.0/SECURITY.md +39 -0
- sidegraph-0.1.0/docs/README.md +78 -0
- sidegraph-0.1.0/docs/concepts/anchoring.md +158 -0
- sidegraph-0.1.0/docs/concepts/data-model.md +273 -0
- sidegraph-0.1.0/docs/concepts/decision-memory.md +79 -0
- sidegraph-0.1.0/docs/concepts/mind-model.md +208 -0
- sidegraph-0.1.0/docs/concepts/retrieval.md +317 -0
- sidegraph-0.1.0/docs/getting-started/bootstrap.md +184 -0
- sidegraph-0.1.0/docs/getting-started/claude-code-setup.md +164 -0
- sidegraph-0.1.0/docs/getting-started/codex-setup.md +134 -0
- sidegraph-0.1.0/docs/getting-started/installation.md +167 -0
- sidegraph-0.1.0/docs/getting-started/quickstart.md +102 -0
- sidegraph-0.1.0/docs/guides/capturing-decisions.md +371 -0
- sidegraph-0.1.0/docs/guides/ci-cd-maintenance.md +452 -0
- sidegraph-0.1.0/docs/guides/naming-your-domains.md +322 -0
- sidegraph-0.1.0/docs/guides/retrieval-in-sessions.md +201 -0
- sidegraph-0.1.0/docs/guides/semantic-docs.md +242 -0
- sidegraph-0.1.0/docs/guides/surviving-refactors.md +181 -0
- sidegraph-0.1.0/docs/guides/team-workflow.md +186 -0
- sidegraph-0.1.0/docs/guides/verifying-your-setup.md +430 -0
- sidegraph-0.1.0/docs/integrations/claude-code.md +234 -0
- sidegraph-0.1.0/docs/integrations/codex.md +155 -0
- sidegraph-0.1.0/docs/integrations/graphify.md +205 -0
- sidegraph-0.1.0/docs/llms.txt +63 -0
- sidegraph-0.1.0/docs/pilot-kit/README.md +82 -0
- sidegraph-0.1.0/docs/pilot-kit/corpus_fit.py +290 -0
- sidegraph-0.1.0/docs/pilot-kit/judge-prompt.md +41 -0
- sidegraph-0.1.0/docs/pilot-kit/questions-prompt.md +33 -0
- sidegraph-0.1.0/docs/pilot-kit/rubric-template.md +28 -0
- sidegraph-0.1.0/docs/reference/cli.md +1138 -0
- sidegraph-0.1.0/docs/reference/configuration.md +186 -0
- sidegraph-0.1.0/docs/reference/git-bindings.md +149 -0
- sidegraph-0.1.0/docs/reference/hooks.md +271 -0
- sidegraph-0.1.0/docs/reference/mcp-tools.md +990 -0
- sidegraph-0.1.0/docs/reference/operations.md +76 -0
- sidegraph-0.1.0/docs/reference/releasing.md +128 -0
- sidegraph-0.1.0/docs/reference/stability.md +87 -0
- sidegraph-0.1.0/docs/reference/store-format.md +548 -0
- sidegraph-0.1.0/docs/whitepaper/index.md +909 -0
- sidegraph-0.1.0/plugin/sidegraph/.claude-plugin/plugin.json +11 -0
- sidegraph-0.1.0/plugin/sidegraph/.codex-plugin/plugin.json +12 -0
- sidegraph-0.1.0/plugin/sidegraph/.mcp.json +16 -0
- sidegraph-0.1.0/plugin/sidegraph/codex/hooks.json +24 -0
- sidegraph-0.1.0/plugin/sidegraph/codex/mcp.json +9 -0
- sidegraph-0.1.0/plugin/sidegraph/hooks/hooks.json +35 -0
- sidegraph-0.1.0/plugin/sidegraph/skills/check-plan/SKILL.md +71 -0
- sidegraph-0.1.0/plugin/sidegraph/skills/check-plan/agents/openai.yaml +6 -0
- sidegraph-0.1.0/plugin/sidegraph/skills/explain-why/SKILL.md +88 -0
- sidegraph-0.1.0/plugin/sidegraph/skills/explain-why/agents/openai.yaml +6 -0
- sidegraph-0.1.0/plugin/sidegraph/skills/heal-anchors/SKILL.md +248 -0
- sidegraph-0.1.0/plugin/sidegraph/skills/heal-anchors/agents/openai.yaml +6 -0
- sidegraph-0.1.0/plugin/sidegraph/skills/import-adrs/SKILL.md +103 -0
- sidegraph-0.1.0/plugin/sidegraph/skills/import-adrs/agents/openai.yaml +6 -0
- sidegraph-0.1.0/plugin/sidegraph/skills/manage-domains/SKILL.md +122 -0
- sidegraph-0.1.0/plugin/sidegraph/skills/manage-domains/agents/openai.yaml +6 -0
- sidegraph-0.1.0/plugin/sidegraph/skills/name-domains/SKILL.md +139 -0
- sidegraph-0.1.0/plugin/sidegraph/skills/name-domains/agents/openai.yaml +6 -0
- sidegraph-0.1.0/plugin/sidegraph/skills/ratify-decisions/SKILL.md +146 -0
- sidegraph-0.1.0/plugin/sidegraph/skills/ratify-decisions/agents/openai.yaml +6 -0
- sidegraph-0.1.0/plugin/sidegraph/skills/record-decision/SKILL.md +203 -0
- sidegraph-0.1.0/plugin/sidegraph/skills/record-decision/agents/openai.yaml +6 -0
- sidegraph-0.1.0/plugin/sidegraph/skills/record-fact/SKILL.md +147 -0
- sidegraph-0.1.0/plugin/sidegraph/skills/record-fact/agents/openai.yaml +6 -0
- sidegraph-0.1.0/plugin/sidegraph/skills/setup/SKILL.md +93 -0
- sidegraph-0.1.0/plugin/sidegraph/skills/setup/agents/openai.yaml +6 -0
- sidegraph-0.1.0/plugin/sidegraph/skills/triage-drift/SKILL.md +104 -0
- sidegraph-0.1.0/plugin/sidegraph/skills/triage-drift/agents/openai.yaml +6 -0
- sidegraph-0.1.0/pyproject.toml +111 -0
- sidegraph-0.1.0/src/sidegraph/__init__.py +37 -0
- sidegraph-0.1.0/src/sidegraph/anchoring.py +246 -0
- sidegraph-0.1.0/src/sidegraph/bootstrap/__init__.py +49 -0
- sidegraph-0.1.0/src/sidegraph/bootstrap/apply.py +603 -0
- sidegraph-0.1.0/src/sidegraph/bootstrap/catalog.py +92 -0
- sidegraph-0.1.0/src/sidegraph/bootstrap/cli.py +827 -0
- sidegraph-0.1.0/src/sidegraph/bootstrap/integrations.py +184 -0
- sidegraph-0.1.0/src/sidegraph/bootstrap/model.py +277 -0
- sidegraph-0.1.0/src/sidegraph/bootstrap/planner.py +400 -0
- sidegraph-0.1.0/src/sidegraph/bootstrap/proof.py +103 -0
- sidegraph-0.1.0/src/sidegraph/bootstrap/review.py +331 -0
- sidegraph-0.1.0/src/sidegraph/bootstrap/scan.py +289 -0
- sidegraph-0.1.0/src/sidegraph/capture.py +1794 -0
- sidegraph-0.1.0/src/sidegraph/cli.py +1902 -0
- sidegraph-0.1.0/src/sidegraph/config.py +148 -0
- sidegraph-0.1.0/src/sidegraph/doc_import.py +2099 -0
- sidegraph-0.1.0/src/sidegraph/doctor.py +1429 -0
- sidegraph-0.1.0/src/sidegraph/domains.py +902 -0
- sidegraph-0.1.0/src/sidegraph/engine/__init__.py +7 -0
- sidegraph-0.1.0/src/sidegraph/engine/reader.py +353 -0
- sidegraph-0.1.0/src/sidegraph/gitio.py +572 -0
- sidegraph-0.1.0/src/sidegraph/host/__init__.py +7 -0
- sidegraph-0.1.0/src/sidegraph/host/hooks.py +770 -0
- sidegraph-0.1.0/src/sidegraph/importer.py +239 -0
- sidegraph-0.1.0/src/sidegraph/okf.py +471 -0
- sidegraph-0.1.0/src/sidegraph/profiles.py +459 -0
- sidegraph-0.1.0/src/sidegraph/retrieval.py +1657 -0
- sidegraph-0.1.0/src/sidegraph/schema.py +386 -0
- sidegraph-0.1.0/src/sidegraph/server.py +2608 -0
- sidegraph-0.1.0/src/sidegraph/store.py +3363 -0
- sidegraph-0.1.0/src/sidegraph/sync.py +885 -0
- sidegraph-0.1.0/src/sidegraph/verify.py +1040 -0
- sidegraph-0.1.0/src/sidegraph/viz/__init__.py +4 -0
- sidegraph-0.1.0/src/sidegraph/viz/assets/vis-network.min.js +33 -0
- sidegraph-0.1.0/src/sidegraph/viz/model.py +248 -0
- sidegraph-0.1.0/src/sidegraph/viz/render.py +110 -0
- sidegraph-0.1.0/src/sidegraph/viz/template.html +131 -0
- sidegraph-0.1.0/tests/__init__.py +0 -0
- sidegraph-0.1.0/tests/fixtures/auto_policy/parity_goldens.json +10 -0
- sidegraph-0.1.0/tests/fixtures/bitfinex_slice.json +28 -0
- sidegraph-0.1.0/tests/fixtures/bootstrap/flows/bmad/_bmad-output/planning-artifacts/architecture/cache/ARCHITECTURE-SPINE.md +12 -0
- sidegraph-0.1.0/tests/fixtures/bootstrap/flows/generic-adr/docs/adr/001-retry.md +10 -0
- sidegraph-0.1.0/tests/fixtures/bootstrap/flows/genkovich-sdd/docs/features/cache/adr/001.md +10 -0
- sidegraph-0.1.0/tests/fixtures/bootstrap/flows/spec-kit/specs/cache/plan.md +10 -0
- sidegraph-0.1.0/tests/fixtures/bootstrap/flows/superpowers/docs/superpowers/specs/2026-07-01-cache-design.md +10 -0
- sidegraph-0.1.0/tests/fixtures/bootstrap/graph.json +10 -0
- sidegraph-0.1.0/tests/fixtures/bootstrap/hosts/claude/.claude/settings.json +7 -0
- sidegraph-0.1.0/tests/fixtures/bootstrap/hosts/claude/.mcp.json +5 -0
- sidegraph-0.1.0/tests/fixtures/bootstrap/hosts/codex/.codex/config.toml +2 -0
- sidegraph-0.1.0/tests/fixtures/bootstrap/hosts/codex/.codex/hooks/hooks.json +6 -0
- sidegraph-0.1.0/tests/fixtures/bootstrap/scan/docs/adr/001-safe.md +5 -0
- sidegraph-0.1.0/tests/fixtures/corpus/PUBLIC_CORPORA.txt +15 -0
- sidegraph-0.1.0/tests/fixtures/corpus/openspec/_provenance.json +11 -0
- sidegraph-0.1.0/tests/fixtures/corpus/openspec/graph.json +13352 -0
- sidegraph-0.1.0/tests/fixtures/corpus/self-corpus/_provenance.json +10 -0
- sidegraph-0.1.0/tests/fixtures/corpus/self-corpus/expected/retrieval-engine-reader.md +46 -0
- sidegraph-0.1.0/tests/fixtures/corpus/self-corpus/graph.json +1418 -0
- sidegraph-0.1.0/tests/fixtures/flows/adr/0001-use-sessions.md +17 -0
- sidegraph-0.1.0/tests/fixtures/flows/bmad/ARCHITECTURE-SPINE.md +60 -0
- sidegraph-0.1.0/tests/fixtures/flows/bmad/tree/_bmad-output/planning-artifacts/architecture/architecture-payments-2026-07-30/.memlog.md +10 -0
- sidegraph-0.1.0/tests/fixtures/flows/bmad/tree/_bmad-output/planning-artifacts/architecture/architecture-payments-2026-07-30/ARCHITECTURE-SPINE.md +60 -0
- sidegraph-0.1.0/tests/fixtures/flows/bmad/tree/_bmad-output/planning-artifacts/prds/prd-payments-2026-07-30/prd.md +24 -0
- sidegraph-0.1.0/tests/fixtures/flows/genkovich/0001-queue-backpressure.md +43 -0
- sidegraph-0.1.0/tests/fixtures/flows/genkovich/sad.md +29 -0
- sidegraph-0.1.0/tests/fixtures/flows/genkovich/tree/docs/features/payments/adr/0001-queue-backpressure.md +43 -0
- sidegraph-0.1.0/tests/fixtures/flows/genkovich/tree/docs/features/payments/sad.md +29 -0
- sidegraph-0.1.0/tests/fixtures/flows/genkovich/tree/docs/features/payments/spec.md +20 -0
- sidegraph-0.1.0/tests/fixtures/flows/openspec/design-empty.md +9 -0
- sidegraph-0.1.0/tests/fixtures/flows/openspec/design-h3-split.md +15 -0
- sidegraph-0.1.0/tests/fixtures/flows/openspec/design-with-summary.md +17 -0
- sidegraph-0.1.0/tests/fixtures/flows/openspec/design.md +25 -0
- sidegraph-0.1.0/tests/fixtures/flows/openspec/proposal-alternatives.md +12 -0
- sidegraph-0.1.0/tests/fixtures/flows/openspec/proposal.md +13 -0
- sidegraph-0.1.0/tests/fixtures/flows/openspec/tree/openspec/changes/add-thing/design.md +13 -0
- sidegraph-0.1.0/tests/fixtures/flows/openspec/tree/openspec/changes/add-thing/proposal.md +11 -0
- sidegraph-0.1.0/tests/fixtures/flows/openspec/tree/openspec/changes/add-thing/specs/cap/spec.md +10 -0
- sidegraph-0.1.0/tests/fixtures/flows/openspec/tree/openspec/changes/add-thing/tasks.md +4 -0
- sidegraph-0.1.0/tests/fixtures/flows/openspec/tree/openspec/changes/archive/2026-01-01-add-thing/design.md +13 -0
- sidegraph-0.1.0/tests/fixtures/flows/openspec/tree/openspec/changes/archive/2026-01-01-add-thing/proposal.md +11 -0
- sidegraph-0.1.0/tests/fixtures/flows/openspec/tree/openspec/config.yaml +1 -0
- sidegraph-0.1.0/tests/fixtures/flows/openspec/tree/openspec/specs/cap/spec.md +10 -0
- sidegraph-0.1.0/tests/fixtures/flows/spec-kit/plan.md +27 -0
- sidegraph-0.1.0/tests/fixtures/flows/spec-kit/tree/specs/003-payment-retries/plan.md +27 -0
- sidegraph-0.1.0/tests/fixtures/flows/spec-kit/tree/specs/003-payment-retries/spec.md +24 -0
- sidegraph-0.1.0/tests/fixtures/flows/superpowers/2026-07-01-example-design.md +21 -0
- sidegraph-0.1.0/tests/fixtures/flows/superpowers/2026-07-01-thin-design.md +12 -0
- sidegraph-0.1.0/tests/fixtures/mini_graph.json +17 -0
- sidegraph-0.1.0/tests/test_anchoring.py +281 -0
- sidegraph-0.1.0/tests/test_anchoring_mapping_refresh.py +104 -0
- sidegraph-0.1.0/tests/test_bootstrap_apply.py +833 -0
- sidegraph-0.1.0/tests/test_bootstrap_catalog.py +156 -0
- sidegraph-0.1.0/tests/test_bootstrap_cli.py +1365 -0
- sidegraph-0.1.0/tests/test_bootstrap_integrations.py +152 -0
- sidegraph-0.1.0/tests/test_bootstrap_model.py +69 -0
- sidegraph-0.1.0/tests/test_bootstrap_planner.py +509 -0
- sidegraph-0.1.0/tests/test_bootstrap_proof.py +454 -0
- sidegraph-0.1.0/tests/test_bootstrap_review.py +739 -0
- sidegraph-0.1.0/tests/test_bootstrap_scan.py +195 -0
- sidegraph-0.1.0/tests/test_capture_auto_accept.py +61 -0
- sidegraph-0.1.0/tests/test_capture_facts.py +329 -0
- sidegraph-0.1.0/tests/test_capture_integration.py +54 -0
- sidegraph-0.1.0/tests/test_capture_neighbors.py +178 -0
- sidegraph-0.1.0/tests/test_capture_propose.py +417 -0
- sidegraph-0.1.0/tests/test_capture_redact.py +58 -0
- sidegraph-0.1.0/tests/test_cli_compact.py +103 -0
- sidegraph-0.1.0/tests/test_cli_doctor.py +252 -0
- sidegraph-0.1.0/tests/test_cli_domains.py +542 -0
- sidegraph-0.1.0/tests/test_cli_import.py +1644 -0
- sidegraph-0.1.0/tests/test_cli_init.py +192 -0
- sidegraph-0.1.0/tests/test_cli_okf.py +230 -0
- sidegraph-0.1.0/tests/test_cli_ratify.py +669 -0
- sidegraph-0.1.0/tests/test_cli_ratify_facts.py +120 -0
- sidegraph-0.1.0/tests/test_cli_sync.py +541 -0
- sidegraph-0.1.0/tests/test_cli_sync_check.py +265 -0
- sidegraph-0.1.0/tests/test_cli_viz.py +113 -0
- sidegraph-0.1.0/tests/test_codex_plugin.py +182 -0
- sidegraph-0.1.0/tests/test_community_baseline.py +53 -0
- sidegraph-0.1.0/tests/test_config.py +231 -0
- sidegraph-0.1.0/tests/test_corpus_expected_renders.py +48 -0
- sidegraph-0.1.0/tests/test_corpus_self_corpus.py +142 -0
- sidegraph-0.1.0/tests/test_coverage_telemetry_e2e.py +161 -0
- sidegraph-0.1.0/tests/test_digest_integrity.py +625 -0
- sidegraph-0.1.0/tests/test_doc_corpus_integration.py +110 -0
- sidegraph-0.1.0/tests/test_doc_import.py +2386 -0
- sidegraph-0.1.0/tests/test_docs_claims.py +780 -0
- sidegraph-0.1.0/tests/test_doctor.py +363 -0
- sidegraph-0.1.0/tests/test_doctor_auto_share.py +550 -0
- sidegraph-0.1.0/tests/test_doctor_code_drift.py +323 -0
- sidegraph-0.1.0/tests/test_doctor_dangling_supports.py +158 -0
- sidegraph-0.1.0/tests/test_doctor_duplicate_entity.py +183 -0
- sidegraph-0.1.0/tests/test_doctor_never_surfaced.py +146 -0
- sidegraph-0.1.0/tests/test_doctor_scan.py +324 -0
- sidegraph-0.1.0/tests/test_doctor_stale_instructions.py +112 -0
- sidegraph-0.1.0/tests/test_doctor_unratified_accept.py +341 -0
- sidegraph-0.1.0/tests/test_domains.py +1666 -0
- sidegraph-0.1.0/tests/test_entity_duplicate_resolution.py +89 -0
- sidegraph-0.1.0/tests/test_entity_get_or_create_race.py +197 -0
- sidegraph-0.1.0/tests/test_fact_reachability_gate.py +152 -0
- sidegraph-0.1.0/tests/test_flow_profile.py +997 -0
- sidegraph-0.1.0/tests/test_git_bindings_blame.py +246 -0
- sidegraph-0.1.0/tests/test_git_bindings_hook.py +436 -0
- sidegraph-0.1.0/tests/test_git_bindings_provenance.py +157 -0
- sidegraph-0.1.0/tests/test_host_drift_nudge.py +186 -0
- sidegraph-0.1.0/tests/test_host_pretool.py +346 -0
- sidegraph-0.1.0/tests/test_host_session_key.py +146 -0
- sidegraph-0.1.0/tests/test_host_session_start.py +485 -0
- sidegraph-0.1.0/tests/test_host_stop.py +709 -0
- sidegraph-0.1.0/tests/test_host_touch_events.py +253 -0
- sidegraph-0.1.0/tests/test_importer.py +530 -0
- sidegraph-0.1.0/tests/test_mind_model_additive_fields.py +105 -0
- sidegraph-0.1.0/tests/test_okf.py +474 -0
- sidegraph-0.1.0/tests/test_openspec_profile.py +463 -0
- sidegraph-0.1.0/tests/test_pathless_descriptor_adoption.py +509 -0
- sidegraph-0.1.0/tests/test_pilot_kit_corpus_fit.py +136 -0
- sidegraph-0.1.0/tests/test_proposal_lifecycle.py +312 -0
- sidegraph-0.1.0/tests/test_ratify_listing_gone_dark.py +61 -0
- sidegraph-0.1.0/tests/test_ratify_policy.py +5561 -0
- sidegraph-0.1.0/tests/test_reader_community_labels.py +82 -0
- sidegraph-0.1.0/tests/test_reader_doc_nodes.py +136 -0
- sidegraph-0.1.0/tests/test_reader_graph.py +82 -0
- sidegraph-0.1.0/tests/test_reader_integration.py +51 -0
- sidegraph-0.1.0/tests/test_reader_nodes_in_file.py +52 -0
- sidegraph-0.1.0/tests/test_reader_perf.py +223 -0
- sidegraph-0.1.0/tests/test_reader_rationale.py +206 -0
- sidegraph-0.1.0/tests/test_reader_read.py +33 -0
- sidegraph-0.1.0/tests/test_reader_resolve.py +134 -0
- sidegraph-0.1.0/tests/test_reader_version.py +74 -0
- sidegraph-0.1.0/tests/test_redaction_seeded.py +76 -0
- sidegraph-0.1.0/tests/test_repoint_integration.py +143 -0
- sidegraph-0.1.0/tests/test_retrieval_context.py +747 -0
- sidegraph-0.1.0/tests/test_retrieval_drift_marker.py +232 -0
- sidegraph-0.1.0/tests/test_retrieval_drilldown.py +666 -0
- sidegraph-0.1.0/tests/test_retrieval_facts.py +222 -0
- sidegraph-0.1.0/tests/test_retrieval_ids.py +213 -0
- sidegraph-0.1.0/tests/test_retrieval_integration.py +120 -0
- sidegraph-0.1.0/tests/test_retrieval_rank.py +763 -0
- sidegraph-0.1.0/tests/test_retrieval_seeds.py +49 -0
- sidegraph-0.1.0/tests/test_retrieval_shown_ids.py +19 -0
- sidegraph-0.1.0/tests/test_retrieval_terminal_evidence.py +98 -0
- sidegraph-0.1.0/tests/test_retrieval_thin_tools.py +175 -0
- sidegraph-0.1.0/tests/test_retrieval_toc.py +333 -0
- sidegraph-0.1.0/tests/test_retrieval_toptier.py +112 -0
- sidegraph-0.1.0/tests/test_retrieval_unratified.py +67 -0
- sidegraph-0.1.0/tests/test_sandbox_hygiene.py +133 -0
- sidegraph-0.1.0/tests/test_schema_descriptor.py +99 -0
- sidegraph-0.1.0/tests/test_schema_domain.py +92 -0
- sidegraph-0.1.0/tests/test_schema_fact.py +41 -0
- sidegraph-0.1.0/tests/test_server_add_anchors.py +184 -0
- sidegraph-0.1.0/tests/test_server_anchoring.py +278 -0
- sidegraph-0.1.0/tests/test_server_capture.py +815 -0
- sidegraph-0.1.0/tests/test_server_coverage_events.py +251 -0
- sidegraph-0.1.0/tests/test_server_domains.py +981 -0
- sidegraph-0.1.0/tests/test_server_drilldown.py +98 -0
- sidegraph-0.1.0/tests/test_server_facts.py +348 -0
- sidegraph-0.1.0/tests/test_server_find_entity.py +138 -0
- sidegraph-0.1.0/tests/test_server_get_store.py +62 -0
- sidegraph-0.1.0/tests/test_server_get_task_context.py +53 -0
- sidegraph-0.1.0/tests/test_server_import.py +48 -0
- sidegraph-0.1.0/tests/test_server_mcp_smoke.py +303 -0
- sidegraph-0.1.0/tests/test_server_ratify_facts.py +100 -0
- sidegraph-0.1.0/tests/test_server_redaction.py +107 -0
- sidegraph-0.1.0/tests/test_server_supersede.py +303 -0
- sidegraph-0.1.0/tests/test_server_sync_anchors.py +104 -0
- sidegraph-0.1.0/tests/test_server_telemetry.py +226 -0
- sidegraph-0.1.0/tests/test_server_thin_tools.py +81 -0
- sidegraph-0.1.0/tests/test_server_verify.py +59 -0
- sidegraph-0.1.0/tests/test_store.py +95 -0
- sidegraph-0.1.0/tests/test_store_atomic_write_tmp_names.py +33 -0
- sidegraph-0.1.0/tests/test_store_canonical_stat.py +262 -0
- sidegraph-0.1.0/tests/test_store_compact.py +599 -0
- sidegraph-0.1.0/tests/test_store_compact_review.py +418 -0
- sidegraph-0.1.0/tests/test_store_concurrent_open.py +99 -0
- sidegraph-0.1.0/tests/test_store_coverage_telemetry.py +105 -0
- sidegraph-0.1.0/tests/test_store_derived_community.py +123 -0
- sidegraph-0.1.0/tests/test_store_domains.py +682 -0
- sidegraph-0.1.0/tests/test_store_entities.py +76 -0
- sidegraph-0.1.0/tests/test_store_fact_cascade.py +102 -0
- sidegraph-0.1.0/tests/test_store_facts.py +128 -0
- sidegraph-0.1.0/tests/test_store_meta.py +144 -0
- sidegraph-0.1.0/tests/test_store_migration.py +423 -0
- sidegraph-0.1.0/tests/test_store_mutation_guard.py +542 -0
- sidegraph-0.1.0/tests/test_store_mutation_immediate.py +135 -0
- sidegraph-0.1.0/tests/test_store_opens_with_merged_duplicate.py +68 -0
- sidegraph-0.1.0/tests/test_store_persistence.py +561 -0
- sidegraph-0.1.0/tests/test_store_ratification.py +293 -0
- sidegraph-0.1.0/tests/test_store_rebuild_atomicity.py +138 -0
- sidegraph-0.1.0/tests/test_store_retrieval.py +97 -0
- sidegraph-0.1.0/tests/test_store_slug_conflicts.py +332 -0
- sidegraph-0.1.0/tests/test_store_stamping_marker.py +322 -0
- sidegraph-0.1.0/tests/test_store_telemetry.py +130 -0
- sidegraph-0.1.0/tests/test_store_threading.py +95 -0
- sidegraph-0.1.0/tests/test_store_tmp_sweep_age.py +90 -0
- sidegraph-0.1.0/tests/test_sync_clean.py +372 -0
- sidegraph-0.1.0/tests/test_sync_domains.py +937 -0
- sidegraph-0.1.0/tests/test_sync_drift_cache.py +280 -0
- sidegraph-0.1.0/tests/test_sync_fresh_clone.py +126 -0
- sidegraph-0.1.0/tests/test_sync_integration.py +165 -0
- sidegraph-0.1.0/tests/test_sync_rebind.py +302 -0
- sidegraph-0.1.0/tests/test_sync_repoint.py +204 -0
- sidegraph-0.1.0/tests/test_sync_report_has_findings.py +92 -0
- sidegraph-0.1.0/tests/test_sync_run.py +162 -0
- sidegraph-0.1.0/tests/test_sync_toc_cache.py +125 -0
- sidegraph-0.1.0/tests/test_sync_volatile_heal.py +303 -0
- sidegraph-0.1.0/tests/test_sync_wiring.py +75 -0
- sidegraph-0.1.0/tests/test_telemetry_retention.py +63 -0
- sidegraph-0.1.0/tests/test_verify_snapshot.py +497 -0
- sidegraph-0.1.0/tests/test_verify_transitions.py +660 -0
- sidegraph-0.1.0/tests/test_viz_asset_packaged.py +9 -0
- sidegraph-0.1.0/tests/test_viz_model.py +127 -0
- sidegraph-0.1.0/tests/test_viz_render_html.py +61 -0
- sidegraph-0.1.0/tests/test_viz_render_json.py +89 -0
- sidegraph-0.1.0/uv.lock +1518 -0
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "sidegraph",
|
|
3
|
+
"description": "Sidegraph — durable decision memory for AI coding agents.",
|
|
4
|
+
"plugins": [
|
|
5
|
+
{
|
|
6
|
+
"name": "sidegraph",
|
|
7
|
+
"source": {
|
|
8
|
+
"source": "local",
|
|
9
|
+
"path": "./plugin/sidegraph"
|
|
10
|
+
},
|
|
11
|
+
"description": "Durable decision/lessons memory over your code graph — captured in-session, human-ratified, retrieved mistakes-first, surviving refactors."
|
|
12
|
+
}
|
|
13
|
+
]
|
|
14
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "sidegraph",
|
|
3
|
+
"description": "Sidegraph — durable decision memory for AI coding agents.",
|
|
4
|
+
"owner": { "name": "SantyagoSeaman", "url": "https://github.com/SantyagoSeaman" },
|
|
5
|
+
"plugins": [
|
|
6
|
+
{
|
|
7
|
+
"name": "sidegraph",
|
|
8
|
+
"source": "./plugin/sidegraph",
|
|
9
|
+
"description": "Durable decision/lessons memory over your code graph — captured in-session, human-ratified, retrieved mistakes-first, surviving refactors.",
|
|
10
|
+
"homepage": "https://github.com/SantyagoSeaman/sidegraph"
|
|
11
|
+
}
|
|
12
|
+
]
|
|
13
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
name: Bug report
|
|
2
|
+
description: Something in Sidegraph behaves differently than documented.
|
|
3
|
+
labels: ["bug"]
|
|
4
|
+
body:
|
|
5
|
+
- type: textarea
|
|
6
|
+
id: what-happened
|
|
7
|
+
attributes:
|
|
8
|
+
label: What happened
|
|
9
|
+
description: What you ran, what you expected, what you got.
|
|
10
|
+
placeholder: |
|
|
11
|
+
Command: uvx --from git+https://github.com/SantyagoSeaman/sidegraph.git@main sidegraph-verify
|
|
12
|
+
Expected: exit 0
|
|
13
|
+
Got: ...
|
|
14
|
+
validations:
|
|
15
|
+
required: true
|
|
16
|
+
- type: textarea
|
|
17
|
+
id: reproduce
|
|
18
|
+
attributes:
|
|
19
|
+
label: Minimal reproduction
|
|
20
|
+
description: The smallest sequence that shows the problem.
|
|
21
|
+
validations:
|
|
22
|
+
required: true
|
|
23
|
+
- type: input
|
|
24
|
+
id: version
|
|
25
|
+
attributes:
|
|
26
|
+
label: Sidegraph version
|
|
27
|
+
description: "Output of: uv run python -c \"import importlib.metadata as m; print(m.version('sidegraph'))\""
|
|
28
|
+
validations:
|
|
29
|
+
required: true
|
|
30
|
+
- type: input
|
|
31
|
+
id: graphify
|
|
32
|
+
attributes:
|
|
33
|
+
label: Graphify version
|
|
34
|
+
description: The engine version whose graph.json you are reading.
|
|
35
|
+
- type: markdown
|
|
36
|
+
attributes:
|
|
37
|
+
value: "For security issues do **not** open an issue — see [SECURITY.md](../blob/main/SECURITY.md)."
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
name: Feature request
|
|
2
|
+
description: Propose a change to Sidegraph.
|
|
3
|
+
labels: ["enhancement"]
|
|
4
|
+
body:
|
|
5
|
+
- type: textarea
|
|
6
|
+
id: problem
|
|
7
|
+
attributes:
|
|
8
|
+
label: The problem
|
|
9
|
+
description: What decision memory is failing you today? Describe the situation, not the solution.
|
|
10
|
+
validations:
|
|
11
|
+
required: true
|
|
12
|
+
- type: textarea
|
|
13
|
+
id: proposal
|
|
14
|
+
attributes:
|
|
15
|
+
label: Proposed change
|
|
16
|
+
validations:
|
|
17
|
+
required: true
|
|
18
|
+
- type: checkboxes
|
|
19
|
+
id: invariants
|
|
20
|
+
attributes:
|
|
21
|
+
label: Invariant check
|
|
22
|
+
description: See CLAUDE.md. Proposals that break these will not land.
|
|
23
|
+
options:
|
|
24
|
+
- label: Does not write into the engine's graph.json (read-only input)
|
|
25
|
+
- label: Does not hard-delete a Decision (the store is append-only)
|
|
26
|
+
- label: Is obviously useful to an LLM consuming the memory
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
<!--
|
|
2
|
+
This file ships in two places. On the internal repo, this PR is the normal path to merge.
|
|
3
|
+
On the public repo (a released snapshot, see CONTRIBUTING.md), this PR is a proposal: it is
|
|
4
|
+
reviewed here and ported upstream with attribution, then arrives back with the next release.
|
|
5
|
+
Either way, fill in the same two sections.
|
|
6
|
+
-->
|
|
7
|
+
|
|
8
|
+
## What changed and why
|
|
9
|
+
|
|
10
|
+
<!-- One or two sentences: what this PR does and the problem it solves. -->
|
|
11
|
+
|
|
12
|
+
## Checklist
|
|
13
|
+
|
|
14
|
+
- [ ] Tests pass (`uv run pytest -q`)
|
|
15
|
+
- [ ] `uv run pre-commit run --all-files` is clean
|
|
16
|
+
- [ ] Docs under `docs/` are updated for any behaviour change
|
|
17
|
+
- [ ] A CHANGELOG entry is added under `[Unreleased]` for any user-visible change
|
|
18
|
+
- [ ] No hand edits to records under `.sidegraph/` (the store is append-only and written by
|
|
19
|
+
the tools, never by hand)
|
|
20
|
+
- [ ] Any new dependency is called out and justified in this description
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
# Project lint+type+test gate. `lint` runs the SAME .pre-commit-config.yaml a developer
|
|
2
|
+
# runs locally, so there is one definition of lint rather than a CI copy that drifts.
|
|
3
|
+
# Mostly distinct from the sidegraph-recipe workflows in docs/guides/ci-cd-maintenance.md
|
|
4
|
+
# (recipes for USER repos consuming Sidegraph) — except `store-lint`, which is Recipe 2
|
|
5
|
+
# self-applied to this repo's own dogfood store (2026-08-09 maintenance retrospective,
|
|
6
|
+
# cadence lever): the store rides every PR, so its transition rules should gate every PR.
|
|
7
|
+
#
|
|
8
|
+
# Actions are pinned to commit SHAs (the tag comment records the version): a mutable tag
|
|
9
|
+
# is a supply-chain hole, and this workflow ships to the public repo by snapshot.
|
|
10
|
+
name: ci
|
|
11
|
+
|
|
12
|
+
on:
|
|
13
|
+
push:
|
|
14
|
+
branches: [main]
|
|
15
|
+
pull_request:
|
|
16
|
+
workflow_call: # reused as the pre-publish gate by publish.yml (tag builds)
|
|
17
|
+
|
|
18
|
+
permissions:
|
|
19
|
+
contents: read
|
|
20
|
+
|
|
21
|
+
jobs:
|
|
22
|
+
lint:
|
|
23
|
+
runs-on: ubuntu-latest
|
|
24
|
+
timeout-minutes: 15
|
|
25
|
+
steps:
|
|
26
|
+
# zizmor artipacked: this job never pushes, so the checkout's git credentials should not
|
|
27
|
+
# persist into the runner's git config where a later step (or an uploaded artifact) could
|
|
28
|
+
# leak them.
|
|
29
|
+
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
|
|
30
|
+
with:
|
|
31
|
+
persist-credentials: false
|
|
32
|
+
|
|
33
|
+
- name: Install uv
|
|
34
|
+
uses: astral-sh/setup-uv@20cfd1bf945f4377ade1205e4dbc17946fc9a30d # v10.0.1
|
|
35
|
+
with:
|
|
36
|
+
python-version: "3.13"
|
|
37
|
+
enable-cache: true
|
|
38
|
+
cache-dependency-glob: "uv.lock"
|
|
39
|
+
|
|
40
|
+
- name: Cache pre-commit hooks
|
|
41
|
+
uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6
|
|
42
|
+
with:
|
|
43
|
+
path: ~/.cache/pre-commit
|
|
44
|
+
key: pre-commit-${{ hashFiles('.pre-commit-config.yaml') }}
|
|
45
|
+
|
|
46
|
+
- name: Install dependencies
|
|
47
|
+
run: uv sync --locked
|
|
48
|
+
|
|
49
|
+
- name: Run pre-commit checks
|
|
50
|
+
run: uv run pre-commit run --all-files
|
|
51
|
+
|
|
52
|
+
test:
|
|
53
|
+
runs-on: ubuntu-latest
|
|
54
|
+
timeout-minutes: 30
|
|
55
|
+
strategy:
|
|
56
|
+
fail-fast: false
|
|
57
|
+
matrix:
|
|
58
|
+
python-version: ["3.13", "3.14"]
|
|
59
|
+
steps:
|
|
60
|
+
# zizmor artipacked: this job never pushes; do not persist git credentials past checkout.
|
|
61
|
+
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
|
|
62
|
+
with:
|
|
63
|
+
persist-credentials: false
|
|
64
|
+
|
|
65
|
+
- name: Install uv
|
|
66
|
+
uses: astral-sh/setup-uv@20cfd1bf945f4377ade1205e4dbc17946fc9a30d # v10.0.1
|
|
67
|
+
with:
|
|
68
|
+
python-version: ${{ matrix.python-version }}
|
|
69
|
+
enable-cache: true
|
|
70
|
+
cache-dependency-glob: "uv.lock"
|
|
71
|
+
|
|
72
|
+
- name: Install dependencies
|
|
73
|
+
run: uv sync --locked
|
|
74
|
+
|
|
75
|
+
- name: Run tests
|
|
76
|
+
run: uv run pytest -q
|
|
77
|
+
|
|
78
|
+
# Recipe 2 (docs/guides/ci-cd-maintenance.md) on our own store: catch a hand-edited or
|
|
79
|
+
# history-rewritten record no MCP tool would produce. Diffs against the PR's merge base
|
|
80
|
+
# (never a moving branch name — see the recipe for why). Skips cleanly when the checkout
|
|
81
|
+
# carries no store: the public snapshot ships .sidegraph only on the demo branch, and
|
|
82
|
+
# this workflow ships to the public repo.
|
|
83
|
+
store-lint:
|
|
84
|
+
if: github.event_name == 'pull_request'
|
|
85
|
+
runs-on: ubuntu-latest
|
|
86
|
+
timeout-minutes: 10
|
|
87
|
+
steps:
|
|
88
|
+
# zizmor artipacked: this job never pushes; do not persist git credentials past checkout.
|
|
89
|
+
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
|
|
90
|
+
with:
|
|
91
|
+
fetch-depth: 0 # full history — merge-base needs it
|
|
92
|
+
persist-credentials: false
|
|
93
|
+
|
|
94
|
+
- name: Install uv
|
|
95
|
+
uses: astral-sh/setup-uv@20cfd1bf945f4377ade1205e4dbc17946fc9a30d # v10.0.1
|
|
96
|
+
with:
|
|
97
|
+
python-version: "3.13"
|
|
98
|
+
enable-cache: true
|
|
99
|
+
cache-dependency-glob: "uv.lock"
|
|
100
|
+
|
|
101
|
+
- name: sidegraph-verify --against merge-base
|
|
102
|
+
run: |
|
|
103
|
+
if [ ! -d .sidegraph ]; then
|
|
104
|
+
echo "no .sidegraph in this checkout — store lint not applicable"
|
|
105
|
+
exit 0
|
|
106
|
+
fi
|
|
107
|
+
uv sync --locked
|
|
108
|
+
git fetch origin "$GITHUB_BASE_REF"
|
|
109
|
+
base="$(git merge-base "origin/$GITHUB_BASE_REF" HEAD)"
|
|
110
|
+
uv run sidegraph-verify --against "$base" --json
|
|
111
|
+
|
|
112
|
+
# Recipe 1 self-applied: rebuild the graph from scratch and fail on attention findings
|
|
113
|
+
# (stale decisions, empty/overbroad domains, slug conflicts, refresh failures). A
|
|
114
|
+
# cache-less rebuild was verified label-identical to the local cached graph and the
|
|
115
|
+
# check green on it (2026-08-09 retrospective, cadence lever) — so a red here is a real
|
|
116
|
+
# finding, not CI-environment noise. Lone orphaned/ambiguous entities do NOT fail the
|
|
117
|
+
# check: multi-anchor tolerates them by design. The engine is version-pinned (engine-
|
|
118
|
+
# seam invariant); the sync writes only to the ephemeral checkout's .sidegraph/.
|
|
119
|
+
anchor-health:
|
|
120
|
+
if: github.event_name == 'pull_request'
|
|
121
|
+
runs-on: ubuntu-latest
|
|
122
|
+
timeout-minutes: 15
|
|
123
|
+
steps:
|
|
124
|
+
# zizmor artipacked: this job never pushes; do not persist git credentials past checkout.
|
|
125
|
+
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
|
|
126
|
+
with:
|
|
127
|
+
persist-credentials: false
|
|
128
|
+
|
|
129
|
+
- name: Install uv
|
|
130
|
+
uses: astral-sh/setup-uv@20cfd1bf945f4377ade1205e4dbc17946fc9a30d # v10.0.1
|
|
131
|
+
with:
|
|
132
|
+
python-version: "3.13"
|
|
133
|
+
enable-cache: true
|
|
134
|
+
cache-dependency-glob: "uv.lock"
|
|
135
|
+
|
|
136
|
+
- name: Rebuild graph and run sidegraph-sync --check
|
|
137
|
+
run: |
|
|
138
|
+
if [ ! -d .sidegraph ]; then
|
|
139
|
+
echo "no .sidegraph in this checkout — anchor health not applicable"
|
|
140
|
+
exit 0
|
|
141
|
+
fi
|
|
142
|
+
uvx --from graphifyy==0.9.6 graphify update .
|
|
143
|
+
uv sync --locked
|
|
144
|
+
uv run sidegraph-sync --json --check
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
# Build and publish sidegraph to PyPI on a version tag — gated on the full test suite.
|
|
2
|
+
#
|
|
3
|
+
# Trigger: push a semver tag, e.g. `git tag v0.1.0 && git push origin v0.1.0`. Deliberately
|
|
4
|
+
# no `workflow_dispatch`: a manual run has no tag ref, and the "tag matches pyproject
|
|
5
|
+
# version" check below only means something against a real tag ref. Keeping a manual
|
|
6
|
+
# trigger around that can never pass that check is pointless at best; before Trusted
|
|
7
|
+
# Publishing goes live for 0.1.0 it would be one stray click away from publishing an
|
|
8
|
+
# untagged tree under whatever version pyproject.toml happens to carry.
|
|
9
|
+
# Gate: the `test` job reuses ci.yml (pre-commit lint + pytest across the Python matrix);
|
|
10
|
+
# build/publish only run if it passes. `git-tag == pyproject version` is enforced
|
|
11
|
+
# unconditionally (not just `if: startsWith(github.ref, 'refs/tags/')`) so a mistyped
|
|
12
|
+
# tag never ships, and so a future trigger that isn't a tag push fails this check
|
|
13
|
+
# loudly instead of silently skipping it.
|
|
14
|
+
# Auth: PyPI Trusted Publishing (OIDC) — no API token stored. One-time PyPI setup:
|
|
15
|
+
# project `sidegraph` → Trusted Publishers → add owner `SantyagoSeaman`, repo
|
|
16
|
+
# `sidegraph`, workflow `publish.yml`, environment `pypi`. Also create a GitHub
|
|
17
|
+
# environment named `pypi` (Settings → Environments) for the protection rule.
|
|
18
|
+
# TestPyPI dry run first (recommended): locally `uv build` then
|
|
19
|
+
# `uv publish --publish-url https://test.pypi.org/legacy/` (needs a TestPyPI token),
|
|
20
|
+
# and `pip install -i https://test.pypi.org/simple/ sidegraph` to smoke the wheel.
|
|
21
|
+
name: publish
|
|
22
|
+
|
|
23
|
+
on:
|
|
24
|
+
push:
|
|
25
|
+
tags: ["v*.*.*"]
|
|
26
|
+
|
|
27
|
+
permissions:
|
|
28
|
+
contents: read
|
|
29
|
+
|
|
30
|
+
jobs:
|
|
31
|
+
test:
|
|
32
|
+
# zizmor self-repository: flags this as the older `./...` reusable-workflow reference and
|
|
33
|
+
# suggests the newer `$/...` form. Not applied: GA support for `$/...` on the runners this
|
|
34
|
+
# workflow actually executes on is unconfirmed, and this reference is exactly the job graph
|
|
35
|
+
# the task guardrails say not to touch on a guess — a broken reusable-workflow call here
|
|
36
|
+
# would silently skip the test gate in front of a PyPI publish. `./...` is GitHub's
|
|
37
|
+
# documented, stable syntax for a same-repo reusable workflow.
|
|
38
|
+
uses: ./.github/workflows/ci.yml # zizmor: ignore[self-repository] stable syntax kept; see comment above
|
|
39
|
+
|
|
40
|
+
build:
|
|
41
|
+
needs: test
|
|
42
|
+
runs-on: ubuntu-latest
|
|
43
|
+
timeout-minutes: 15
|
|
44
|
+
steps:
|
|
45
|
+
# zizmor artipacked: this job never pushes; do not persist git credentials past checkout.
|
|
46
|
+
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
|
|
47
|
+
with:
|
|
48
|
+
persist-credentials: false
|
|
49
|
+
|
|
50
|
+
- name: Install uv
|
|
51
|
+
uses: astral-sh/setup-uv@20cfd1bf945f4377ade1205e4dbc17946fc9a30d # v10.0.1
|
|
52
|
+
|
|
53
|
+
- name: Tag matches pyproject version
|
|
54
|
+
# Unconditional on purpose: `on:` above only triggers this workflow from a tag push,
|
|
55
|
+
# but this check is the backstop if that ever changes (e.g. workflow_dispatch comes
|
|
56
|
+
# back without this comment being read first). A non-tag ref fails it cleanly instead
|
|
57
|
+
# of silently skipping straight to build/publish.
|
|
58
|
+
run: |
|
|
59
|
+
VERSION=$(uv run --no-project python -c "import tomllib; print(tomllib.load(open('pyproject.toml','rb'))['project']['version'])")
|
|
60
|
+
TAG="${GITHUB_REF_NAME#v}"
|
|
61
|
+
[ "$VERSION" = "$TAG" ] || { echo "tag v$TAG != pyproject version $VERSION — bump one to match" >&2; exit 1; }
|
|
62
|
+
|
|
63
|
+
- name: Build sdist + wheel
|
|
64
|
+
run: uv build
|
|
65
|
+
|
|
66
|
+
- uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7
|
|
67
|
+
with:
|
|
68
|
+
name: dist
|
|
69
|
+
path: dist/
|
|
70
|
+
|
|
71
|
+
publish:
|
|
72
|
+
needs: build
|
|
73
|
+
runs-on: ubuntu-latest
|
|
74
|
+
environment: pypi
|
|
75
|
+
permissions:
|
|
76
|
+
id-token: write # OIDC token for PyPI Trusted Publishing
|
|
77
|
+
steps:
|
|
78
|
+
- uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8
|
|
79
|
+
with:
|
|
80
|
+
name: dist
|
|
81
|
+
path: dist/
|
|
82
|
+
|
|
83
|
+
- name: Publish to PyPI
|
|
84
|
+
uses: pypa/gh-action-pypi-publish@dc37677b2e1c63e2034f94d8a5b11f265b73ba33 # v1.14.2
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
name: scorecard
|
|
2
|
+
|
|
3
|
+
# OpenSSF Scorecard — supply-chain / security-health analysis. Publishes to the public
|
|
4
|
+
# OpenSSF API so the README badge works.
|
|
5
|
+
#
|
|
6
|
+
# This file ships to the public repo by snapshot but must not run in the internal
|
|
7
|
+
# development repo (private; the analysis is meaningless there) — hence the repository guard
|
|
8
|
+
# on the job rather than a public-only overlay mechanism.
|
|
9
|
+
on:
|
|
10
|
+
workflow_dispatch:
|
|
11
|
+
branch_protection_rule:
|
|
12
|
+
schedule:
|
|
13
|
+
- cron: "20 7 * * 1" # weekly, Monday 07:20 UTC
|
|
14
|
+
push:
|
|
15
|
+
branches: [main]
|
|
16
|
+
|
|
17
|
+
permissions: read-all
|
|
18
|
+
|
|
19
|
+
jobs:
|
|
20
|
+
analysis:
|
|
21
|
+
name: Scorecard analysis
|
|
22
|
+
if: github.repository == 'SantyagoSeaman/sidegraph'
|
|
23
|
+
runs-on: ubuntu-latest
|
|
24
|
+
timeout-minutes: 15
|
|
25
|
+
permissions:
|
|
26
|
+
contents: read
|
|
27
|
+
id-token: write # publish results to the OpenSSF API (required for the badge)
|
|
28
|
+
steps:
|
|
29
|
+
- name: Checkout
|
|
30
|
+
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
|
|
31
|
+
with:
|
|
32
|
+
persist-credentials: false
|
|
33
|
+
|
|
34
|
+
- name: Run analysis
|
|
35
|
+
uses: ossf/scorecard-action@2d1146689b8cda280b9bc96326124645441f03bc # v2.4.4
|
|
36
|
+
with:
|
|
37
|
+
results_file: results.sarif
|
|
38
|
+
results_format: sarif
|
|
39
|
+
publish_results: true
|
|
40
|
+
|
|
41
|
+
- name: Upload artifact
|
|
42
|
+
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7
|
|
43
|
+
with:
|
|
44
|
+
name: SARIF file
|
|
45
|
+
path: results.sarif
|
|
46
|
+
retention-days: 5
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
# Python
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[cod]
|
|
4
|
+
*.egg-info/
|
|
5
|
+
.eggs/
|
|
6
|
+
build/
|
|
7
|
+
dist/
|
|
8
|
+
.venv/
|
|
9
|
+
venv/
|
|
10
|
+
|
|
11
|
+
# Tooling
|
|
12
|
+
.pytest_cache/
|
|
13
|
+
.ruff_cache/
|
|
14
|
+
.mypy_cache/
|
|
15
|
+
|
|
16
|
+
# IDE
|
|
17
|
+
.idea/
|
|
18
|
+
.vscode/
|
|
19
|
+
|
|
20
|
+
# OS
|
|
21
|
+
.DS_Store
|
|
22
|
+
|
|
23
|
+
# Sidegraph local store (the committed sidecar lives in the target repo, not here)
|
|
24
|
+
sidegraph.db
|
|
25
|
+
*.db-journal
|
|
26
|
+
|
|
27
|
+
# Graphify engine output — read-only input, regenerated by `graphify update` (invariant #1)
|
|
28
|
+
graphify-out/
|
|
29
|
+
|
|
30
|
+
# sidegraph-viz output — generated artifact, regenerated by `sidegraph-viz`
|
|
31
|
+
sidegraph-graph.html
|
|
32
|
+
sidegraph-graph.json
|
|
33
|
+
|
|
34
|
+
# Corpus leak-gate secondary token denylist (never committed — holds sensitive markers)
|
|
35
|
+
/.corpus-leak-denylist
|
|
36
|
+
|
|
37
|
+
# promote-fixtures displaces originals here while copying; removed on every controlled path,
|
|
38
|
+
# but a hard kill (SIGKILL) can leave one behind
|
|
39
|
+
tests/fixtures/.promote-fixtures-trash-*
|
|
40
|
+
|
|
41
|
+
# The private sidegraph-sandbox testbed is never nested inside this OSS repo
|
|
42
|
+
/sidegraph-sandbox/
|
|
43
|
+
|
|
44
|
+
# Corpus working copies must never live inside this tree (spec §3). The guard test is the
|
|
45
|
+
# mechanism; this entry is the backstop that stops an accidental nesting being committed
|
|
46
|
+
# before the guard runs.
|
|
47
|
+
sandboxes/
|
|
48
|
+
|
|
49
|
+
# Machine-local host/tool configs and flow scratch — never repo state. .mcp.json points at
|
|
50
|
+
# a localhost MCP port that dies with the IDE session; .codex/ is the Codex CLI's local
|
|
51
|
+
# config; .superpowers/ is the flow's working scratch (briefs/diffs/tokens) whose durable
|
|
52
|
+
# outputs are distilled into design/superpowers/ and the store.
|
|
53
|
+
#
|
|
54
|
+
# Anchored to the repo root (leading "/"): these patterns exist only to ignore the developer's
|
|
55
|
+
# OWN root-level scratch files/dirs, never a project file that happens to share the basename.
|
|
56
|
+
# Unanchored, they matched (and silently untracked-from-`git add -A`) tracked, force-added
|
|
57
|
+
# project content at any depth — plugin/sidegraph/.mcp.json (the Claude plugin's MCP manifest)
|
|
58
|
+
# and three Codex bootstrap fixtures under tests/fixtures/ — which is exactly how the first
|
|
59
|
+
# real public release's commit shipped missing those four files (design/testing intact on
|
|
60
|
+
# disk, dropped from the commit because the public checkout's `git add -A` obeys .gitignore).
|
|
61
|
+
/.mcp.json
|
|
62
|
+
/.codex/
|
|
63
|
+
/.superpowers/
|
|
64
|
+
/.worktrees/
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
title = "sidegraph gitleaks config"
|
|
2
|
+
|
|
3
|
+
# Extends gitleaks' default ruleset rather than replacing it.
|
|
4
|
+
[extend]
|
|
5
|
+
useDefault = true
|
|
6
|
+
|
|
7
|
+
# Path-scoped allowlist, never a global disable: every path below either belongs to the
|
|
8
|
+
# redaction feature's own test fixtures (deliberately shaped like a real credential so the
|
|
9
|
+
# redaction regexes in src/sidegraph/capture.py have something to catch — see
|
|
10
|
+
# tests/test_capture_redact.py's docstring), a design-plan doc quoting the same fixtures, or
|
|
11
|
+
# vendored third-party content we do not edit. A real secret anywhere else in the repo still
|
|
12
|
+
# fails the scan. This file ships to the public repo (tests/ ships wholesale with the same
|
|
13
|
+
# fixtures), so it has to hold there too.
|
|
14
|
+
[allowlist]
|
|
15
|
+
description = "Known-fake secrets in redaction-feature fixtures and vendored/planning content"
|
|
16
|
+
paths = [
|
|
17
|
+
'''^tests/test_capture_redact\.py$''',
|
|
18
|
+
'''^tests/test_redaction_seeded\.py$''',
|
|
19
|
+
'''^tests/test_capture_propose\.py$''',
|
|
20
|
+
'''^tests/test_capture_integration\.py$''',
|
|
21
|
+
'''^tests/test_capture_facts\.py$''',
|
|
22
|
+
'''^tests/test_importer\.py$''',
|
|
23
|
+
'''^tests/test_doc_import\.py$''',
|
|
24
|
+
'''^tests/test_domains\.py$''',
|
|
25
|
+
'''^tests/test_server_capture\.py$''',
|
|
26
|
+
'''^tests/test_server_domains\.py$''',
|
|
27
|
+
'''^tests/test_server_facts\.py$''',
|
|
28
|
+
'''^tests/test_server_redaction\.py$''',
|
|
29
|
+
'''^design/superpowers/plans/2026-07-06-capture-ratification\.md$''',
|
|
30
|
+
'''^design/superpowers/plans/2026-07-10-facts-layer\.md$''',
|
|
31
|
+
'''^src/sidegraph/viz/assets/vis-network\.min\.js$''',
|
|
32
|
+
]
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
# The single definition of "lint" for this repo. The same file drives the local
|
|
2
|
+
# pre-commit hook, `uv run pre-commit run --all-files`, the CI `lint` job, and the
|
|
3
|
+
# release script's snapshot verification — so those four can never disagree.
|
|
4
|
+
#
|
|
5
|
+
# ruff and mypy run as `repo: local` hooks through `uv run` rather than through their
|
|
6
|
+
# upstream pre-commit mirrors: that keeps exactly ONE version of each tool (the one
|
|
7
|
+
# pinned in uv.lock), and lets mypy see the real project environment, which it needs
|
|
8
|
+
# for the pydantic.mypy plugin configured in pyproject.toml.
|
|
9
|
+
#
|
|
10
|
+
# .sidegraph/ is excluded repo-wide: the store is append-only and machine-written, and
|
|
11
|
+
# letting a whitespace fixer rewrite its records would mutate the store as a side effect
|
|
12
|
+
# of committing. src/sidegraph/viz/assets/ holds a vendored 688 KB bundle that is not
|
|
13
|
+
# ours to reformat. sidegraph-graph.html is the --demo release's generated decision-graph
|
|
14
|
+
# viz (tools/release-public.sh force-adds it since it's gitignored internally): it's over a
|
|
15
|
+
# megabyte and its size tracks the store, so check-added-large-files (--maxkb=1024) would
|
|
16
|
+
# fail the FIRST --demo release at its own verification gate — a generated release artifact,
|
|
17
|
+
# not something to lint or size-cap.
|
|
18
|
+
# The whitepaper's VERBATIM raw-artifact bundle is excluded under BOTH of its paths: it
|
|
19
|
+
# lives at design/whitepaper/evidence/artifact-bundle/ here and the release relocates it
|
|
20
|
+
# to docs/whitepaper/evidence/artifact-bundle/ in the public snapshot, where this same
|
|
21
|
+
# config runs again as the snapshot's verification step. Its scripts ship byte-identical
|
|
22
|
+
# to what produced the published numbers, under a SHA-256 manifest — a formatter "fixing"
|
|
23
|
+
# them falsifies both the verbatim promise and every hash. Measured, not hypothetical:
|
|
24
|
+
# with only the internal path excluded, the first snapshot build reformatted nine bundle
|
|
25
|
+
# scripts and broke 41 of the manifest's hashes. (The corpus leak gate still scans the
|
|
26
|
+
# bundle either way: it walks the filesystem itself and ignores this exclude.)
|
|
27
|
+
exclude: '^(\.sidegraph/|src/sidegraph/viz/assets/|sidegraph-graph\.html|(design|docs)/whitepaper/evidence/artifact-bundle/)'
|
|
28
|
+
|
|
29
|
+
repos:
|
|
30
|
+
- repo: https://github.com/pre-commit/pre-commit-hooks
|
|
31
|
+
rev: v5.0.0
|
|
32
|
+
hooks:
|
|
33
|
+
- id: trailing-whitespace
|
|
34
|
+
args: [--markdown-linebreak-ext=md] # keep intentional two-space hard breaks in docs
|
|
35
|
+
- id: end-of-file-fixer
|
|
36
|
+
- id: check-yaml
|
|
37
|
+
- id: check-json
|
|
38
|
+
# Catches a malformed pyproject.toml (or other tracked .toml) before it reaches CI's
|
|
39
|
+
# `uv sync --locked`, which fails on the same file far less legibly.
|
|
40
|
+
- id: check-toml
|
|
41
|
+
- id: check-merge-conflict
|
|
42
|
+
- id: check-added-large-files
|
|
43
|
+
args: [--maxkb=1024]
|
|
44
|
+
- id: debug-statements
|
|
45
|
+
# Refuses a commit that adds a real private key (RSA/DSA/EC/OpenSSH) as a tracked file —
|
|
46
|
+
# the capture-redaction feature (src/sidegraph/capture.py) already regexes decision
|
|
47
|
+
# CONTENT for this pattern; this guards the source tree itself. Excludes the redaction
|
|
48
|
+
# feature's own fake-key test fixtures and the design note that quotes them, none of
|
|
49
|
+
# which is a real key.
|
|
50
|
+
- id: detect-private-key
|
|
51
|
+
exclude: |
|
|
52
|
+
(?x)^(
|
|
53
|
+
tests/test_capture_redact\.py|
|
|
54
|
+
tests/test_redaction_seeded\.py|
|
|
55
|
+
design/superpowers/plans/2026-07-06-capture-ratification\.md
|
|
56
|
+
)$
|
|
57
|
+
|
|
58
|
+
# Broad secret-detection net (AWS/GCP/GitHub/Slack tokens, private keys, etc.) beyond the
|
|
59
|
+
# corpus leak gate's fixed denylist and the redaction feature's own patterns — catches a
|
|
60
|
+
# live credential anywhere in a tracked file, not just the paths those two already watch.
|
|
61
|
+
# `.gitleaks.toml` path-scopes allowlisting for the redaction feature's own fake-token test
|
|
62
|
+
# fixtures (tests/test_capture_redact.py etc.), never a global disable.
|
|
63
|
+
- repo: https://github.com/gitleaks/gitleaks
|
|
64
|
+
rev: v8.30.1
|
|
65
|
+
hooks:
|
|
66
|
+
- id: gitleaks
|
|
67
|
+
|
|
68
|
+
# Finds GitHub Actions supply-chain/security issues (unpinned actions, script injection via
|
|
69
|
+
# untrusted `${{ }}` template interpolation, excessive `permissions:`) in the workflows that
|
|
70
|
+
# ship to the public repo — the class of defect a human diff review easily misses.
|
|
71
|
+
- repo: https://github.com/zizmorcore/zizmor-pre-commit
|
|
72
|
+
rev: v1.30.1
|
|
73
|
+
hooks:
|
|
74
|
+
- id: zizmor
|
|
75
|
+
|
|
76
|
+
# Static-checks GitHub Actions workflow YAML (invalid expressions, undefined contexts,
|
|
77
|
+
# shellcheck issues inside `run:` steps) — complements zizmor's security focus with
|
|
78
|
+
# correctness checks zizmor does not cover.
|
|
79
|
+
- repo: https://github.com/rhysd/actionlint
|
|
80
|
+
rev: v1.7.12
|
|
81
|
+
hooks:
|
|
82
|
+
- id: actionlint
|
|
83
|
+
|
|
84
|
+
- repo: local
|
|
85
|
+
hooks:
|
|
86
|
+
- id: ruff-check
|
|
87
|
+
name: ruff check
|
|
88
|
+
entry: uv run ruff check --fix
|
|
89
|
+
language: system
|
|
90
|
+
types_or: [python, pyi]
|
|
91
|
+
require_serial: true
|
|
92
|
+
- id: ruff-format
|
|
93
|
+
name: ruff format
|
|
94
|
+
entry: uv run ruff format
|
|
95
|
+
language: system
|
|
96
|
+
types_or: [python, pyi]
|
|
97
|
+
require_serial: true
|
|
98
|
+
- id: mypy
|
|
99
|
+
name: mypy
|
|
100
|
+
entry: uv run mypy
|
|
101
|
+
language: system
|
|
102
|
+
types: [python]
|
|
103
|
+
pass_filenames: false
|
|
104
|
+
require_serial: true
|
|
105
|
+
- id: corpus-leak-gate
|
|
106
|
+
name: corpus leak gate
|
|
107
|
+
# `python3`, not `uv run python`: the checker is deliberately stdlib-only, so uv buys
|
|
108
|
+
# nothing and would couple the gate to uv project discovery — which fails outright in a
|
|
109
|
+
# tree whose pyproject uv cannot parse (the release script's own test fixtures).
|
|
110
|
+
# The `test -f` guard exists because THIS FILE SHIPS: .pre-commit-config.yaml is in the
|
|
111
|
+
# release ALLOWLIST while tools/ is not, and the release script verifies the snapshot by
|
|
112
|
+
# running `pre-commit run --all-files` inside it. Without the guard, an always_run hook
|
|
113
|
+
# would look for a checker that by design does not exist there and fail every release,
|
|
114
|
+
# the public repo's CI, and every public contributor's first commit.
|
|
115
|
+
entry: bash -c 'test ! -f tools/corpus_leak.py || exec python3 tools/corpus_leak.py'
|
|
116
|
+
language: system
|
|
117
|
+
pass_filenames: false
|
|
118
|
+
always_run: true
|
|
119
|
+
require_serial: true
|
|
120
|
+
- id: uv-lock-check
|
|
121
|
+
name: uv.lock is in sync with pyproject.toml
|
|
122
|
+
# Catches a dependency bumped in pyproject.toml without refreshing uv.lock, which
|
|
123
|
+
# `uv sync --locked` (CI, and the release script's VERIFY_CMD/VIZ_CMD) would otherwise
|
|
124
|
+
# refuse at a much less convenient point — mid-release, or mid-CI-run.
|
|
125
|
+
entry: uv lock --check
|
|
126
|
+
language: system
|
|
127
|
+
pass_filenames: false
|
|
128
|
+
files: ^(pyproject\.toml|uv\.lock)$
|
|
129
|
+
- id: check-public-twins
|
|
130
|
+
name: public-twin contract check
|
|
131
|
+
# A `.public.` twin (plugin manifest, CLAUDE.public.md, CONTRIBUTING.public.md,
|
|
132
|
+
# AGENTS.public.md) with no base counterpart, or a plugin manifest that still points
|
|
133
|
+
# at the working tree instead of the released package, would otherwise ship broken
|
|
134
|
+
# and surface only when a consumer's install fails. Self-guarded like
|
|
135
|
+
# corpus-leak-gate: tools/ is not in the release ALLOWLIST, so this checker does not
|
|
136
|
+
# exist in the public snapshot or its CI.
|
|
137
|
+
entry: bash -c 'test ! -f tools/check_public_twins.py || exec python3 tools/check_public_twins.py'
|
|
138
|
+
language: system
|
|
139
|
+
pass_filenames: false
|
|
140
|
+
always_run: true
|
|
141
|
+
require_serial: true
|
|
142
|
+
- id: check-shipped-links
|
|
143
|
+
name: shipped-docs link check
|
|
144
|
+
# A relative Markdown link that resolves in THIS repo can still 404 once the release
|
|
145
|
+
# mapping is applied (design/whitepaper/draft.md -> docs/whitepaper/index.md, `.public.`
|
|
146
|
+
# twins renamed onto their base names, design/ and tools/ absent) — this catches that
|
|
147
|
+
# before the commit lands. Self-guarded: tools/ is not in the release ALLOWLIST.
|
|
148
|
+
entry: bash -c 'test ! -f tools/check_shipped_links.py || exec python3 tools/check_shipped_links.py'
|
|
149
|
+
language: system
|
|
150
|
+
pass_filenames: false
|
|
151
|
+
always_run: true
|
|
152
|
+
require_serial: true
|
|
153
|
+
- id: plugin-manifest-validate
|
|
154
|
+
name: validate plugin/marketplace manifests
|
|
155
|
+
# Confirms the plugin and marketplace manifests parse and validate under Claude Code's
|
|
156
|
+
# own schema before they ship, catching a manifest that would fail to install silently
|
|
157
|
+
# different from how it fails here. Skips cleanly (exit 0) where the `claude` CLI is
|
|
158
|
+
# not on PATH, e.g. the public repo's CI.
|
|
159
|
+
entry: bash -c 'command -v claude >/dev/null || exit 0; claude plugin validate .claude-plugin/marketplace.json && claude plugin validate plugin/sidegraph'
|
|
160
|
+
language: system
|
|
161
|
+
pass_filenames: false
|
|
162
|
+
files: ^(\.claude-plugin/|plugin/sidegraph/)
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
3.13
|