Conversation
Replace the long security-detail bullets with six human-facing headlines; All changes keeps the full technical record. Co-authored-by: Cursor <cursoragent@cursor.com>
Jaiph is the language and orchestrator, not a sandbox product. Isolation stays an outer wrap (container, pod, CI). Co-authored-by: Cursor <cursoragent@cursor.com>
…exports One interpreted callable (`def`); jaiph run requires export def main. Journal, hooks, HTTP, and telemetry drop the workflow noun (RUN_START, /v1/defs, jaiph.def). Co-authored-by: Cursor <cursoragent@cursor.com>
The live tree prints kind and name, not the source modifier. Fixtures that call across import or serve/MCP now mark those names export under private-by-default. Co-authored-by: Cursor <cursoragent@cursor.com>
…/first-run Co-authored-by: Cursor <cursoragent@cursor.com>
Send is a step (`send <payload> -> channel`). Routes stay on the channel line. Handlers take 1 to 3 parameters. Co-authored-by: Cursor <cursoragent@cursor.com>
Landing and 110_examples still expected 3-param banners and log lines the example no longer emits. Co-authored-by: Cursor <cursoragent@cursor.com>
The homepage was a language-reference dump. Replace it with short copy, MCP/HTTP/first-run cards, and a single Windows switch. Surrounding how-to pages get matching titles and tighter prose. Co-authored-by: Cursor <cursoragent@cursor.com>
Pages still described the old minisign fallback, serve JSON shapes, and run-async/script rules. Align them with the code, and surface --allow-unpinned in jaiph use --help. Co-authored-by: Cursor <cursoragent@cursor.com>
The sandbox is gone (00b4623); these comments and test names still described container mounts, docker force-remove, and container-stop hooks that no longer exist. e2e/ensure_fail.jh was an unreferenced fossil (tests write their own copy via e2e::file) and its transpile output line leaves .gitignore with it. Behavior unchanged. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Follow-through on d72101a ("the public noun is def / run"): docs, landing-page sample trees, CLI hints, and parser/validator error messages now say def / run / program instead of workflow. Renames the operator-log mirror opt-in JAIPH_SERVER_LOG_WORKFLOW to JAIPH_SERVER_LOG_RUNS (hard rename, no fallback) and refreshes the parse/validate snapshots plus embedded jaiph-skill assets. Also fixes the grammar.md heading anchor: the stacked legacy IAL made kramdown emit #workflow-body-statements and drop #def-body-statements. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The Summary led with the language change only; the sandbox removal is the bigger operational break for anyone deploying, so it gets its own Summary bullet with the what-to-do-instead pointer (wrap jaiph in your own container — docs/deploy.md). Also records the JAIPH_SERVER_LOG_RUNS rename under Run contracts. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Add three #dev-ready QUEUE.md tasks for fail-closed script env with definition-site `use` and `--env` as the only grant, named prompts, and nested script/prompt/def. Point the engineer implement prompt at fable. Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Script and run subprocesses no longer inherit the runner's full host
environment. Every named, imported, and inline script now spawns with a
sterile env: the prompt base env names/prefixes, the runtime contract
keys (JAIPH_WORKSPACE, JAIPH_SCRIPTS, JAIPH_RUN_DIR, JAIPH_ARTIFACTS_DIR),
and only the host keys a script requests via a new `use` clause.
A script declaration may name host keys with `use IDENT { IDENT }` after
the script name (and after the `as` alias for `import script`), before
the `=`. A `use` key reaches the script only when it is also passed as
`--env KEY` or `--env KEY=VALUE`; presence on the host env alone is not
enough. `jaiph run`, `serve`, and `mcp` preflight the whole import graph
and fail with E_ENV_MISSING for any `use` key not passed via `--env`;
`jaiph test` injects passed keys but does not hard-fail on missing ones.
Removes `trusted_envs` entirely — parse, metadata, planning, runtime
injection, docs, and tests — in favor of the sterile default plus
`use` + `--env`. Prompts remain fail-closed on scrubPromptEnv. Docs
(grammar, language, jaiph-skill, configuration, cli, env-vars) updated.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Add a module-level `prompt IDENT(params) [use KEY...] = rhs` definition
in the same namespace as script/def/const/channels, with an optional
`returns` schema and `export` support. Named prompts are invoked with
parentheses (`prompt foo(a)` or `const x = prompt foo("hi")`), while the
existing bare `prompt IDENT` identifier-as-body form is preserved.
The `use` clause injects host keys into the invoking agent subprocess on
top of scrubPromptEnv, reusing the script `use` grammar and reserved-key
rules; anonymous `prompt "..."` / `prompt """..."""` stay sterile and
gain no `--env` secrets. Named-prompt `use` keys join the import-graph
use set, so run/serve/mcp preflight requires each on `--env` (test does
not hard-fail). Arity mismatches and `run foo()` on a named prompt are
E_VALIDATE. Grammar, language, and skill docs updated.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Allow a def body to declare nested const, script, named prompt, and def alongside const steps, sharing one sequential local namespace with the def's parameters. Nested names are visible only after their declaration and only within the enclosing def; they may shadow module-level bindings of the same name but not the def's parameters. export, config, import, and channel are rejected on nested declarations (E_PARSE). Nested defs and named prompts are interpreted in-process and interpolate the enclosing scope's params and consts at runtime; nested scripts remain subprocesses with a sterile env, their own use clause, and --env grant, receiving enclosing bindings only via explicit argv. Nested scripts emit as script files with stable unique names. Docs, grammar, and e2e coverage updated accordingly.
The sterile script env left import script gh without `use`, so overnight CI-wait defs start then fail in require-token. Declare use on that library import, point the engineer implement prompt at fable, and queue the remaining env/prompt gaps as one #dev-ready task for fable. Co-authored-by: Cursor <cursoragent@cursor.com>
Shell-fallthrough def lines now spawn with the same sterile env as
inline scripts instead of inheriting the full runner env, so bare
lines like echo "$GITHUB_TOKEN" can no longer read granted or
kernel keys. Thread named-prompt use env into the Codex backend so
codex agents honor use the same way Cursor/Claude/custom already do.
Reject nested import / import script and config { inside any nested
def body as E_PARSE rather than silently turning them into shell.
Drop JAIPH_ENV_GRANT in scrubPromptEnv so it no longer reaches prompt
agents. Replace the raw NUL separator in planUseEnvs dedupe keys with
a printable separator so git treats use-envs.ts as text. Add a
cross-module use spawn test proving run lib.publish() carries the
imported script's use key into the child env.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
parseAttachedBlock dropped inNestedDef, so those lines still became sh -c. Thread the flag through every attached-block path. Point the engineer implement prompt at opus. Co-authored-by: Cursor <cursoragent@cursor.com>
VS Code, Zed, and the docs highlighter now color the use clause, import script, and named prompt forms. trusted_envs is no longer treated as a live config key. Co-authored-by: Cursor <cursoragent@cursor.com>
Move the Unreleased language rewrite into 0.14.0 and bump the CLI, installers, and editor plugins to match. Co-authored-by: Cursor <cursoragent@cursor.com>
A bare --env KEY with no host value now names the key and the two ways to pass it. Co-authored-by: Cursor <cursoragent@cursor.com>
…time
Nested decls compiled, but ${…} in nested consts/prompts (including triple-quoted bodies) and nested-script emit names were untested.
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Close the use/--env hole on JAIPH_CHAIN_KEY and JAIPH_RUN_SUMMARY_FILE, add the operator async how-to, and pin the handle/named-prompt cases the 0.14.0 review found missing. Co-authored-by: Cursor <cursoragent@cursor.com>
Task 2 must support in-branch script/def/prompt/const and reject use after the body, with parse, validate, and runtime tests for if/else/for/catch/recover. Co-authored-by: Cursor <cursoragent@cursor.com>
State the dedicated-user / two-run recipe and queue constructing the runner env so host keys are not copied onto the process by default. Co-authored-by: Cursor <cursoragent@cursor.com>
A `const` referenced before its declaration now raises `E_VALIDATE`
(unknown identifier) instead of compiling and interpolating empty at
runtime. This closes the gap where `walkStepTree` added every `const`
name to the def-wide `knownVars` set, making a forward reference in a
`${…}` interpolation, a bare `run`/`prompt` call argument, or an
`if`/`match` subject silently valid.
Sequential visibility is now tracked the same way `localsSoFar` gates
nested decls: a new `seqConstVisibility` helper exposes the visible
`knownVars` (full set minus not-yet-declared consts) and the forward
consts at each step, and the validator snapshots the visible set at each
nested `def`/`prompt` declaration point so an enclosing const declared
after the nested body is not in scope (forward-const TDZ). Params and
module-level consts stay visible; runtime interpolation of a missing var
is unchanged. The `walkStepTree` descent is extracted to
`validate-step-tree.ts` and now also returns `constNames`.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Nested `script` / `def` / named `prompt` / `const` declared inside an
`if` / `else` / `else if` / `for` / `catch` / `recover` body are now
visible only within that declaring body and only after their
declaration, matching the sequential rule already used for top-of-def
locals. Previously `validateDefTree` hoisted every `local_decl` into a
def-wide `localsSoFar`, so a name declared only inside a branch was
treated as visible after the branch — validating fine but failing at
runtime when the branch was not taken.
Each body is its own lexical scope: sibling branches declaring the same
name are independent locals (not a rebind), and a branch may shadow an
enclosing def or module binding for the rest of that body only. A
`run` / `prompt` / `${name}` / bare-arg reference to a name after its
declaring body has closed is now `E_VALIDATE`. The recursive descent is
extracted from `validate.ts` into `validate-def-scope.ts` (replacing
`validate-step-tree.ts`), and `localPromptReturnsResolver` uses the same
visible set so `${r.field}` on a `returns` prompt is legal only where
the capture is in scope.
Runtime no longer silently returns empty/status 1 on a missing name;
validation rejects the miss-after-branch cases before they can run.
Docs updated: docs/language.md Nested declarations documents that
in-branch decls are allowed and scoped to the declaring body.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
When validating a nested `def`'s body, add the def's own name to the local
map so self-recursion resolves. `def fact(n) { … return run fact(m) }` now
compiles and, with a base case, returns the computed value; a runaway
self-recursion hits the existing recursion-depth cap (256) rather than the
pre-fix unknown-local failure.
Only the def's own name is added — later sibling nested defs are still not
hoisted, so `def a() { run b() }` before `def b` stays E_VALIDATE (unknown
local). Docs under Nested declarations, the grammar reference, and the jaiph
skill note the self-recursion allowance and the sibling-forward-ref rejection.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
A stored Claude CLI login is enough; the env-var warning existed for Docker. Co-authored-by: Cursor <cursoragent@cursor.com>
Close three editor-plugin highlighting gaps left after the 0.14.0 review
across the VS Code TextMate grammar and the Zed Tree-sitter grammar. A
named prompt call site `prompt name(...)` now scopes the callee `name` as
`entity.name.function.prompt` (VS Code) / `@function` (Zed), not just the
`prompt` keyword. A dotted `if` / `else if` subject such as `answer.risk`
in `if answer.risk == "ok"` gets the same field scopes as `${var.field}`.
The Tree-sitter grammar drops `<-` from its operator choice — the send
form is `->` only and `send x <- ch` is `E_PARSE` — so neither editor
paints `<-` as a send operator; the regenerated `src/` parser is
committed. Fixtures gain an `export prompt` and a named-prompt call site,
with matching assertions and a `<-` negative case; stale-keyword
regressions still pass.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Replace operator-facing strings that still taught the retired nouns. The send-outside-context error, channel route diagnostic, and shell guard text now use def / send ... -> wording instead of "workflow execution context", "-> <workflow>", and "channel send (<-)". The e2e readonly "sandbox" branch and its e2e::readonly_sandbox_available helper are removed so CI no longer pretends Jaiph ships a sandbox, and the contributing docs match. Misleading test titles and comments that said ensure/workflow while asserting run/def are renamed, with compiler txtar fixtures and snapshots regenerated. No behavior changes; internal identifiers such as WORKFLOW_RUNNER_ARG and filenames are left in place. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Build the runner env from an allowlist instead of copying the whole host environment, so ungranted host keys never reach the workflow leader, runtime, or `jaiph test` env object. The runner env now carries only the prompt-base names/prefixes, JAIPH_* control keys, and backend credential keys the runner must forward via scrubPromptEnv. --env grant values no longer sit on the leader/runtime env. Grant names stay on JAIPH_ENV_GRANT, while grant values travel to the detached leader through a side channel outside the leader env and outside any workspace or JAIPH_RUN_DIR path (env-grant-file). hostEnvSnapshot resolves granted `use` values from that grant map; ungranted host keys are absent from both the runner env and the map. The use ∩ --env rule, E_ENV_MISSING preflight, reserved-key rejection, and scrubPromptEnv / applyUseEnv for named prompts are unchanged: a `use` script or named prompt still receives its granted value, while anonymous prompts and non-`use` declarations still do not. Docs (script-env, why-jaiph) now state that --env values reach only subprocesses whose declaration uses the key and are absent from the runner process, keeping the existing "this is not a sandbox" caveat. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
A documented one-line return match (and return prompt) was falling through to a shell step. return is now parse-or-E_PARSE. Co-authored-by: Cursor <cursoragent@cursor.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…dits Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
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.
No description provided.