diff --git a/10-core/app-spec.md b/10-core/app-spec.md index 00d517cd9..b4da37435 100644 --- a/10-core/app-spec.md +++ b/10-core/app-spec.md @@ -1061,6 +1061,20 @@ One class of command is different: those that run **caller-supplied logic** whos The author taking responsibility for an `exec` script's mode is the only authority that exists — no manifest can inspect an arbitrary script. This resolves issue #165: a read-only host-`exec` app is no longer mislabeled write-mode or forced to declare a bogus `safety:` block. +Not every `exec` is overridable. `blender`'s `exec` (#692) is fixed `mode: write` with no override, because a read-mode node runs for real under `--dry-run` and a preview must never render an animation. + +#### Literal inputs (`literal: true`) + +An input a command runs as a program — an `exec` command's `code` — must be pinned by the approval, and the `.lock` hashes the app source, not what a template later resolves to. A `code: '{{ inputs.code }}'` would run Python supplied after a person approved the lock. So an agent manifest may declare an input **`literal: true`**: + +```yaml +inputs: + code: { type: string, required: true, literal: true } + args: { type: object } # data: still templatable +``` + +A node that gives a literal input any template syntax (`{{ }}`, `{% %}`, `{# #}`) is refused with **`E_APP_INPUT_MUST_BE_LITERAL`**, naming the node and the input, by `aware app validate`, by the lock compiler, and by the runtime. The runtime check reads the node's merged, **un-rendered** value before any template is rendered, so a lock produced by an older compiler cannot smuggle one through either. Pass run-time data through a templatable input (`args`) instead. Today only `blender`'s `exec.code` is literal; the other host `exec` commands adopting it is tracked separately (#693). + ### The block ```yaml diff --git a/20-agents/aeco/visualization/blender/manifest.yaml b/20-agents/aeco/visualization/blender/manifest.yaml index a7b289b0b..a16571a66 100644 --- a/20-agents/aeco/visualization/blender/manifest.yaml +++ b/20-agents/aeco/visualization/blender/manifest.yaml @@ -1,5 +1,5 @@ agent: blender -version: 0.1.0 +version: 0.2.0 display-name: Blender description: | The first visualization agent in the substrate that renders with NO human in @@ -12,6 +12,11 @@ description: | renderers in the box (EEVEE for drafts and turntables, Cycles for path-traced hero shots). + Beyond the fixed recipes, `exec` runs author-time `bpy` code -- a construction + sequence, a fly-through, a sun study -- written once when the workflow is + authored, pinned in the approved lock, and run unchanged on every run. Long + renders report per-frame progress while they work. + Materials are assigned from what the IFC already states: product class plus associated material grade, with clay as a never-fail default. That is what makes the chain autonomous — nobody is there to click a material. @@ -44,6 +49,10 @@ requires: filesystem: - read: '*.ifc,*.blend' - write: '*.blend,*.png,*.mp4' + # `exec` runs author code that writes its renders into `output-dir`. Like + # tekla/rhino exec, Python writes are not sandboxed, so this is declared as + # broadly as it is -- the contract a person approves with the lock. + - write: any # `exec` only # Runtime built-in: the transport runs in-process in the `aware` runtime, spawning # `blender -b -P