From db88cb65d3d8fffd2e80faa8d0c6cc1ce5d71c34 Mon Sep 17 00:00:00 2001 From: "Jonathan D.A. Jewell" <6759885+hyperpolymath@users.noreply.github.com> Date: Sun, 20 Sep 2026 14:41:48 +0000 Subject: [PATCH] chore(phase7): Guix zig check, honest Containerfiles, mise pins Zig FFI is the Guix check phase. Containers run 0.15.1 tests, no fake HTTP. mise/tool-versions drop rust nightly. GitHub environment ci via API. Signed-off-by: Jonathan D.A. Jewell <6759885+hyperpolymath@users.noreply.github.com> --- .devcontainer/Containerfile | 8 +- .tool-versions | 13 +-- build/Containerfile | 44 +++-------- build/guix.scm | 80 ++++++------------- container/Containerfile | 144 +++++----------------------------- container/entrypoint.sh | 7 +- docs/reports/PHASE-7-ENV.adoc | 26 ++++++ mise.toml | 13 ++- 8 files changed, 99 insertions(+), 236 deletions(-) create mode 100644 docs/reports/PHASE-7-ENV.adoc diff --git a/.devcontainer/Containerfile b/.devcontainer/Containerfile index 03447ed..bbfb15a 100644 --- a/.devcontainer/Containerfile +++ b/.devcontainer/Containerfile @@ -7,7 +7,7 @@ FROM cgr.dev/chainguard/wolfi-base:latest -# Install common development tools +# Install common development tools + Zig 0.15.1 (official tarball) RUN apk update && apk add --no-cache \ bash \ curl \ @@ -17,7 +17,13 @@ RUN apk update && apk add --no-cache \ build-base \ posix-libc-utils \ shadow \ + tar \ + xz \ && rm -rf /var/cache/apk/* +RUN curl -fsSL -o /tmp/zig.tar.xz \ + https://ziglang.org/download/0.15.1/zig-x86_64-linux-0.15.1.tar.xz \ + && tar -xJf /tmp/zig.tar.xz -C /opt \ + && ln -s /opt/zig-x86_64-linux-0.15.1/zig /usr/local/bin/zig # Create non-root dev user (matches devcontainer.json remoteUser) RUN groupadd -g 1000 nonroot || true \ diff --git a/.tool-versions b/.tool-versions index ce60c32..f8c7335 100644 --- a/.tool-versions +++ b/.tool-versions @@ -1,10 +1,3 @@ -# Uncomment and customize for your project -# rust nightly -# just 1.40.0 -# nickel 1.10.0 -# gleam 1.8.0 -# elixir 1.18.0 -# erlang 27.2 -# zig 0.14.0 -# idris2 0.7.0 -rust nightly +# asdf/mise fallback. Canonical pins: mise.toml +just 1.40.0 +zig 0.15.1 diff --git a/build/Containerfile b/build/Containerfile index be7078d..719789c 100644 --- a/build/Containerfile +++ b/build/Containerfile @@ -1,41 +1,19 @@ # SPDX-License-Identifier: MPL-2.0 # Copyright (c) 2026 Jonathan D.A. Jewell (hyperpolymath) # -# Containerfile for Panoply -# Build: podman build -t panoply:latest -f Containerfile . -# Run: podman run --rm -it panoply:latest -# Seal: selur seal panoply:latest +# podman build -t panoply:test -f build/Containerfile . -# --- Build stage --- FROM cgr.dev/chainguard/wolfi-base:latest AS build +WORKDIR /src +RUN apk add --no-cache curl tar xz +RUN curl -fsSL -o /tmp/zig.tar.xz \ + https://ziglang.org/download/0.15.1/zig-x86_64-linux-0.15.1.tar.xz \ + && tar -xJf /tmp/zig.tar.xz -C /opt \ + && ln -s /opt/zig-x86_64-linux-0.15.1/zig /usr/local/bin/zig +COPY src/interface/ffi /src/src/interface/ffi +WORKDIR /src/src/interface/ffi +RUN zig version && zig build test -# TODO: Install build dependencies for your stack -# Examples: -# RUN apk add --no-cache rust cargo # Rust -# RUN apk add --no-cache elixir erlang # Elixir -# RUN apk add --no-cache zig # Zig - -WORKDIR /build -COPY . . - -# TODO: Replace with your build command -# Examples: -# RUN cargo build --release -# RUN mix deps.get && MIX_ENV=prod mix release -# RUN zig build -Doptimize=ReleaseSafe - -# --- Runtime stage --- FROM cgr.dev/chainguard/static:latest - -# Copy built artifact from build stage -# TODO: Replace with your binary/artifact path -# Examples: -# COPY --from=build /build/target/release/panoply /usr/local/bin/ -# COPY --from=build /build/_build/prod/rel/panoply /app/ -# COPY --from=build /build/zig-out/bin/panoply /usr/local/bin/ - -# Non-root user (chainguard images default to nonroot) +# Test-build artefact only. No daemon. USER nonroot - -# TODO: Replace with your entrypoint -# ENTRYPOINT ["/usr/local/bin/panoply"] diff --git a/build/guix.scm b/build/guix.scm index 2a25452..cce83d9 100644 --- a/build/guix.scm +++ b/build/guix.scm @@ -1,79 +1,51 @@ ;; SPDX-License-Identifier: MPL-2.0 ;; Copyright (c) 2026 Jonathan D.A. Jewell (hyperpolymath) ;; -;; Guix package definition for Panoply +;; Guix package for panoply (library: Zig FFI tests; Idris2 optional). +;; guix shell -D -f build/guix.scm +;; guix build -f build/guix.scm ;; -;; Usage: -;; guix shell -D -f guix.scm # Enter development shell -;; guix build -f guix.scm # Build package -;; -;; TODO: wire real build/check phases and native/runtime inputs once the -;; Core/Evidence/Manifest artefacts land (currently text-level placeholders -;; only — no guix toolchain was available locally to verify a real build). -;; See: https://guix.gnu.org/manual/en/html_node/Defining-Packages.html +;; Guix's zig package may lag 0.15.1 (mise pin). If check fails on version, +;; use the Containerfile tarball or mise — do not silently skip tests. (use-modules (guix packages) (guix gexp) - (guix git-download) (guix build-system gnu) (guix licenses) - (gnu packages base)) + (gnu packages zig) + (gnu packages commencement)) (package (name "panoply") (version "0.1.0") - (source (local-file "." "source" + (source (local-file ".." "source" #:recursive? #t #:select? (lambda (file stat) (not (string-contains file ".git"))))) (build-system gnu-build-system) (arguments - '(#:phases + '(#:tests? #t + #:phases (modify-phases %standard-phases - ;; TODO: Customize build phases for your project - ;; Examples for common stacks: - ;; - ;; Rust: - ;; (replace 'build (lambda _ (invoke "cargo" "build" "--release"))) - ;; (replace 'check (lambda _ (invoke "cargo" "test"))) - ;; - ;; Elixir: - ;; (replace 'build (lambda _ (invoke "mix" "compile"))) - ;; (replace 'check (lambda _ (invoke "mix" "test"))) - ;; - ;; Zig: - ;; (replace 'build (lambda _ (invoke "zig" "build"))) - ;; (replace 'check (lambda _ (invoke "zig" "build" "test"))) (delete 'configure) - (delete 'build) - (delete 'check) + (replace 'build + (lambda _ + (with-directory-excursion "src/interface/ffi" + (invoke "zig" "build")))) + (replace 'check + (lambda _ + (with-directory-excursion "src/interface/ffi" + (invoke "zig" "build" "test")))) (replace 'install (lambda* (#:key outputs #:allow-other-keys) (let ((out (assoc-ref outputs "out"))) - (mkdir-p (string-append out "/share/doc")) + (mkdir-p (string-append out "/share/doc/panoply")) (copy-file "README.adoc" - (string-append out "/share/doc/README.adoc")))))))) - (native-inputs - (list - ;; TODO: Add build-time dependencies - ;; Examples: - ;; rust (gnu packages rust) - ;; elixir (gnu packages elixir) - ;; zig (gnu packages zig) - )) - (inputs - (list - ;; TODO: Add runtime dependencies - )) + (string-append out "/share/doc/panoply/README.adoc")))))))) + (native-inputs (list zig gcc-toolchain)) (home-page "https://github.com/hyperpolymath/panoply") - (synopsis "An envelope-first language discipline: every safety claim explicit, scoped, inspectable, and mechanically accountable.") - (description "Panoply is defined by three artefacts: a checked Core into -which every accepted program projects, explicit evidence for the claims a -program makes, and a safety-envelope manifest recording which guarantees -have been earned and which have not. It is not yet feature-complete; the -Core checker, evidence formats, manifest schema, and backend contracts -named by the charter are still being built. See README.adoc and -docs/architecture/DESIGN-DISCIPLINE.adoc for details.") - (license (list - ;; MPL-2.0 extends MPL-2.0 - mpl2.0))) + (synopsis "Envelope-first language discipline (Idris2 ABI + Zig FFI)") + (description "Panoply is a library, not a server. This package runs the +Zig FFI test build. Idris2 ABI typecheck is optional and not a Guix input +until a channel pin exists.") + (license mpl2.0)) diff --git a/container/Containerfile b/container/Containerfile index ed4b27e..ef43081 100644 --- a/container/Containerfile +++ b/container/Containerfile @@ -1,136 +1,28 @@ # SPDX-License-Identifier: MPL-2.0 -# Panoply Container Image +# Copyright (c) 2026 Jonathan D.A. Jewell (hyperpolymath) # -# Multi-stage build template for Chainguard Wolfi base images. -# Customise the builder stage for your language and copy the -# resulting binary/release into the minimal runtime stage. -# -# Build with Podman: -# podman build -t panoply:latest -f container/Containerfile . -# -# Run: -# podman run -p 8080:8080 panoply:latest -# -# Run with persistent volume: -# podman run -p 8080:8080 -v panoply-data:/data panoply:latest +# Canonical container path (stapeln). Same as build/Containerfile: +# Zig FFI tests only. Panoply is not an HTTP service — no EXPOSE 8080. -# ============================================================================ -# Stage 1: Builder -# ============================================================================ -# -# Install build tools and compile the application. -# This stage is discarded after the build — only the compiled output -# is copied into the runtime stage. -# -# Language-specific examples (uncomment the one you need): -# -# --- Rust --- -# RUN apk add --no-cache rust pkgconf build-base -# COPY Cargo.toml Cargo.lock ./ -# COPY src/ ./src/ -# RUN cargo build --release -# # Output: /build/target/release/panoply -# -# --- Elixir --- -# RUN apk add --no-cache erl27-elixir-1.18 erlang-27 erlang-27-dev git build-base -# COPY mix.exs mix.lock ./ -# COPY lib/ ./lib/ -# COPY config/ ./config/ -# ENV MIX_ENV=prod -# RUN mix local.hex --force && mix local.rebar --force && \ -# mix deps.get --only prod && mix compile && mix release -# # Output: /build/_build/prod/rel/panoply/ -# -# --- Zig --- -# RUN apk add --no-cache zig build-base -# COPY build.zig build.zig.zon ./ -# COPY src/ ./src/ -# RUN zig build -Doptimize=ReleaseFast -# # Output: /build/zig-out/bin/panoply -# FROM cgr.dev/chainguard/wolfi-base:latest AS builder +WORKDIR /src +RUN apk add --no-cache curl tar xz +RUN curl -fsSL -o /tmp/zig.tar.xz \ + https://ziglang.org/download/0.15.1/zig-x86_64-linux-0.15.1.tar.xz \ + && tar -xJf /tmp/zig.tar.xz -C /opt \ + && ln -s /opt/zig-x86_64-linux-0.15.1/zig /usr/local/bin/zig +COPY src/interface/ffi /src/src/interface/ffi +WORKDIR /src/src/interface/ffi +RUN zig build test -# TODO: Install your language toolchain -RUN apk add --no-cache build-base - -WORKDIR /build - -# TODO: Copy source files and build -COPY . . -# RUN - -# ============================================================================ -# Stage 2: Runtime -# ============================================================================ -# -# Minimal production image. Only the compiled binary/release and runtime -# dependencies are included. No compilers, no source code, no build tools. -# FROM cgr.dev/chainguard/wolfi-base:latest - -# OCI image labels (compatible with cerro-torre .ctp bundle metadata) LABEL org.opencontainers.image.title="Panoply" \ - org.opencontainers.image.description="An envelope-first language discipline: every safety claim explicit, scoped, inspectable, and mechanically accountable." \ - org.opencontainers.image.url="https://github.com/hyperpolymath/panoply" \ + org.opencontainers.image.description="Envelope-first language discipline (library; FFI tests)" \ org.opencontainers.image.source="https://github.com/hyperpolymath/panoply" \ - org.opencontainers.image.vendor="hyperpolymath" \ - org.opencontainers.image.licenses="MPL-2.0" \ - org.opencontainers.image.authors="Jonathan D.A. Jewell " \ - dev.cerrotorre.manifest="container/manifest.toml" \ - dev.cerrotorre.gatekeeper="container/.gatekeeper.yaml" \ - dev.stapeln.compose="container/compose.toml" - -# Install minimal runtime dependencies. -# Adjust this list for your application: -# - ca-certificates: TLS root certificates -# - curl: health check probe -# - libstdc++: C++ standard library (if needed by native deps) -# - ncurses: terminal UI (if needed, e.g. Elixir IEx) -RUN apk add --no-cache ca-certificates curl - -# Create non-root user for the application. -# Running as root inside containers is a security anti-pattern. -RUN addgroup -S appuser && adduser -S appuser -G appuser - -WORKDIR /app - -# TODO: Copy compiled binary/release from builder stage. -# Examples: -# COPY --from=builder /build/target/release/panoply /app/panoply -# COPY --from=builder /build/_build/prod/rel/panoply /app/release/ -# COPY --from=builder /build/zig-out/bin/panoply /app/panoply - -# Copy entrypoint script + org.opencontainers.image.licenses="MPL-2.0" COPY container/entrypoint.sh /app/entrypoint.sh -RUN chmod +x /app/entrypoint.sh - -# Copy stapeln integration files (svalinn gatekeeper policy, cerro-torre manifest) -COPY container/.gatekeeper.yaml /etc/svalinn/gatekeeper.yaml -COPY container/manifest.toml /app/manifest.toml - -# Create data directory for persistent storage (mountable volume) -RUN mkdir -p /data && chown appuser:appuser /data - -# Set ownership of the application directory -RUN chown -R appuser:appuser /app - -# Environment variables — customise for your application -ENV APP_HOST=[::] -ENV APP_PORT=8080 -ENV APP_LOG_FORMAT=json -ENV APP_DATA_DIR=/data - -# Declare /data as a volume for persistent storage -VOLUME ["/data"] - -# Run as non-root -USER appuser - -# Expose the application port -EXPOSE 8080 - -# Health check — the application must respond 2xx at /health -HEALTHCHECK --interval=30s --timeout=5s --start-period=10s --retries=3 \ - CMD curl -sf http://localhost:${APP_PORT}/health || exit 1 - +USER nonroot +WORKDIR /app ENTRYPOINT ["/app/entrypoint.sh"] +# Default: print honesty, then exit 0 (no daemon). +CMD ["true"] diff --git a/container/entrypoint.sh b/container/entrypoint.sh index 09e79b0..14b008a 100755 --- a/container/entrypoint.sh +++ b/container/entrypoint.sh @@ -27,11 +27,8 @@ trap cleanup TERM INT # Startup logging # --------------------------------------------------------------------------- -echo "Starting panoply..." -echo " Host: ${APP_HOST:-[::]}" -echo " Port: ${APP_PORT:-8080}" -echo " Data: ${APP_DATA_DIR:-/data}" -echo " Log: ${APP_LOG_FORMAT:-json}" +echo "panoply container: library image, not an HTTP daemon" +echo " zig tests ran at image build; there is no listen port" # --------------------------------------------------------------------------- # Health check preparation diff --git a/docs/reports/PHASE-7-ENV.adoc b/docs/reports/PHASE-7-ENV.adoc new file mode 100644 index 0000000..d5cde5b --- /dev/null +++ b/docs/reports/PHASE-7-ENV.adoc @@ -0,0 +1,26 @@ +// SPDX-License-Identifier: CC-BY-SA-4.0 +// Copyright (c) Jonathan D.A. Jewell += Phase 7 — Guix, containers, mise, environments +:revdate: 2026-09-20 + +== 7.1 Guix + +`build/.guix-channel` + `build/guix.scm`. Package now **builds and checks** +Zig FFI (`zig build test`). Guix zig may not be 0.15.1 — mise/container +tarball is the pin. Idris2 not a Guix input yet. + +== 7.2 Containers + +`container/Containerfile` and `build/Containerfile` run Zig 0.15.1 tests. +**No fake :8080 /health** (library). Devcontainer installs the same tarball. +Podman, Chainguard Wolfi. + +== 7.3 mise + +`mise.toml`: just 1.40.0, zig 0.15.1, bun 1.2.21, deno 2.5.0. +`.tool-versions` no longer claims `rust nightly`. + +== 7.4 GitHub environments + +`github-pages` already existed. `ci` created via API (no secrets). +Pages remains the only deploy environment. diff --git a/mise.toml b/mise.toml index 8eee28c..7d6f143 100644 --- a/mise.toml +++ b/mise.toml @@ -1,13 +1,12 @@ # SPDX-License-Identifier: MPL-2.0 -# Panoply toolchain pins (mise). -# JS reach order (owner 2026-09-20): Bun → Deno → pnpm → npm. -# Packager remains Guix (`build/guix.scm`); mise is a local version helper. +# Panoply toolchain pins (mise). Packager remains Guix (`build/guix.scm`). +# JS reach: Bun → Deno → pnpm → npm. [tools] -just = "latest" +just = "1.40.0" zig = "0.15.1" -bun = "latest" -deno = "latest" +bun = "1.2.21" +deno = "2.5.0" [env] -# Idris2 is not a mise registry tool; install via Guix. +# Idris2 is not in the mise registry; install via Guix or the Idris2 installer.