feat(omp): bridge hook-guard denials and context through native hooks - #3506
andrebrait wants to merge 3 commits into
Conversation
There was a problem hiding this comment.
Graphify reviewed this change.
Worth a look — the grounded gate found no coupling regressions or blocking issues, but 2 advisory finding(s) below merit a look before merge.
Formal verification. 2 change(s) tested, no difference found (not proven).
Graphify review — findings
Adds a native Oh My Pi guard integration via graphify omp install, which delegates registration to omp plugin install on the shipped graphify/omp package directory (with graphify omp path printing that directory for manual linking); the omp command is silenced from the stale-graph warning and rejects args other than install/path. The graphify TypeScript extension runs the installed hook-guard read|search CLI before native read/glob/grep/search bash calls on local paths, turning policy denials into OMP block/reason and guidance into a single deduplicated context message that resets on new user runs and session boundaries; it resolves graphify only from an absolute PATH entry outside the project, caps input/output/time per call, and fails open on any error. Trust gating relies on ctx.isProjectTrusted(), which current OMP reports as always-true, so it is not an enforced sandbox — OMP links must be removed with omp plugin uninstall graphify-omp since graphify uninstall does not touch OMP's registry.
Worth a look
- Project-controlled PATH symlink can bypass graphify executable rejection —
graphify/omp/index.ts:28· Escalate · high- agreed by 2 of 2 members but NOT verified (no proof, no reproducing execution) — consensus is not a verdict; needs human review
- Shared abort controller lets one session cancel another session's guard —
graphify/omp/index.ts:56· Escalate · medium- agreed by 2 of 2 members but NOT verified (no proof, no reproducing execution) — consensus is not a verdict; needs human review
Analysis details — impact, health, verification
Impact & health
Graphify review
Impact — 680 functions depend on the 413 functions this change touches.
Health — this change adds coupling hotspots:
- new:
dispatch_command()— 2 callers, 124 callees - new:
dispatch_install_cli()— 6 callers, 31 callees - new:
codebuddy_install()— 20 callers, 5 callees - new:
claude_install()— 19 callers, 4 callees - new:
gemini_install()— 10 callers, 7 callees - new:
claude_uninstall()— 17 callers, 4 callees - new:
_project_uninstall()— 5 callers, 13 callees - new:
_copy_skill_file()— 12 callers, 5 callees - …and 13 more — each is listed as a finding
Verification — 680 functions in the blast radius were not formally verified this run (proofs are advisory here).
Gate & verification
graphify gate
PASS — objectively clean (no health regressions, tests not run — proofs not run this pass (advisory)). Grounded, not self-assessed.
Advisory (not blocking):
- verification_scope: 680 function(s) in the blast radius were not formally verified this run
Test selection
Test selection
270 of 270 test file(s) selected (100%) via static blast radius.
Escalated to a full run for safety — the selection is not trustworthy on its own (see below). CI should run the whole suite.
tests/omp.test.ts— impact, changed-test, full-run-safetytests/test_affected_cli.py— impact, full-run-safetytests/test_affected_member_seed.py— full-run-safetytests/test_agents_platform.py— impact, full-run-safetytests/test_analyze.py— full-run-safetytests/test_anthropic_custom_endpoint.py— full-run-safetytests/test_antigravity_install.py— full-run-safetytests/test_apm_fallback_version.py— full-run-safetytests/test_architecture_doc.py— full-run-safetytests/test_astro_extraction.py— full-run-safetytests/test_astro_import_ids.py— full-run-safetytests/test_atomic_canvas_export.py— full-run-safetytests/test_atomic_version_stamp.py— impact, full-run-safetytests/test_atomic_writes.py— full-run-safetytests/test_backend_env_isolation.py— full-run-safetytests/test_backend_extras.py— full-run-safetytests/test_benchmark.py— full-run-safetytests/test_benchmark_raw_graph.py— full-run-safetytests/test_build.py— full-run-safetytests/test_build_merge_hyperedges_and_prune.py— full-run-safetytests/test_build_merge_shrink_guard.py— full-run-safetytests/test_builtin_global_type_refs.py— full-run-safetytests/test_cache.py— full-run-safetytests/test_callflow_html.py— full-run-safetytests/test_cargo_introspect.py— full-run-safetytests/test_carried_hyperedge_remap.py— full-run-safetytests/test_case_sensitive_resolution.py— full-run-safetytests/test_charmap_encoding.py— full-run-safetytests/test_chunking.py— full-run-safetytests/test_cjs_module_extension.py— full-run-safetytests/test_claude_cli_backend.py— full-run-safetytests/test_claude_md.py— impact, full-run-safetytests/test_cli_broken_pipe.py— full-run-safetytests/test_cli_export.py— full-run-safetytests/test_cli_help.py— full-run-safetytests/test_cluster.py— full-run-safetytests/test_codebuddy.py— impact, full-run-safetytests/test_community_hub_labels.py— full-run-safetytests/test_community_labels_skill.py— full-run-safetytests/test_confidence.py— full-run-safetytests/test_corrupt_graph_json.py— full-run-safetytests/test_cpp_nested_and_cli.py— full-run-safetytests/test_cpp_objc_cross_file_calls.py— full-run-safetytests/test_cpp_preprocess.py— full-run-safetytests/test_cross_extension_reexport_self_cycle.py— full-run-safetytests/test_cross_language_call_resolution.py— full-run-safetytests/test_cross_repo_member_calls.py— full-run-safetytests/test_cross_repo_shared_types.py— full-run-safetytests/test_csharp_call_site_generic_args.py— full-run-safetytests/test_csharp_enum_members.py— full-run-safety- … and 220 more
non-code file(s) changed (
CHANGELOG.md,README.md,graphify/omp/package.json,pyproject.toml) → running the full suite for safety (a code graph can't see config/fixture/data deps)
changed code file(s) with no mapped test (
CHANGELOG.md,README.md,pyproject.toml) — a coverage gap or a missing link — running the full suite rather than only the selected tests
Selection is safe under the controlled-regression assumption; always-run tests + a periodic full run are the backstops. Advisory — it never changes the check verdict.
Formal verification
No difference found (not proven): No behavior difference found in dispatch\_install\_cli (not a proof).
The verifier ran both versions of dispatch\_install\_cli on many inputs and saw identical behavior every time. Strong evidence the change is safe, but evidence, not a proof.
Guarantee: Empirical: differential testing (both versions run on many generated inputs). A divergence on an untested input remains possible, so this is 'no counterexample found', not 'proven equivalent'.
Note: An input the sampler did not try could still differ.
No difference found (not proven): No behavior difference found in \_run\_cli (not a proof).
The verifier ran both versions of \_run\_cli on many inputs and saw identical behavior every time. Strong evidence the change is safe, but evidence, not a proof.
Guarantee: Empirical: differential testing (both versions run on many generated inputs). A divergence on an untested input remains possible, so this is 'no counterexample found', not 'proven equivalent'.
Note: An input the sampler did not try could still differ.
· 21 more finding(s) on lines outside this diff (see the check run).
There was a problem hiding this comment.
Graphify reviewed this change.
Worth a look — the grounded gate found no coupling regressions or blocking issues, but 5 advisory finding(s) below merit a look before merge.
Formal verification. 2 change(s) tested, no difference found (not proven).
Graphify review — findings
Adds a native Oh My Pi guard integration via graphify omp install, which links the shipped graphify/omp package (containing package.json and a TypeScript index.ts extension) through omp plugin install, with graphify omp path printing the package directory and both commands routed through dispatch_install_cli and silenced from the stale-graph warning. The extension runs the installed graphify hook-guard read|search CLI before native read/glob/grep/search bash calls, turning policy denials into OMP block/reason and guidance into one deduplicated per-run context message; it only inspects local filesystem targets, requires an absolute-PATH graphify outside the project, and fails open on missing commands, oversized I/O, or a two-second timeout. Note the guard relies on ctx.isProjectTrusted(), which current OMP always returns true, so it is not an enforced sandbox and should only be enabled in trusted projects.
Worth a look
- Command inside project cwd is accepted, contradicting stated security intent —
graphify/omp/index.ts:31· Escalate · high- agreed by 2 of 2 members but NOT verified (no proof, no reproducing execution) — consensus is not a verdict; needs human review
- Read guard payload ignores the actual file_path input —
graphify/omp/index.ts:79· Escalate · high- agreed by 2 of 2 members but NOT verified (no proof, no reproducing execution) — consensus is not a verdict; needs human review
- Glob pattern is overwritten with resolved directory —
graphify/omp/index.ts:92· Escalate · high- agreed by 2 of 2 members but NOT verified (no proof, no reproducing execution) — consensus is not a verdict; needs human review
- Installer executes first omp found on PATH —
graphify/install.py:2113· Escalate · medium- agreed by 2 of 2 members but NOT verified (no proof, no reproducing execution) — consensus is not a verdict; needs human review
- Concurrent tool_call handlers race on shared guidance state via check-then-act —
graphify/omp/index.ts:84· Escalate · medium- agreed by 2 of 2 members but NOT verified (no proof, no reproducing execution) — consensus is not a verdict; needs human review
Analysis details — impact, health, verification
Impact & health
Graphify review
Impact — 680 functions depend on the 413 functions this change touches.
Health — this change adds coupling hotspots:
- new:
dispatch_command()— 2 callers, 124 callees - new:
dispatch_install_cli()— 6 callers, 31 callees - new:
codebuddy_install()— 20 callers, 5 callees - new:
claude_install()— 19 callers, 4 callees - new:
gemini_install()— 10 callers, 7 callees - new:
claude_uninstall()— 17 callers, 4 callees - new:
_project_uninstall()— 5 callers, 13 callees - new:
_copy_skill_file()— 12 callers, 5 callees - …and 13 more — each is listed as a finding
Verification — 680 functions in the blast radius were not formally verified this run (proofs are advisory here).
Health delta baseline: last indexed commit fe66389 (diverged from this PR's base — delta is approximate).
Gate & verification
graphify gate
PASS — objectively clean (no health regressions, tests not run — proofs not run this pass (advisory)). Grounded, not self-assessed.
Advisory (not blocking):
- verification_scope: 680 function(s) in the blast radius were not formally verified this run
Test selection
Test selection
270 of 270 test file(s) selected (100%) via static blast radius.
Escalated to a full run for safety — the selection is not trustworthy on its own (see below). CI should run the whole suite.
tests/omp.test.ts— impact, changed-test, full-run-safetytests/test_affected_cli.py— impact, full-run-safetytests/test_affected_member_seed.py— full-run-safetytests/test_agents_platform.py— impact, full-run-safetytests/test_analyze.py— full-run-safetytests/test_anthropic_custom_endpoint.py— full-run-safetytests/test_antigravity_install.py— full-run-safetytests/test_apm_fallback_version.py— full-run-safetytests/test_architecture_doc.py— full-run-safetytests/test_astro_extraction.py— full-run-safetytests/test_astro_import_ids.py— full-run-safetytests/test_atomic_canvas_export.py— full-run-safetytests/test_atomic_version_stamp.py— impact, full-run-safetytests/test_atomic_writes.py— full-run-safetytests/test_backend_env_isolation.py— full-run-safetytests/test_backend_extras.py— full-run-safetytests/test_benchmark.py— full-run-safetytests/test_benchmark_raw_graph.py— full-run-safetytests/test_build.py— full-run-safetytests/test_build_merge_hyperedges_and_prune.py— full-run-safetytests/test_build_merge_shrink_guard.py— full-run-safetytests/test_builtin_global_type_refs.py— full-run-safetytests/test_cache.py— full-run-safetytests/test_callflow_html.py— full-run-safetytests/test_cargo_introspect.py— full-run-safetytests/test_carried_hyperedge_remap.py— full-run-safetytests/test_case_sensitive_resolution.py— full-run-safetytests/test_charmap_encoding.py— full-run-safetytests/test_chunking.py— full-run-safetytests/test_cjs_module_extension.py— full-run-safetytests/test_claude_cli_backend.py— full-run-safetytests/test_claude_md.py— impact, full-run-safetytests/test_cli_broken_pipe.py— full-run-safetytests/test_cli_export.py— full-run-safetytests/test_cli_help.py— full-run-safetytests/test_cluster.py— full-run-safetytests/test_codebuddy.py— impact, full-run-safetytests/test_community_hub_labels.py— full-run-safetytests/test_community_labels_skill.py— full-run-safetytests/test_confidence.py— full-run-safetytests/test_corrupt_graph_json.py— full-run-safetytests/test_cpp_nested_and_cli.py— full-run-safetytests/test_cpp_objc_cross_file_calls.py— full-run-safetytests/test_cpp_preprocess.py— full-run-safetytests/test_cross_extension_reexport_self_cycle.py— full-run-safetytests/test_cross_language_call_resolution.py— full-run-safetytests/test_cross_repo_member_calls.py— full-run-safetytests/test_cross_repo_shared_types.py— full-run-safetytests/test_csharp_call_site_generic_args.py— full-run-safetytests/test_csharp_enum_members.py— full-run-safety- … and 220 more
non-code file(s) changed (
CHANGELOG.md,README.md,graphify/omp/package.json,pyproject.toml) → running the full suite for safety (a code graph can't see config/fixture/data deps)
changed code file(s) with no mapped test (
CHANGELOG.md,README.md,graphify/omp/package.json,pyproject.toml) — a coverage gap or a missing link — running the full suite rather than only the selected tests
Selection is safe under the controlled-regression assumption; always-run tests + a periodic full run are the backstops. Advisory — it never changes the check verdict.
Formal verification
No difference found (not proven): No behavior difference found in dispatch\_install\_cli (not a proof).
The verifier ran both versions of dispatch\_install\_cli on many inputs and saw identical behavior every time. Strong evidence the change is safe, but evidence, not a proof.
Guarantee: Empirical: differential testing (both versions run on many generated inputs). A divergence on an untested input remains possible, so this is 'no counterexample found', not 'proven equivalent'.
Note: An input the sampler did not try could still differ.
No difference found (not proven): No behavior difference found in \_run\_cli (not a proof).
The verifier ran both versions of \_run\_cli on many inputs and saw identical behavior every time. Strong evidence the change is safe, but evidence, not a proof.
Guarantee: Empirical: differential testing (both versions run on many generated inputs). A divergence on an untested input remains possible, so this is 'no counterexample found', not 'proven equivalent'.
Note: An input the sampler did not try could still differ.
· 21 more finding(s) on lines outside this diff (see the check run).
|
Triage of the refreshed automated review on
No code changes for those five. Dogfooding did find one real packaging issue: replaying the PR onto a newer Graphify release can leave |
37dd4ac to
445ee20
Compare
There was a problem hiding this comment.
Graphify reviewed this change.
Worth a look — the grounded gate found no coupling regressions or blocking issues, but 2 advisory finding(s) below merit a look before merge.
Formal verification. 2 change(s) tested, no difference found (not proven).
Graphify review — findings
Adds a native Oh My Pi guard integration exposed as graphify omp install, which delegates registration to omp plugin install on the wheel-shipped graphify/omp package directory (graphify omp path prints that directory for manual linking); it refuses unless omp is on PATH and rejects any argument other than install/path. The shipped TypeScript extension runs the installed graphify hook-guard read|search CLI before native read/glob/grep/search-bash calls, turning policy denials into OMP block/reason and guidance into a deduplicated, per-run/session context message, with in-flight hooks cancelled on session boundaries. It resolves graphify only from absolute PATH entries outside the project (no project-Python fallback), inspects local paths only, and fails open under a 256 KiB input / 64 KiB output / 2s-kill budget; omp is also added to the silent-command set so it skips the freshness warning.
Worth a look
- Read tool ignores file_path input —
graphify/omp/index.ts:79· Escalate · high- agreed by 2 of 2 members but NOT verified (no proof, no reproducing execution) — consensus is not a verdict; needs human review
- Grep break occurs after processing only first non-remote path, but expandDelimitedPathEntries may yield multiple search roots —
graphify/omp/index.ts:111· Escalate · medium- agreed by 2 of 2 members but NOT verified (no proof, no reproducing execution) — consensus is not a verdict; needs human review
Analysis details — impact, health, verification
Impact & health
Graphify review
Impact — 691 functions depend on the 418 functions this change touches.
Health — this change adds coupling hotspots:
- new:
dispatch_command()— 2 callers, 125 callees - new:
dispatch_install_cli()— 6 callers, 31 callees - new:
codebuddy_install()— 20 callers, 5 callees - new:
claude_install()— 19 callers, 4 callees - new:
_copy_skill_file()— 12 callers, 6 callees - new:
gemini_install()— 10 callers, 7 callees - new:
claude_uninstall()— 17 callers, 4 callees - new:
_project_uninstall()— 5 callers, 13 callees - …and 14 more — each is listed as a finding
Verification — 691 functions in the blast radius were not formally verified this run (proofs are advisory here).
Gate & verification
graphify gate
PASS — objectively clean (no health regressions, tests not run — proofs not run this pass (advisory)). Grounded, not self-assessed.
Advisory (not blocking):
- verification_scope: 691 function(s) in the blast radius were not formally verified this run
Test selection
Test selection
288 of 288 test file(s) selected (100%) via static blast radius.
Escalated to a full run for safety — the selection is not trustworthy on its own (see below). CI should run the whole suite.
tests/omp.test.ts— impact, changed-test, full-run-safetytests/test_affected_cli.py— impact, full-run-safetytests/test_affected_member_seed.py— full-run-safetytests/test_agents_platform.py— impact, full-run-safetytests/test_analyze.py— full-run-safetytests/test_anthropic_custom_endpoint.py— full-run-safetytests/test_antigravity_install.py— full-run-safetytests/test_apm_fallback_version.py— full-run-safetytests/test_architecture_doc.py— full-run-safetytests/test_astro_extraction.py— full-run-safetytests/test_astro_import_ids.py— full-run-safetytests/test_atomic_canvas_export.py— full-run-safetytests/test_atomic_version_stamp.py— impact, full-run-safetytests/test_atomic_writes.py— full-run-safetytests/test_backend_env_isolation.py— full-run-safetytests/test_backend_extras.py— full-run-safetytests/test_benchmark.py— full-run-safetytests/test_benchmark_raw_graph.py— full-run-safetytests/test_build.py— full-run-safetytests/test_build_merge_dedup_scope.py— full-run-safetytests/test_build_merge_hyperedges_and_prune.py— full-run-safetytests/test_build_merge_shrink_guard.py— full-run-safetytests/test_builtin_global_type_refs.py— full-run-safetytests/test_cache.py— full-run-safetytests/test_callflow_html.py— full-run-safetytests/test_cargo_introspect.py— full-run-safetytests/test_carried_hyperedge_remap.py— full-run-safetytests/test_case_sensitive_resolution.py— full-run-safetytests/test_charmap_encoding.py— full-run-safetytests/test_chunking.py— full-run-safetytests/test_cjs_module_extension.py— full-run-safetytests/test_claude_cli_backend.py— full-run-safetytests/test_claude_md.py— impact, full-run-safetytests/test_cli_broken_pipe.py— full-run-safetytests/test_cli_export.py— full-run-safetytests/test_cli_help.py— full-run-safetytests/test_cluster.py— full-run-safetytests/test_codebuddy.py— impact, full-run-safetytests/test_community_hub_labels.py— full-run-safetytests/test_community_labels_skill.py— full-run-safetytests/test_confidence.py— full-run-safetytests/test_corrupt_graph_json.py— full-run-safetytests/test_cpp_nested_and_cli.py— full-run-safetytests/test_cpp_objc_cross_file_calls.py— full-run-safetytests/test_cpp_preprocess.py— full-run-safetytests/test_cross_extension_reexport_self_cycle.py— full-run-safetytests/test_cross_language_call_resolution.py— full-run-safetytests/test_cross_repo_external_call_guards.py— full-run-safetytests/test_cross_repo_member_calls.py— full-run-safetytests/test_cross_repo_shared_types.py— full-run-safety- … and 238 more
non-code file(s) changed (
CHANGELOG.md,README.md,graphify/omp/package.json,pyproject.toml) → running the full suite for safety (a code graph can't see config/fixture/data deps)
changed code file(s) with no mapped test (
CHANGELOG.md,README.md,graphify/omp/package.json,pyproject.toml) — a coverage gap or a missing link — running the full suite rather than only the selected tests
Selection is safe under the controlled-regression assumption; always-run tests + a periodic full run are the backstops. Advisory — it never changes the check verdict.
Formal verification
No difference found (not proven): No behavior difference found in dispatch\_install\_cli (not a proof).
The verifier ran both versions of dispatch\_install\_cli on many inputs and saw identical behavior every time. Strong evidence the change is safe, but evidence, not a proof.
Guarantee: Empirical: differential testing (both versions run on many generated inputs). A divergence on an untested input remains possible, so this is 'no counterexample found', not 'proven equivalent'.
Note: An input the sampler did not try could still differ.
No difference found (not proven): No behavior difference found in \_run\_cli (not a proof).
The verifier ran both versions of \_run\_cli on many inputs and saw identical behavior every time. Strong evidence the change is safe, but evidence, not a proof.
Guarantee: Empirical: differential testing (both versions run on many generated inputs). A divergence on an untested input remains possible, so this is 'no counterexample found', not 'proven equivalent'.
Note: An input the sampler did not try could still differ.
· 22 more finding(s) on lines outside this diff (see the check run).
There was a problem hiding this comment.
Graphify reviewed this change.
Worth a look — the grounded gate found no coupling regressions or blocking issues, but 5 advisory finding(s) below merit a look before merge.
Formal verification. 2 change(s) tested, no difference found (not proven).
Graphify review — findings
Adds a native Oh My Pi guard integration installable via graphify omp install, which shells out to omp plugin install against the shipped graphify/omp package directory (omp path prints that directory for manual linking); it registers the omp subcommand in dispatch_install_cli and marks it silent so the freshness check is skipped. The shipped extension runs the existing graphify hook-guard read|search CLI before native read/glob/grep/search-bash calls, turning policy denials into OMP block/reason and guidance into a deduplicated per-run context message, inspecting only local filesystem targets with 256 KiB input / 64 KiB output caps and a two-second subprocess budget, and failing open on missing commands or bad output. Adds a CI omp-bridge job that runs tests/omp.test.ts under bun against the installed CLI, gitignores graphify/omp/node_modules/, and documents that removal goes through omp plugin uninstall graphify-omp rather than graphify uninstall.
Worth a look
- Read tool ignores file_path and guards cwd instead —
graphify/omp/index.ts:79· Escalate · high- agreed by 2 of 2 members but NOT verified (no proof, no reproducing execution) — consensus is not a verdict; needs human review
- Read/Glob guard ignores native path fields —
graphify/omp/index.ts:79· Escalate · high- agreed by 2 of 2 members but NOT verified (no proof, no reproducing execution) — consensus is not a verdict; needs human review
- Stale generation write into shared guidance set after reset —
graphify/omp/index.ts· Escalate · medium- agreed by 2 of 2 members but NOT verified (no proof, no reproducing execution) — consensus is not a verdict; needs human review
- Oversized tool input fails open —
graphify/omp/index.ts:75· Escalate · medium- agreed by 2 of 2 members but NOT verified (no proof, no reproducing execution) — consensus is not a verdict; needs human review
- GRAPHIFY_TEST_CLI can recurse after PATH is replaced —
tests/omp.test.ts:64· Escalate · medium- agreed by 2 of 2 members but NOT verified (no proof, no reproducing execution) — consensus is not a verdict; needs human review
Analysis details — impact, health, verification
Impact & health
Graphify review
Impact — 699 functions depend on the 426 functions this change touches.
Health — this change adds coupling hotspots:
- new:
dispatch_command()— 2 callers, 125 callees - new:
dispatch_install_cli()— 6 callers, 31 callees - new:
codebuddy_install()— 20 callers, 5 callees - new:
claude_install()— 19 callers, 4 callees - new:
_copy_skill_file()— 12 callers, 6 callees - new:
gemini_install()— 10 callers, 7 callees - new:
claude_uninstall()— 17 callers, 4 callees - new:
_project_uninstall()— 5 callers, 13 callees - …and 14 more — each is listed as a finding
Verification — 699 functions in the blast radius were not formally verified this run (proofs are advisory here).
Gate & verification
graphify gate
PASS — objectively clean (no health regressions, tests not run — proofs not run this pass (advisory)). Grounded, not self-assessed.
Advisory (not blocking):
- verification_scope: 699 function(s) in the blast radius were not formally verified this run
Test selection
Test selection
288 of 288 test file(s) selected (100%) via static blast radius.
Escalated to a full run for safety — the selection is not trustworthy on its own (see below). CI should run the whole suite.
tests/omp.test.ts— impact, changed-test, full-run-safetytests/test_affected_cli.py— impact, full-run-safetytests/test_affected_member_seed.py— full-run-safetytests/test_agents_platform.py— impact, full-run-safetytests/test_analyze.py— full-run-safetytests/test_anthropic_custom_endpoint.py— full-run-safetytests/test_antigravity_install.py— full-run-safetytests/test_apm_fallback_version.py— full-run-safetytests/test_architecture_doc.py— full-run-safetytests/test_astro_extraction.py— full-run-safetytests/test_astro_import_ids.py— full-run-safetytests/test_atomic_canvas_export.py— full-run-safetytests/test_atomic_version_stamp.py— impact, full-run-safetytests/test_atomic_writes.py— full-run-safetytests/test_backend_env_isolation.py— full-run-safetytests/test_backend_extras.py— full-run-safetytests/test_benchmark.py— full-run-safetytests/test_benchmark_raw_graph.py— full-run-safetytests/test_build.py— full-run-safetytests/test_build_merge_dedup_scope.py— full-run-safetytests/test_build_merge_hyperedges_and_prune.py— full-run-safetytests/test_build_merge_shrink_guard.py— full-run-safetytests/test_builtin_global_type_refs.py— full-run-safetytests/test_cache.py— full-run-safetytests/test_callflow_html.py— full-run-safetytests/test_cargo_introspect.py— full-run-safetytests/test_carried_hyperedge_remap.py— full-run-safetytests/test_case_sensitive_resolution.py— full-run-safetytests/test_charmap_encoding.py— full-run-safetytests/test_chunking.py— full-run-safetytests/test_cjs_module_extension.py— full-run-safetytests/test_claude_cli_backend.py— full-run-safetytests/test_claude_md.py— impact, full-run-safetytests/test_cli_broken_pipe.py— full-run-safetytests/test_cli_export.py— full-run-safetytests/test_cli_help.py— full-run-safetytests/test_cluster.py— full-run-safetytests/test_codebuddy.py— impact, full-run-safetytests/test_community_hub_labels.py— full-run-safetytests/test_community_labels_skill.py— full-run-safetytests/test_confidence.py— full-run-safetytests/test_corrupt_graph_json.py— full-run-safetytests/test_cpp_nested_and_cli.py— full-run-safetytests/test_cpp_objc_cross_file_calls.py— full-run-safetytests/test_cpp_preprocess.py— full-run-safetytests/test_cross_extension_reexport_self_cycle.py— full-run-safetytests/test_cross_language_call_resolution.py— full-run-safetytests/test_cross_repo_external_call_guards.py— full-run-safetytests/test_cross_repo_member_calls.py— full-run-safetytests/test_cross_repo_shared_types.py— full-run-safety- … and 238 more
non-code file(s) changed (
.github/workflows/ci.yml,.gitignore,CHANGELOG.md,README.md,graphify/omp/bun.lock…) → running the full suite for safety (a code graph can't see config/fixture/data deps)
changed code file(s) with no mapped test (
.github/workflows/ci.yml,CHANGELOG.md,README.md,graphify/omp/package.json,pyproject.toml) — a coverage gap or a missing link — running the full suite rather than only the selected tests
Selection is safe under the controlled-regression assumption; always-run tests + a periodic full run are the backstops. Advisory — it never changes the check verdict.
Formal verification
No difference found (not proven): No behavior difference found in dispatch\_install\_cli (not a proof).
The verifier ran both versions of dispatch\_install\_cli on many inputs and saw identical behavior every time. Strong evidence the change is safe, but evidence, not a proof.
Guarantee: Empirical: differential testing (both versions run on many generated inputs). A divergence on an untested input remains possible, so this is 'no counterexample found', not 'proven equivalent'.
Note: An input the sampler did not try could still differ.
No difference found (not proven): No behavior difference found in \_run\_cli (not a proof).
The verifier ran both versions of \_run\_cli on many inputs and saw identical behavior every time. Strong evidence the change is safe, but evidence, not a proof.
Guarantee: Empirical: differential testing (both versions run on many generated inputs). A divergence on an untested input remains possible, so this is 'no counterexample found', not 'proven equivalent'.
Note: An input the sampler did not try could still differ.
· 22 more finding(s) on lines outside this diff (see the check run).
Summary
Bridge Graphify's existing hook-guard policy into OMP's native tool_call/context hooks, including strict denials. Ship the extension inside the Python distribution and register it through OMP's plugin manager with graphify omp install.
Related work
Related to #1937, which adds OMP nudges on tool results. This patch targets a different runtime contract: reuse hook-guard before execution so strict denials, native grep, path selectors, and policy context actually work. It does not duplicate hardcoded tool-result guidance. There is installation/documentation overlap; happy to coordinate the landing order.
Verification
No existing project index was built or changed. OMP's isProjectTrusted() currently always returns true and is not a sandbox; docs say so. Tested host: OMP18.1.17 integration SHA6aef0e8ad51b3bc5ea7a5f2a255c3d48e4c5af72, not a promise about all published builds with that version. The installed executable policy excludes a project-local .venv; docs recommend uv tool/pipx.
AI-assisted implementation, independently reviewed for contracts, hostile input, test honesty and unnecessary complexity.