runtime+prompt: content verbs read stdin OR arg; content travels in the program#23
Merged
Merged
Conversation
…he program
Backend portability principle: on temporal a program runs on an arbitrary
remote worker, so it cannot read local files — only the data passed in
(stdin) and out (stdout) crosses that boundary. A pipeline must therefore
carry its content as values, not reach into ambient local state. The same
program must run unchanged on memory and temporal.
This makes the content verbs echo-like (stdin OR arg) so pasted content
travels in the program:
runtime (internal/agentscript/runtime.go):
- summarize: was input-ONLY — it ignored its arg, so summarize "text"
summarized empty input (the bug seen live in Slack). Now: use piped
input if present, else the arg; error clearly if neither.
- analyze: if there's no piped input, treat the arg as the content
(not only the focus), so analyze "text" works standalone.
- (ask already did arg + optional stdin context — left as the model.)
prompt (pkg/script/translate.go):
- New PASSING CONTENT section: put pasted text directly in the
command's quoted argument; do NOT use a file path or read for pasted
content — content travels in the argument so the program is portable
across backends.
Effect: '@loom in memory: summarize <pasted text>' now translates to
memory static ( summarize "<pasted text>" ) and runs in-process on
Claude Code, returning a real summary — and the identical program is
valid on temporal later (content is a value, not a local file).
Verified: summarize "text" and (stdin >=> summarize) both reach the LLM
with content (sandbox lacks the claude binary, which is why they stop
there — proving the route). No file/local-state dependency.
CI: vet, gofmt, staticcheck, go test ./pkg/..., build pass.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The principle (your point about temporal portability)
On temporal a program runs on an arbitrary remote worker — it cannot read local files; only data passed in (stdin) and out (stdout) crosses that boundary. So a pipeline must carry its content as values, not reach into ambient local state (
read "/tmp/x"). The same program must run unchanged on memory and temporal —read "localfile"violates that; stdin/arg content does not.This makes the content verbs echo-like (stdin OR arg) so pasted content travels in the program.
The bug this fixes (seen live in Slack)
@loom in memory: summarize "..."returned 'no content was included' — becausesummarizewas input-only: it ignored its arg and summarized empty upstream input.Changes
runtime (
internal/agentscript/runtime.go):summarize: use piped input if present, else the arg; clear error if neitheranalyze: no piped input → treat the arg as content (not just the focus)askalready did arg + optional stdin context — kept as the model)prompt (
pkg/script/translate.go):readfor pasted content — content travels in the argument so the program is portable across backendsEffect
@loom in memory: summarize <pasted text>→memory static ( summarize "<pasted text>" )→ runs in-process on Claude Code → real summary. The identical program is valid on temporal later (content is a value, not a local file).Verified
summarize "text"andstdin >=> summarizeboth reach the LLM with content (sandbox lacks theclaudebinary — proving the route). No local-state dependency.go test ./pkg/...