Skip to main content
← Back to list
01Issue
FeatureShippedSwamp ClubPublicEnterprise
Assigneesstack72

Relationships

#2036 Document env.* namespace for model-instance globalArguments (host-portable config)

Opened by webframp · 9/6/2026· Shipped 9/14/2026

Problem

The env.* CEL namespace works in model instance globalArguments but is undocumented in the model expression reference. This is the model-instance sibling of the datastore-layer gap fixed in #1801 — same shape ("a committed config file needs a value that varies per host/operator"), one layer up.

Concretely: a model definition YAML is committed to git, but a globalArguments value often must vary per host (e.g. an absolute filesystem path that differs between Linux /home/[REDACTED]/... and macOS /Users/[REDACTED]/...). Today the only portable option is to hardcode one host's absolute path, which breaks the moment the repo is used from another machine.

What actually works (but isn't documented)

${{ env.VAR }} in globalArguments resolves correctly at method-run time:

globalArguments:
  repo_root: ${{ env.HOME }}/src/webframp/swamp-extensions   # portable, no new var
  # or an explicit var:
  # repo_root: ${{ env.EXT_MAINT_REPO_ROOT }}

Verified on swamp 20260904.230512.0:

  • Resolves at run time, not evaluate time — consistent with the documented behavior that vault.*/env.* are "left untouched during expansion — they resolve at their own runtime/execution stage."
  • ${{ env.HOME }} + literal suffix produces a fully host-portable path with zero new environment variables — works on both macOS and Linux.
  • Missing var fails loudly and precisely, which is good:
    error: No such key: EXT_MAINT_REPO_ROOT
    path: globalArguments.repo_root
    envVar: EXT_MAINT_REPO_ROOT

The documentation gap

references/model/references/expressions.md — the "Reference Types" table lists inputs, model, file, self, data (and vault in prose) but has no mention of env. The only place env.* is documented is the workflow reference (references/workflow/references/expressions-and-foreach.md, "Environment Variables" section). A user working with model instances has no signal the namespace exists there, so relying on it feels like depending on undocumented behavior.

Requested changes

  1. Document env.* in the model expression reference — add it to the Reference Types table alongside inputs/self/data, with a host-portable path example (${{ env.HOME }}/...) and a note that it resolves at method-run time (not at model evaluate).
  2. Call out the cross-host portability pattern explicitly in the model / model create docs: prefer ${{ env.* }} over hardcoded absolute paths in committed globalArguments.
  3. (Optional) Validation / discoverability improvements:
    • Surface required env vars at create/evaluate time so an operator learns up front which host vars a model instance depends on (today model evaluate and model get show the literal ${{ env... }}, so the resolved value and the dependency aren't inspectable until a method runs).
    • Consider a model validate signal that flags committed absolute paths in globalArguments as a portability smell, nudging toward env.*.

Relationship to #1801

#1801 (shipped) added env/interpolation support at the datastore layer, which had a genuine bootstrap blocker (datastore initializes before vault resolution). Model instances have no such blocker — they run well after the environment is available, and env.* already resolves for them. So this is narrower: primarily a documentation coverage issue (make env a documented, first-class option for model-instance config), plus optional validation/discoverability niceties to help operators keep committed configs host-portable.

02Bog Flow
✓OPEN✓TRIAGED✓IN PROGRESS✓SHIPPED+ 1 MOREASSIGNED+ 2 MOREREVIEW+ 4 MOREPR_MERGED+ 2 MORESESSION_SUMMARIZED

Shipped

9/14/2026, 3:49:51 PM

Click a lifecycle step above to view its details.

03Sludge Pulse
stack72 assigned stack729/14/2026, 3:35:19 PM
Editable. Press Enter to edit.

stack72 commented 9/14/2026, 3:50:09 PM

Thanks @webframp for reporting this! The fix has been merged and a release is on its way. We appreciate your contribution to swamp.

Sign in to post a ripple.