Contract versioning
The interface between para and a project is versioned. It covers everything a project's .paraspace/ directory depends on:
- the environment para injects,
- the hook names and semantics,
- the
~/.paraspacelayout in the guest, - the env file keys,
- the
.paraspace/stackfile format, - the project-command mechanism,
- bundled layer entry points and
$PARA_HELPERSfunctions.
para implements contract version 1. Contract versions are integers and must match exactly; ranges and semver strings are not supported.
para init writes the pin into the scaffolded env file:
PARA_CONTRACT=1Hooks receive it as an environment variable. Update it when you migrate your .paraspace/ to a new contract.
If the versions don't match, para stops with an error. Projects without a declared version still run, but para doctor suggests adding one.
The rules:
- A breaking change to the interface bumps
PARA_CONTRACTby one. - Additive changes (a new variable, a new optional key) don't.
- A project bumps its own
PARA_CONTRACTwhen it migrates its.paraspace/. - There is no range syntax and no compatibility window: one integer, compared for equality.
Before 1.0
para is 0.x and contract 1 is not frozen. A change that breaks a .paraspace/ lands in contract 1 rather than bumping it, and there is no migration log of those breaking changes.
Bundled layer code lives under node_modules/paraspace/ and is pinned by the project's lockfile. A project that declares paraspace as a devDependency keeps working until it chooses to update. To see what changed in the bundled layers between two versions, run:
npm diff --diff=paraspace@0.2.0 --diff=paraspace@0.3.0A globally installed parahands the invocation to the project's own copy, so the version the lockfile pins is the one that runs and the global version does not need to match.
At 1.0 the contract freezes, and anything that breaks a .paraspace/ bumps the number instead.