Problem
aware app run executes edited installed source even when the existing compiled .lock still carries the previous source hash and a different command. This breaks the documented approved-source/lock Run contract and is a release blocker for FloLess project-owned workflow publication.
Verified against exact fetched default branch 9265ebb228c3fddcdff226982aae991d6b5ee77f, built locally as aware 0.134.0 with cargo build --offline --locked on Windows. No simulation or external service was used: the workflow called the installed builtin ui agent only, under a fresh isolated AWARE_HOME.
Reproduction
- Use an isolated AWARE_HOME. Install the local
_core/ui agent from this checkout.
- Create this
chat-storage-probe.flo in an otherwise empty source directory:
app: chat-storage-probe
version: 0.1.0
description: A harmless local catalogue probe for storage verification.
requires:
- ui@1.0.0
nodes:
- id: catalog
agent: ui
command: catalog
mode: read
description: Read the installed built-in UI catalogue without external services.
aware app compile <source-dir>/chat-storage-probe.flo
aware app install <source-dir>
aware app run chat-storage-probe --json succeeds, as expected.
- In the installed
<AWARE_HOME>/apps/chat-storage-probe/chat-storage-probe.flo, change command: catalog to:
command: validate
config:
descriptor: {}
- Leave
<AWARE_HOME>/apps/chat-storage-probe/chat-storage-probe.lock untouched. Run aware app run chat-storage-probe --json again.
Observed
Exit 0, run complete. The trace proves the changed command actually executed:
{"kind":"node-start","node":"catalog","agent":"ui","command":"validate"}
{"kind":"node-output","node":"catalog","data":{"valid":false,"errors":["version: missing required field (must be 1)","panels: missing required field (an array of panels)"],"warnings":[],"schema-version":"1"}}
{"kind":"run-end","status":"ok"}
The trace above is reduced to relevant fields. The installed directory contained exactly one source .flo, the compiled .lock, and install-time lockfile.yaml; this was not an edit of the separate original authoring directory or an ambiguous source selection.
The stored source hash was sha256:883d2aeaee1e0546b78099f584134eaf46289de8248ce56522dfd8d635c4d679; current installed-source SHA256 was 18d5c6f8db5cb37a26a441b10be756e89cbc0f681d611f624c3b7f6a59a2b821; compiled lock bytes remained unchanged. This measured reproduction also included harmless appended comment lines from the preceding byte-drift probe; both byte-only drift and the semantic command change were accepted.
Expected
A real Run with a compiled approval artifact must refuse source-hash mismatch before any node dispatch, requesting compile/approval again. It must not execute the altered source while the previous lock remains approved. Define behavior for a missing lock explicitly too; do not silently weaken the approved-artifact contract.
Code evidence / related context
At the pinned commit, cli/src/commands/app.rs:227-237 resolves the installed app directory, finds its manifest and loads source with load_app; the run entry does not validate the compiled lock source hash. cli/src/app_lock.rs:190-196 computes the lock hash from raw source bytes. Thus ignoring the mismatch is not canonical YAML/comment normalization.
Related area: #106 deterministic app build pipeline. No fix is included here. FloLess must independently gate authoring source versus its derived installed publication, but that extra gate does not replace AWARE enforcing its own installed source/lock contract.
Problem
aware app runexecutes edited installed source even when the existing compiled.lockstill carries the previous source hash and a different command. This breaks the documented approved-source/lock Run contract and is a release blocker for FloLess project-owned workflow publication.Verified against exact fetched default branch
9265ebb228c3fddcdff226982aae991d6b5ee77f, built locally asaware 0.134.0withcargo build --offline --lockedon Windows. No simulation or external service was used: the workflow called the installed builtinuiagent only, under a fresh isolated AWARE_HOME.Reproduction
_core/uiagent from this checkout.chat-storage-probe.floin an otherwise empty source directory:aware app compile <source-dir>/chat-storage-probe.floaware app install <source-dir>aware app run chat-storage-probe --jsonsucceeds, as expected.<AWARE_HOME>/apps/chat-storage-probe/chat-storage-probe.flo, changecommand: catalogto:<AWARE_HOME>/apps/chat-storage-probe/chat-storage-probe.lockuntouched. Runaware app run chat-storage-probe --jsonagain.Observed
Exit 0,
run complete. The trace proves the changed command actually executed:{"kind":"node-start","node":"catalog","agent":"ui","command":"validate"} {"kind":"node-output","node":"catalog","data":{"valid":false,"errors":["version: missing required field (must be 1)","panels: missing required field (an array of panels)"],"warnings":[],"schema-version":"1"}} {"kind":"run-end","status":"ok"}The trace above is reduced to relevant fields. The installed directory contained exactly one source
.flo, the compiled.lock, and install-timelockfile.yaml; this was not an edit of the separate original authoring directory or an ambiguous source selection.The stored source hash was
sha256:883d2aeaee1e0546b78099f584134eaf46289de8248ce56522dfd8d635c4d679; current installed-source SHA256 was18d5c6f8db5cb37a26a441b10be756e89cbc0f681d611f624c3b7f6a59a2b821; compiled lock bytes remained unchanged. This measured reproduction also included harmless appended comment lines from the preceding byte-drift probe; both byte-only drift and the semantic command change were accepted.Expected
A real Run with a compiled approval artifact must refuse source-hash mismatch before any node dispatch, requesting compile/approval again. It must not execute the altered source while the previous lock remains approved. Define behavior for a missing lock explicitly too; do not silently weaken the approved-artifact contract.
Code evidence / related context
At the pinned commit,
cli/src/commands/app.rs:227-237resolves the installed app directory, finds its manifest and loads source withload_app; the run entry does not validate the compiled lock source hash.cli/src/app_lock.rs:190-196computes the lock hash from raw source bytes. Thus ignoring the mismatch is not canonical YAML/comment normalization.Related area: #106 deterministic app build pipeline. No fix is included here. FloLess must independently gate authoring source versus its derived installed publication, but that extra gate does not replace AWARE enforcing its own installed source/lock contract.