Conversation
Protect the host-mounted .jaiph/runs contract by asserting Docker-backed runs create and grow step .out/.err files before the workflow exits. Made-with: Cursor
Keep nested run/ensure calls explicit across validation, formatting, and runtime execution, and make Docker use the local Jaiph package with a writable workspace fallback so container behavior matches local runs. Made-with: Cursor
Enforce that nested call-like expressions inside argument positions must use an explicit `run` or `ensure` keyword. Bare call-like forms (`run foo(bar())`, `run foo(rule_bar())`, `run foo(\`echo x\`())`, `const x = bar()`) are now rejected at compile time with actionable error messages. The explicit forms (`run foo(run bar())`, `run foo(ensure rule_bar())`, `run foo(run \`echo x\`())`) execute the nested call first and pass the result as a single argument. Validator extended with inline script detection, runtime evaluates managed argument tokens before outer dispatch, and the formatter round-trips all valid nested forms. Regression tests cover all accepted and rejected patterns. Docs and grammar updated. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…nfig file Signed-off-by: Jakub Dzikowski <jakub.t.dzikowski@gmail.com>
…runtime images Remove all auto-derivation and runtime bootstrap paths from Docker mode. The runtime no longer builds derived images via npm pack or installs jaiph into arbitrary base images at run time. Every Docker image must already contain a working jaiph CLI; missing jaiph now fails fast with an actionable error. Default docker_image switches from node:20-bookworm to the official ghcr.io/jaiphlang/jaiph-runtime image. A new CI workflow publishes that image for release tags and nightly builds. Docs, init scaffolding, and E2E tests are updated to reflect the strict contract. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Support module.name, module.version, and module.description as optional
string keys in the module-level config { } block. Values are stored on
WorkflowMetadata.module as descriptive metadata only — they do not
affect agent, run, or runtime behavior. Workflow-level config blocks
reject module.* keys with E_PARSE, consistent with the existing
runtime.* guard. The formatter round-trips all three keys. Unit tests
cover happy path, partial keys, coexistence, round-trip, and
workflow-level rejection. Docs and grammar updated.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add mount denylist rejecting dangerous host paths (/, /proc, /sys, /dev, Docker socket) at validation time with E_VALIDATE_MOUNT. Add environment variable denylist (SSH_*, GPG_*, AWS_*, GCP_*, AZURE_*, GOOGLE_*, DOCKER_*, KUBE*, NPM_TOKEN*) preventing host credential leakage into containers. Launch containers with --cap-drop ALL --cap-add SYS_ADMIN --security-opt no-new-privileges for least-privilege capability control. Document threat model in docs/sandboxing.md covering what Docker does and does not protect against (hooks on host, network egress, agent credential forwarding, image supply chain, container escapes). Add failure-modes reference table, expanded network-mode guidance, and env denylist spec. Unit tests cover all new validation and filtering paths. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Docker is now enabled by default when neither CI=true nor JAIPH_UNSAFE=true is set in the environment. This makes sandboxed execution the safe default for local development while keeping Docker off in CI (where it is typically unavailable or redundant) and when the user explicitly opts out via JAIPH_UNSAFE=true. Precedence: JAIPH_DOCKER_ENABLED env > in-file runtime.docker_enabled > CI/unsafe default rule. The test harness and E2E runner set JAIPH_UNSAFE=true so existing tests continue to run on host. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Docker runs enforce an immutability contract: the host workspace is bind-mounted read-only and /jaiph/workspace is a sandbox-local copy-on-write layer discarded on exit. The only persistence channel to the host is the run-artifacts directory. During teardown, the runtime now automatically exports a workspace.patch file (git diff --binary) into the run directory so sandbox edits can be reviewed or applied on the host. Patch export is best-effort, owned by the runtime (not workflow logic), and runs regardless of workflow exit status. When there are no changes, the file is omitted. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…nd eliminate outdated content. Signed-off-by: Jakub Dzikowski <jakub.t.dzikowski@gmail.com>
Signed-off-by: Jakub Dzikowski <jakub.t.dzikowski@gmail.com>
Introduce `recover` as a first-class repair-and-retry primitive for `run` steps, distinct from the existing one-shot `catch`. When a run step fails, the recover block binds the error, executes a repair body, and retries the step in a loop until it succeeds or the retry limit (default 10, configurable via `config`) is exhausted. Covers parser, formatter, validator, runtime, e2e acceptance test, and docs-site syntax highlighting for the new keyword. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…osition
Replace the implicit end-of-workflow join with a first-class Handle<T>
that run async returns immediately. Handles resolve transparently on
first non-passthrough read (argument passing to run, interpolation,
comparison, branching) while passthrough operations (assignment, list
storage, unchanged forwarding) leave them unresolved. Workflow exit
implicitly joins any remaining unresolved handles.
Ship recover composition for run async in the same change: the parser
now accepts recover(err) { ... } after run async ref(args), and the
runtime wires up the same retry-limit semantics used by non-async
recover. Includes the spec document, parser/formatter/runtime tests,
updated grammar and language docs, and syntax highlighter support.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
… out of the sandbox Introduce a two-layer artifacts system for workflows running inside the Docker sandbox (or on the host). The runtime layer creates a .jaiph/runs/<run_id>/artifacts/ directory before workflow execution and exposes its path via the JAIPH_ARTIFACTS_DIR env var (resolving to /jaiph/run/artifacts in the container, the host path otherwise). The library layer ships .jaiph/libs/jaiphlang/artifacts.jh paired with artifacts.sh, providing three export workflow entries: save (copy a file into artifacts), save_patch (git diff excluding .jaiph/), and apply_patch (git apply). The library mirrors the existing queue.jh pattern. Includes runtime unit tests, an E2E test, and docs updates. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Exercise the live TTY progress tree path for `run async` workflows under a real pseudo-terminal. The test spawns `jaiph run` with two concurrent async branches (branch_a, branch_b), each emitting deterministic progress events via log and script steps with sleeps. A Python pty.openpty() harness captures the raw PTY stream and asserts per-branch events render under correct subscript nodes (₁, ₂), resolved Handle<T> return values appear in the final frame, and no orphaned ANSI escape sequences survive after CSI stripping. This closes the regression gap left by the sync-only 81_tty_progress_tree.sh test. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Jakub Dzikowski <jakub.t.dzikowski@gmail.com>
…g guide The actual filesystem cleanup (deleting 22+ leftover debug directories, removing tracked cruft files safe_name and QUEUE.md.tmp.4951, and adding .gitignore patterns for docker-*/, nested-*/, overlay-*/, local-*/, .tmp*/, QUEUE.md.tmp.*) was committed earlier. This commit records the bookkeeping side: - CHANGELOG.md: add entry describing the cleanup and disposition of safe_name, lib/, and run/ (all deleted — no live consumers found). - QUEUE.md: remove the completed task from the queue. - docs/contributing.md: add "Workspace hygiene" section documenting the .gitignore patterns and how to override them with git add -f. Disposition of investigated paths: - safe_name: deleted (tracked file, no live consumers) - lib/: deleted (empty top-level directory, no live consumers) - run/: deleted (empty top-level directory, no live consumers) No code changes; documentation and queue bookkeeping only. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Delete exportWorkspacePatch and findRunArtifacts from src/runtime/docker.ts, exportPatchIfDocker from node-workflow-runtime.ts, and the findRunArtifacts call in src/cli/commands/run.ts. These functions served the abandoned per-call isolated keyword and are fully replaced by the artifacts.jh library (artifacts.save_patch() for workspace patches, JAIPH_ARTIFACTS_DIR for artifact discovery). Also removes ~150 LoC of dead tests in docker.test.ts and updates docs (sandboxing.md, architecture.md, artifacts.md) to reflect the removal. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…TYLine When fuse overlay is unavailable, rsync and the cp fallback no longer copy .jaiph/runs; emit a clear stderr line before the temp workspace copy. In TTY mode, stderr_line events use writeTTYLine so lines show immediately without clearing/redrawing the running status line. Add QUEUE item for agent_inbox workflow quoting noise. Signed-off-by: Jakub Dzikowski <jakub.t.dzikowski@gmail.com>
Strip backslash-escaped quotes from display formatting so workflow step labels and log lines render human-readably. Three layers changed: formatNamedParamsForDisplay and formatParamsForDisplay no longer escape inner double quotes with backslash (the surrounding key="value" delimiters are structural, not shell-safe); formatStartLine in display.ts applies the same change for prompt previews; and node-workflow-runtime strips outer quotes from interpolated channel-send payloads via stripOuterQuotes so messages flow through dispatch without literal quote wrappers. Regression tests added; E2E golden output updated. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- CI: build/push ghcr.io/jaiphlang/jaiph-runtime from .jaiph/Dockerfile on nightly branch (:nightly) and version tags (:<semver>, :latest); pass JAIPH_REPO_REF for install ref. - Runtime: resolveImage always uses configured/default image with pull + jaiph check; stop auto docker build of workspace .jaiph/Dockerfile on jaiph run (keep runtime.docker_image / JAIPH_DOCKER_*). - Docs and E2E aligned; unit test contract updated for resolveImage. Signed-off-by: Jakub Dzikowski <jakub.t.dzikowski@gmail.com>
- Move published Docker recipe to runtime/Dockerfile; CI builds from runtime/. - jaiph init: stop creating .jaiph/Dockerfile; bootstrap prompt and tests/e2e updated. - Reference docs: describe current behavior only (sandboxing patches, inbox send, grammar/testing notes, jaiph-skill, libraries comment). Signed-off-by: Jakub Dzikowski <jakub.t.dzikowski@gmail.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.