Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
435e7ae
Add Docker live run-artifact regression test.
dzikowski Apr 17, 2026
81e9aa3
Fix explicit nested managed calls in Docker runs.
dzikowski Apr 17, 2026
d25fb3f
Feat: Require explicit managed calls in nested argument lists
dzikowski Apr 17, 2026
955a67b
Queue: Harden docker tasks, add version/name/description for jaiph co…
dzikowski Apr 17, 2026
d398b7a
Feat: Enforce strict Docker image contract and publish official GHCR …
dzikowski Apr 17, 2026
c5e20c0
Feat: Add optional module manifest keys to config block
dzikowski Apr 17, 2026
d9b3b00
Feat: Harden Docker execution environment with least-privilege defaults
dzikowski Apr 17, 2026
e08f584
Feat: Default Docker sandboxing to on for local development
dzikowski Apr 17, 2026
6a0e253
Feat: Export workspace patch on Docker run teardown
dzikowski Apr 18, 2026
348e3e4
Remove target design documentation file to streamline project focus a…
dzikowski Apr 19, 2026
58bbcca
Queue: Add cleanup tasks
dzikowski Apr 20, 2026
f055601
Feat: Add recover loop semantics for non-isolated run
dzikowski Apr 20, 2026
97b3aff
Feat: Implement Handle<T> value model for run async with recover comp…
dzikowski Apr 20, 2026
e34a2f9
Feat: Add artifacts.jh library and runtime mount for publishing files…
dzikowski Apr 20, 2026
7a04ab0
Test: Add PTY-based E2E test for run async progress rendering
dzikowski Apr 20, 2026
9052ad0
Attempt to fix CI
dzikowski Apr 20, 2026
477967c
Docs: Record debug cruft cleanup in changelog, queue, and contributin…
dzikowski Apr 20, 2026
0a25ba1
Cleanup: Remove dead per-call-isolated leftovers from Docker runtime
dzikowski Apr 20, 2026
1d642be
Fix: Exclude .jaiph/runs from docker copy; TTY stderr_line via writeT…
dzikowski Apr 20, 2026
5eb9d4c
Fix: Remove double-quote escaping noise from step titles and log output
dzikowski Apr 20, 2026
eaec3b7
Docker: Publish runtime from .jaiph/Dockerfile; pull GHCR on run
dzikowski Apr 20, 2026
712c5b9
Docs: Drop historical phrasing; relocate runtime image to runtime/
dzikowski Apr 20, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 56 additions & 0 deletions .github/workflows/docker-publish.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
name: Publish Docker runtime image

on:
push:
branches: [nightly]
tags: ["v*"]

permissions:
contents: read
packages: write

env:
REGISTRY: ghcr.io
IMAGE_NAME: jaiphlang/jaiph-runtime

jobs:
publish:
name: Build and push jaiph-runtime
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4

- name: Log in to GHCR
uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}

- name: Image tags and jaiph ref
id: meta
run: |
if [[ "${GITHUB_REF}" == refs/tags/v* ]]; then
VERSION="${GITHUB_REF_NAME#v}"
echo "tags=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${VERSION},${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest" >> "$GITHUB_OUTPUT"
echo "jaiph_ref=v${VERSION}" >> "$GITHUB_OUTPUT"
else
echo "tags=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:nightly" >> "$GITHUB_OUTPUT"
echo "jaiph_ref=nightly" >> "$GITHUB_OUTPUT"
fi

- name: Build and push
uses: docker/build-push-action@v6
with:
context: runtime
file: runtime/Dockerfile
push: true
tags: ${{ steps.meta.outputs.tags }}
build-args: |
JAIPH_REPO_REF=${{ steps.meta.outputs.jaiph_ref }}

- name: Verify pushed image contains jaiph
run: |
TAG="$(echo '${{ steps.meta.outputs.tags }}' | cut -d',' -f1)"
docker run --rm --entrypoint sh "${TAG}" -lc "command -v jaiph && jaiph --version"
10 changes: 9 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -48,4 +48,12 @@ e2e/ensure_fail.sh
e2e/current_branch.sh
e2e/assign_capture.sh

.obsidian/
.obsidian/

# debug / temp directories (never commit)
docker-*/
nested-*/
overlay-*/
local-*/
.tmp*/
QUEUE.md.tmp.*
2 changes: 1 addition & 1 deletion .jaiph/architect_review.jh
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ workflow review_one_header(header) {
const verdict = run first_line_str(packed)
const updated_description = run rest_lines_str(packed)
const body_file = run jaiph_review_body_file()
run mkdir_p_simple(run, jaiph_tmp_dir())
run mkdir_p_simple(run jaiph_tmp_dir())
run str_equals(verdict, "dev-ready") catch (err) {
run arg_nonempty(updated_description) catch (err) {
fail "needs-work requires a non-empty updated_description (questions for the author)."
Expand Down
36 changes: 36 additions & 0 deletions .jaiph/libs/jaiphlang/artifacts.jh
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
#!/usr/bin/env jaiph

#
# Artifact publishing for Jaiph workflows.
# Copies files from the workspace into ${JAIPH_ARTIFACTS_DIR} so they
# survive sandbox teardown and are readable on the host at
# .jaiph/runs/<run_id>/artifacts/.
#
# Usage:
# import "jaiphlang/artifacts" as artifacts
#
# workflow default() {
# run artifacts.save("./build/output.bin", "build-output.bin")
# run artifacts.save_patch("snapshot.patch")
# }
#
import script "./artifacts.sh" as artifacts

# Copies the file at `local_path` into the artifacts directory under `name`.
# Returns the absolute path of the saved artifact.
export workflow save(local_path, name) {
return run artifacts("save", local_path, name)
}

# Runs `git diff` (working tree vs HEAD, excluding .jaiph/) and writes
# the patch to the artifacts directory under `name`.
# Returns the absolute path of the saved patch file.
export workflow save_patch(name) {
return run artifacts("save_patch", name)
}

# Applies a patch file to the current workspace via `git apply`.
# Useful for replaying artifacts across runs.
export workflow apply_patch(path) {
run artifacts("apply_patch", path)
}
72 changes: 72 additions & 0 deletions .jaiph/libs/jaiphlang/artifacts.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
#!/usr/bin/env bash
#
# Artifacts helper for Jaiph workflows.
# Reads JAIPH_ARTIFACTS_DIR to locate the writable artifacts directory.
# Works identically inside the Docker sandbox and on the host.
#
set -euo pipefail

ARTIFACTS_DIR="${JAIPH_ARTIFACTS_DIR:?JAIPH_ARTIFACTS_DIR is not set}"

cmd_save() {
local src="$1" name="$2"
if [[ ! -f "${src}" ]]; then
printf 'artifacts save: file not found: %s\n' "${src}" >&2
exit 1
fi
local dest="${ARTIFACTS_DIR}/${name}"
mkdir -p "$(dirname "${dest}")"
cp -- "${src}" "${dest}"
printf '%s' "${dest}"
}

cmd_save_patch() {
local name="$1"
local dest="${ARTIFACTS_DIR}/${name}"
mkdir -p "$(dirname "${dest}")"
# Exclude .jaiph/ from the produced patch — the runtime writes its own
# state under .jaiph/ and including it would clobber state on apply.
local diff_out
diff_out="$(git diff HEAD -- . ':!.jaiph/' 2>/dev/null || true)"
if [[ -z "${diff_out}" ]]; then
# Also check for untracked files (intent-to-add)
git add -N . -- ':!.jaiph/' 2>/dev/null || true
diff_out="$(git diff HEAD -- . ':!.jaiph/' 2>/dev/null || true)"
# Reset intent-to-add to avoid side effects
git reset HEAD -- . 2>/dev/null || true
fi
if [[ -n "${diff_out}" ]]; then
printf '%s\n' "${diff_out}" > "${dest}"
else
# Empty/clean workspace — create empty file
: > "${dest}"
fi
printf '%s' "${dest}"
}

cmd_apply_patch() {
local patch_path="$1"
if [[ ! -f "${patch_path}" ]]; then
printf 'artifacts apply_patch: patch file not found: %s\n' "${patch_path}" >&2
exit 1
fi
if [[ ! -s "${patch_path}" ]]; then
printf 'artifacts apply_patch: patch file is empty: %s\n' "${patch_path}" >&2
exit 1
fi
git apply "${patch_path}"
}

# -- dispatch ----------------------------------------------------------------
cmd="${1:-}"
shift || true

case "${cmd}" in
save) cmd_save "$@" ;;
save_patch) cmd_save_patch "$@" ;;
apply_patch) cmd_apply_patch "$@" ;;
*)
printf 'Usage: artifacts <save|save_patch|apply_patch> [args...]\n' >&2
exit 1
;;
esac
Loading
Loading