Skip to content

Code editor - #72

Open
jtoman wants to merge 16 commits into
masterfrom
jtoman/code-munger
Open

Code editor#72
jtoman wants to merge 16 commits into
masterfrom
jtoman/code-munger

Conversation

@jtoman

@jtoman jtoman commented Jul 14, 2026

Copy link
Copy Markdown
Contributor

Prototype for editor agent to allow the cvl author to request (limited) changes to the source code to work around prover limitations (unstructured/custom storage, refactoring, etc.)

Gated with a judge agent as usual.

@jtoman
jtoman marked this pull request as ready for review July 17, 2026 05:10
@jtoman
jtoman requested a review from shellygr July 17, 2026 05:11

@shellygr shellygr left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do we include edits in the final report? I missed it here


result, stdout = await run_prover_inner(
folder,
[_CONF_NAME, "--build_only"],

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do you want to go further and use --compilation_steps_only to make sure the changes are compatible with the spec? or is that handled elsewhere?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oh that's a great point, if we change a storage layout that the spec is directly accessing.

But now that I'm thinking it through; the editor can't change the spec. If we gate completion on "the spec still works", the editor can't propose changes that break the spec, even if the author fully intends to fix the spec in response. The agent being able to rollback its edits are the defense against the editor agent completely borking the spec.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fair enough


Decide whether anything in the diff contradicts or outdates the answer. If every claim the answer makes still holds against the changed source, it is still valid. If the diff changes something the answer depends on — a moved or renamed symbol, altered control flow, a removed branch, a changed signature — it is no longer valid, and you say in one sentence what changed.

Edits are usually small and surgical, so most findings are unaffected; mark a finding invalid only when the diff actually touches what the answer relies on."""

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is it given the original or current version? some changes could look local but they are not.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it is shown the diff. And you're right, a change in foo() may or may not be relevant to gorp, depending on whether bar() (called by gorp) itself calls foo.

I think I will make this prompt pessimistic to account for this wrinkle. Ugh, of course it wasn't easy.

edit_store: EditStore,
sc: SourceCode,
) -> MigrationOracle:
"""Build a :class:`MigrationOracle` that decides, in one LLM call, whether a

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

as above, point for future review - not sure it's a one-shot call

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why wouldn't it be? it's operating on raw BaseChatModel with ainvoke; we aren't calling a graph.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I meant that maybe it's better to allow for calling a graph?

Comment thread composer/spec/source/munge/munge_agent.py
Comment on lines +463 to +464
# "commit_edit" is the name the editor's result message tells the author
# to call (see EditMungeTool.run's result_msg) — keep them in sync.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤔
isn't there a less fragile way to maintain this?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure what I follow; what fragility are you foreseeing here? The alternative is to have the edit agent make direct edits to the author's state (bad) or provide a way for the author agent to say directly what edits to apply, but that's just a backdoor to synthesize edits without the edit author. Having agents communicate results between each other with keyed ids is pretty effectively used elsewhere, and is both economical token wise and the only way to make sure an agent doesn't misrepresent or garble results.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I meant the tool names; if those are so stable we can afford keeping them constant strings that's fine

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oh oh oh, yes, let's make those constants.

Comment thread composer/templates/munge_editor_system.j2
Comment thread composer/templates/munge_feedback_system.j2
Comment thread composer/templates/munge_feedback_system.j2

## Do Not Reject For

- Incidental overflow reverts from ordinary checked Solidity math in new code. These are expected

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

so solidity to solidity new reverts due to math are okay but assembly/unchecked to checked solidity is not

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah exactly. If somehow one plus turns into two, I don't want a munge getting rejected with "YOU ADDED A REVERT".

Comment thread composer/templates/property_generation_system_prompt.j2
Comment on lines +463 to +464
# "commit_edit" is the name the editor's result message tells the author
# to call (see EditMungeTool.run's result_msg) — keep them in sync.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure what I follow; what fragility are you foreseeing here? The alternative is to have the edit agent make direct edits to the author's state (bad) or provide a way for the author agent to say directly what edits to apply, but that's just a backdoor to synthesize edits without the edit author. Having agents communicate results between each other with keyed ids is pretty effectively used elsewhere, and is both economical token wise and the only way to make sure an agent doesn't misrepresent or garble results.


result, stdout = await run_prover_inner(
folder,
[_CONF_NAME, "--build_only"],

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oh that's a great point, if we change a storage layout that the spec is directly accessing.

But now that I'm thinking it through; the editor can't change the spec. If we gate completion on "the spec still works", the editor can't propose changes that break the spec, even if the author fully intends to fix the spec in response. The agent being able to rollback its edits are the defense against the editor agent completely borking the spec.


Decide whether anything in the diff contradicts or outdates the answer. If every claim the answer makes still holds against the changed source, it is still valid. If the diff changes something the answer depends on — a moved or renamed symbol, altered control flow, a removed branch, a changed signature — it is no longer valid, and you say in one sentence what changed.

Edits are usually small and surgical, so most findings are unaffected; mark a finding invalid only when the diff actually touches what the answer relies on."""

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it is shown the diff. And you're right, a change in foo() may or may not be relevant to gorp, depending on whether bar() (called by gorp) itself calls foo.

I think I will make this prompt pessimistic to account for this wrinkle. Ugh, of course it wasn't easy.

Comment thread composer/spec/source/munge/munge_agent.py
edit_store: EditStore,
sc: SourceCode,
) -> MigrationOracle:
"""Build a :class:`MigrationOracle` that decides, in one LLM call, whether a

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why wouldn't it be? it's operating on raw BaseChatModel with ainvoke; we aren't calling a graph.

Comment thread composer/templates/munge_charter.j2
Comment thread composer/templates/munge_editor_system.j2

## Do Not Reject For

- Incidental overflow reverts from ordinary checked Solidity math in new code. These are expected

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah exactly. If somehow one plus turns into two, I don't want a munge getting rejected with "YOU ADDED A REVERT".

Comment thread composer/templates/property_generation_system_prompt.j2
tool_call_id=tool_call_id, content=result.result_str,
prover_link=result.link, validations=stamper(state),
prover_link=result.link,
validations=stamper(state, state["version_history"]),

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is where we include the version history (which implicitly includes the vfs).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants