Skip to content

engine: protobuf ProjectPatch/ModelPatch/ModelOperation messages are dead schema #538

Description

@bpowers

Problem

src/simlin-engine/src/project_io.proto (lines 402-459) defines a family of patch messages:

  • ProjectPatch { project_ops, models }
  • ModelPatch { name, ops }
  • ProjectOperation (oneof: SetSimSpecsOp, SetSourceOp)
  • ModelOperation (oneof: UpsertStockOp, UpsertFlowOp, UpsertAuxOp, UpsertModuleOp, DeleteVariableOp, RenameVariableOp, UpsertViewOp, DeleteViewOp, UpdateStockFlowsOp)
  • the associated *Op payload messages (UpsertModuleOp, etc.)

These compile to prost types in src/simlin-engine/src/project_io.gen.rs (ProjectPatch at line 819, ModelOperation at 848, UpsertModuleOp at 908).

No Rust code references the prost-generated patch types. A repo-wide grep for project_io::ProjectPatch / project_io::ModelPatch / project_io::ModelOperation / project_io::UpsertModuleOp returns zero matches, and src/simlin-engine/src/serde.rs has no conversion functions for them.

The actually-exercised patch path is JSON-only and uses a separate, hand-written native type that is unrelated to protobuf:

  • src/simlin-engine/src/patch.rs defines a native ProjectPatch / ModelPatch / ModelOperation (plain Rust structs/enums over datamodel::*, not prost-derived).
  • src/libsimlin/src/patch.rs defines JsonProjectPatch / JsonModelOperation (serde) and converts them to the native engine::ProjectPatch via convert_json_project_patch / convert_json_model_operation, called from the simlin_project_apply_patch FFI entry point.
  • src/simlin-mcp-core/src/tools/edit_model.rs likewise builds the native simlin_engine::ProjectPatch directly.

So there are two same-named-but-unrelated ProjectPatch families, and the protobuf one is dead: it has a generated Rust type but no conversion path and no caller.

Why it matters

  • Maintainability / latent inconsistency: a contributor extending the patch surface (e.g. for Vensim macro support, where this was discovered) reasonably assumes project_io.proto is the source of truth and may add proto messages that are never wired up — or may not realize the proto definitions exist and are stale.
  • Protobuf versioning discipline: the repo treats project_io.proto as a versioned wire format (there is a DB of serialized instances). Carrying dead patch messages in that file muddies which messages are actually load-bearing.
  • It is either (a) genuinely dead schema that should be deleted, or (b) an intended-but-never-implemented proto patch path. Either way the current state is undocumented and confusing.

Component(s) affected

  • src/simlin-engine/src/project_io.proto
  • src/simlin-engine/src/project_io.gen.rs (generated)
  • (contrast with the live path: src/simlin-engine/src/patch.rs, src/libsimlin/src/patch.rs, src/simlin-mcp-core/src/tools/edit_model.rs)

Possible approaches

  1. Delete the dead messages from project_io.proto (ProjectPatch, ModelPatch, ProjectOperation, ModelOperation, and the *Op payload messages that are not used elsewhere) and regenerate. Since these messages are never serialized to the DB (only Project is), removing them is wire-safe. Verify each *Op's inner payload message isn't shared with a live message before deleting.
  2. Or decide proto is meant to be the patch wire format, and implement the project_io <-> patch.rs conversion in serde.rs plus a proto FFI entry, retiring the bespoke JsonProjectPatch in libsimlin. This is the larger change and should only happen if there's a real need for a binary patch format.

Given the JSON path is the one with full FFI + MCP coverage, option 1 (delete) is the likely answer, but the choice should be made deliberately.

Discovery context

Identified during a codebase investigation for Vensim macro support; out of scope for that work.

Activity

  1. added
    engineIssues with the rust-based simulation engine
    hygieneToil, but its useful to get get too behind on it
    on Jun 8, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    engineIssues with the rust-based simulation enginehygieneToil, but its useful to get get too behind on it

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions