feat(omp): bridge hook-guard denials and context through native hooks - #3506
feat(omp): bridge hook-guard denials and context through native hooks#3506andrebrait wants to merge 1 commit 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).
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.