Edition
Every deployed program carries an edition: a counter that starts at 0 and increments each time the program is upgraded. It is how the network distinguishes the code you audited from the code running now.
leo query program my_program.aleo # latest edition
leo query program my_program.aleo --edition 0 # the original deployment
Editions exist because Aleo programs can be upgradable. The constructor's annotation decides whether upgrades are possible at all, and that decision is permanent: @noupgrade freezes the code, @admin(address="aleo1...") lets one address deploy new editions, and @checksum gates upgrades on an on-chain value.
What an upgrade can change is limited. Function logic can change, and new entry points, records, structs, mappings, and storage can be added. The program ID, existing function signatures, existing struct and record definitions, and existing mapping names cannot. Neither can the constructor or its policy annotation.
For anything reading a program's behaviour programmatically, the edition is the version to record. std::ctx::edition() exposes the current edition to a running program, and std::prog::checksum() and std::prog::function_checksum() give you a content hash to compare against, which is a stronger check than a version number when you care that specific code has not changed underneath you.