Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
8 changes: 7 additions & 1 deletion .devcontainer/Containerfile
Original file line number Diff line number Diff line change
Expand Up @@ -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 \
Expand All @@ -17,7 +17,13 @@
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 \

Check warning on line 24 in .devcontainer/Containerfile

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Replace this invocation of "curl" with the ADD instruction.

See more on https://sonarcloud.io/project/issues?id=hyperpolymath_panoply&issues=AaC_RI2j_s_fzfLynwuk&open=AaC_RI2j_s_fzfLynwuk&pullRequest=76

Check warning on line 24 in .devcontainer/Containerfile

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Not enforcing HTTPS here might allow for redirections to insecure websites. Make sure it is safe here.

See more on https://sonarcloud.io/project/issues?id=hyperpolymath_panoply&issues=AaC_RI2j_s_fzfLynwul&open=AaC_RI2j_s_fzfLynwul&pullRequest=76
&& 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 \
Expand Down
13 changes: 3 additions & 10 deletions .tool-versions
Original file line number Diff line number Diff line change
@@ -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
44 changes: 11 additions & 33 deletions build/Containerfile
Original file line number Diff line number Diff line change
@@ -1,41 +1,19 @@
# SPDX-License-Identifier: MPL-2.0
# Copyright (c) 2026 Jonathan D.A. Jewell (hyperpolymath) <j.d.a.jewell@open.ac.uk>
#
# 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 \

Check warning on line 10 in build/Containerfile

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Replace this invocation of "curl" with the ADD instruction.

See more on https://sonarcloud.io/project/issues?id=hyperpolymath_panoply&issues=AaC_RIzD_s_fzfLynwug&open=AaC_RIzD_s_fzfLynwug&pullRequest=76

Check warning on line 10 in build/Containerfile

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Not enforcing HTTPS here might allow for redirections to insecure websites. Make sure it is safe here.

See more on https://sonarcloud.io/project/issues?id=hyperpolymath_panoply&issues=AaC_RIzD_s_fzfLynwuh&open=AaC_RIzD_s_fzfLynwuh&pullRequest=76
&& 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"]
80 changes: 26 additions & 54 deletions build/guix.scm
Original file line number Diff line number Diff line change
@@ -1,79 +1,51 @@
;; SPDX-License-Identifier: MPL-2.0
;; Copyright (c) 2026 Jonathan D.A. Jewell (hyperpolymath) <j.d.a.jewell@open.ac.uk>
;;
;; 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))
144 changes: 18 additions & 126 deletions container/Containerfile
Original file line number Diff line number Diff line change
@@ -1,136 +1,28 @@
# SPDX-License-Identifier: MPL-2.0
# Panoply Container Image
# Copyright (c) 2026 Jonathan D.A. Jewell (hyperpolymath) <j.d.a.jewell@open.ac.uk>
#
# 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 \

Check warning on line 11 in container/Containerfile

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Replace this invocation of "curl" with the ADD instruction.

See more on https://sonarcloud.io/project/issues?id=hyperpolymath_panoply&issues=AaC_RI1i_s_fzfLynwui&open=AaC_RI1i_s_fzfLynwui&pullRequest=76

Check warning on line 11 in container/Containerfile

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Not enforcing HTTPS here might allow for redirections to insecure websites. Make sure it is safe here.

See more on https://sonarcloud.io/project/issues?id=hyperpolymath_panoply&issues=AaC_RI1i_s_fzfLynwuj&open=AaC_RI1i_s_fzfLynwuj&pullRequest=76
&& 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 <your-build-command>

# ============================================================================
# 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 <j.d.a.jewell@open.ac.uk>" \
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"]
7 changes: 2 additions & 5 deletions container/entrypoint.sh
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
26 changes: 26 additions & 0 deletions docs/reports/PHASE-7-ENV.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
// SPDX-License-Identifier: CC-BY-SA-4.0
// Copyright (c) Jonathan D.A. Jewell <j.d.a.jewell@open.ac.uk>
= 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.
Loading
Loading