Plugin tool contribution - #158
Open
jtoman wants to merge 1 commit into
Open
Conversation
jtoman
force-pushed
the
jtoman/plugin-tool-contribution
branch
from
August 13, 2026 03:41
fa4fee3 to
844fcab
Compare
ericeil
reviewed
Aug 14, 2026
| if stat == "TIMEOUT": | ||
| if len(r.children) == 0: | ||
| return [RuleResult(path=effective_path, cex_dump=None,status=stat)] | ||
| if all(r.nodeType == "SANITY" for r in r.children): |
Contributor
There was a problem hiding this comment.
Does the for r in r.children modify the existing r, or create a new scope? (You use r again on the next line)
| config + resource set (already including ``invariants.spec`` when there are | ||
| structural invariants), plus the in-memory invariant result for the report.""" | ||
| _store: ProverArtifactStore | ||
| # _store: ProverArtifactStore |
Comment on lines
+101
to
+103
| # _editing: SourceEditing | ||
| # _analysis_store: CexAnalysisStore | ||
| # _prover_options: ProverOptions |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Allows plugins to contribute tools to the formalizers of individual backends.
This accomplished in two places. First, the formalizers (not the backend) declares a
tool_provider_typefield. This field names a particular subclass ofPipelinePluginwhich provide tools for the formalizer to use. This information is used by the pipeline to construct a formalization cache key that includes the plugins that contributed to that formalization.The actual binding of tools is accomplished by pushing a
ToolBinderobject through to the formalizer. TheToolBindertakesToolExtensiontype and the "injected parameters" and returns a sequence ofProvidedTools. EachProvidedToolsobject encapsulates the Langchain tools that may be bound directly on the graph plus the system prompt blurb describing to the agent how to use said tool.Tool Discovery Details
The ToolBinder type is a polymorphic function with (roughly) the following signature:
where
Uis the usualFeatureUnitbound type parameter for the backend.**Pis a param spec type parameter; it defines the protocol for how the formalizer communicates with its plugins in a way that is opaque to the pipeline core.ToolExtensionitself is defined as a class with two fields:projecttakes an instance ofTP(the tool provider) and projects out a member function which takes, as arguments: the feature unit being formalized (represented byU), the list of properties being formalized, the "plugin tool context" (see below), and "whatever arguments are represented by P". The fixed argument prefix (U,list[PropertyFormulation], andPluginToolContext) are all injected automatically by the tool binder implementation; all the arguments represented byPare passed through from the call to theToolBinder. [1]Behind the scenes, the
ToolBinderconstructed by the pipeline core iterates all of the plugins loaded for a run, and finds those that are subclasses ofprovider, it injects the fixed prefix arguments alongside the formalization specific arguments represented byP. In addition, a special classAnyBackendallows a plugin to define tools used by anybackend; it only has the fixed prefix injected, formalization specific parameters are never passed through.The
PluginToolContexttype is the existingPluginContexttype without therunnerfield; the plugin is expected to provide its functionality through tools, which should not be spawned as top-level multi-job tasks. In addition, we provide aregisterfield of typeArtifactRegistrar. This lets plugins communicate unstructured "verification artifacts" back to the main pipeline. These artifacts are included in the main report as side information.Tool Usage
In practice, the expected shape of communication between a plugin and the formalizer are two parameters, the actual runtime representation of the author's state type, and a projector function, which takes an instance of the state and yields a slice of the state used by the author.
For example, the
CertoraProverToolapi provides the plugin tools withtype[SourceCVLGenerationState]and(SourceCVLGenerationState) -> AsyncContextManager[CVLAuthorState].CVLAuthorStatecontains, among other things:It is strongly recommended (but not enforced) that formalizers handle provisioning of abstractions for accessing the utilities they themselves access through tools (e.g., running the prover) instead of passing through the raw building blocks to access those utilities themselves. For example, in the prover runner case above, passing through the data necessary for the plugin to run the prover "from scratch" would require passing the
ProverOptionsthe "config overlay" (the basic config elaboration performed by the author's prover tool), the current configuration (already passed), and require the plugin to know how to piece all that together. All of this together would create a far greater API surface with which to maintain BC for the plugins (e.g., don't rename theprover_config_overlayfunction because some random plugin might need it). In other words, use this projector function pattern to push functionality to the plugins, instead of making them pull in random pieces of code from the rest of the AP codebase.Parallelization
To support long running tools, we've added a
TaskHostabstraction, which can be used to launch background tasks that run in parallel with the main agent. It is expected this will be used to allow plugins to doe their work as background tasks. The main formalization agent can use the task management tools to query background task state and to wait for/retrieve results.Prover Tools
The other "big" piece of this PR is enabling plugins for the Certora Prover tool to propose edits to the source code under verification. This could be useful to, e.g., write a plugin that addresses PTA failures due to inline assembly, or to use Concord to make verified large scale rewrites beyond what the code editor agent is empowered to do. These edits are proposed and committed using the existing edit store infrastructure. However, we extend the edit store to record the provenance of edits; the existing editor is called "MungeAgent", edits from plugins are tagged with their id (this tagging is handled automatically; the plugins cannot lie about their id).
On Testing
I have proven this code correct, but I haven't yet tested it [2]. I am sharing it here because its in its mostly final state; I plan to do a big test run in parallel with the review process.
[1] There is a second form which takes an
InjectedToolExtension, which allows thePpart of the plugin to know about the plugin id it is requesting. Don't think too hard about it, it makes your head hurt.[2] I haven't actually proved it correct either