Merge pull request 'LithosAnanke v4.0.0-alpha.1: the first alpha release' (#127) from StarForth-v4.0.0 into master
Runner image / Build and publish the runner image (push) Successful in 51s
Runner image / Build and publish the runner image (push) Successful in 51s
This commit was merged in pull request #127.
This commit is contained in:
@@ -18,7 +18,8 @@ on:
|
||||
workflow_dispatch:
|
||||
|
||||
concurrency:
|
||||
group: qemu # one QEMU at a time on the runner: shared with nightly.yml and release.yml
|
||||
group: qemu # every workflow shares this one group: one run at a time,
|
||||
# a runner-image rebuild included (Captain Bob, 2026-11-07)
|
||||
cancel-in-progress: false
|
||||
|
||||
jobs:
|
||||
@@ -37,6 +38,18 @@ jobs:
|
||||
fetch-depth: 0 # the SBOM's version is git describe
|
||||
lfs: false # only the logs and DoE CSVs are in LFS; the build needs neither
|
||||
|
||||
- name: The capsule-signing key
|
||||
env:
|
||||
KEY: ${{ secrets.CAPSULE_SIGN_KEY }}
|
||||
run: | # ci/pki/make-ca.sh; kernel/Makefile signs with SIGN_KEY
|
||||
if [ -n "$KEY" ]; then
|
||||
f="${RUNNER_TEMP:-/tmp}/capsule-signing.key"
|
||||
(umask 077; printf '%s\n' "$KEY" > "$f")
|
||||
echo "SIGN_KEY=$f" >> "$GITHUB_ENV"; echo "The capsules will be signed."
|
||||
else
|
||||
echo "::warning::No CAPSULE_SIGN_KEY secret: the capsules are built unsigned."
|
||||
fi
|
||||
|
||||
- name: Acceptance amd64
|
||||
run: scripts/nightly.sh accept amd64
|
||||
- name: Acceptance aarch64
|
||||
|
||||
@@ -9,8 +9,14 @@ name: Build
|
||||
on:
|
||||
push:
|
||||
branches: [StarForth-v4.0.0] # not master: what reaches it has just passed acceptance (#119)
|
||||
paths-ignore: ['site/**'] # the websites (site/) build nothing here; each run is ~17 min on
|
||||
# the server the wikis share (Captain Bob, 2026-11-07)
|
||||
workflow_dispatch:
|
||||
|
||||
concurrency:
|
||||
group: qemu # every workflow shares this one group (Captain Bob, 2026-11-07: a
|
||||
cancel-in-progress: false # runner-image rebuild blocks other jobs, always): one run at a time
|
||||
|
||||
jobs:
|
||||
image:
|
||||
name: Image ${{ matrix.board }}
|
||||
@@ -34,6 +40,18 @@ jobs:
|
||||
fetch-depth: 0 # the SBOM's version is git describe
|
||||
lfs: false # only the logs and DoE CSVs are in LFS; the build needs neither
|
||||
|
||||
- name: The capsule-signing key
|
||||
env:
|
||||
KEY: ${{ secrets.CAPSULE_SIGN_KEY }}
|
||||
run: | # ci/pki/make-ca.sh; kernel/Makefile signs with SIGN_KEY
|
||||
if [ -n "$KEY" ]; then
|
||||
f="${RUNNER_TEMP:-/tmp}/capsule-signing.key"
|
||||
(umask 077; printf '%s\n' "$KEY" > "$f")
|
||||
echo "SIGN_KEY=$f" >> "$GITHUB_ENV"; echo "The capsules will be signed."
|
||||
else
|
||||
echo "::warning::No CAPSULE_SIGN_KEY secret: the capsules are built unsigned."
|
||||
fi
|
||||
|
||||
- name: Boot image
|
||||
run: make boot_image TARGET=${{ matrix.board }}
|
||||
|
||||
@@ -62,5 +80,17 @@ jobs:
|
||||
with:
|
||||
lfs: false
|
||||
|
||||
- name: The capsule-signing key
|
||||
env:
|
||||
KEY: ${{ secrets.CAPSULE_SIGN_KEY }}
|
||||
run: | # ci/pki/make-ca.sh; kernel/Makefile signs with SIGN_KEY
|
||||
if [ -n "$KEY" ]; then
|
||||
f="${RUNNER_TEMP:-/tmp}/capsule-signing.key"
|
||||
(umask 077; printf '%s\n' "$KEY" > "$f")
|
||||
echo "SIGN_KEY=$f" >> "$GITHUB_ENV"; echo "The capsules will be signed."
|
||||
else
|
||||
echo "::warning::No CAPSULE_SIGN_KEY secret: the capsules are built unsigned."
|
||||
fi
|
||||
|
||||
- name: make -C v4 test
|
||||
run: make -C v4 test
|
||||
|
||||
@@ -14,6 +14,10 @@ on:
|
||||
- cron: '0 4 * * *' # 04:00 UTC, after the images (nightly.yml, 03:00)
|
||||
workflow_dispatch:
|
||||
|
||||
concurrency:
|
||||
group: qemu # every workflow shares this one group (Captain Bob, 2026-11-07: a
|
||||
cancel-in-progress: false # runner-image rebuild blocks other jobs, always): one run at a time
|
||||
|
||||
jobs:
|
||||
docs:
|
||||
name: Book, volumes, API reference
|
||||
|
||||
@@ -20,7 +20,8 @@ on:
|
||||
workflow_dispatch:
|
||||
|
||||
concurrency:
|
||||
group: qemu # one QEMU at a time on the runner: shared with acceptance.yml
|
||||
group: qemu # every workflow shares this one group: one run at a time,
|
||||
# a runner-image rebuild included (Captain Bob, 2026-11-07)
|
||||
cancel-in-progress: false
|
||||
|
||||
jobs:
|
||||
@@ -39,6 +40,18 @@ jobs:
|
||||
fetch-depth: 0 # the SBOM's version is git describe
|
||||
lfs: false # only the logs and DoE CSVs are in LFS; the build needs neither
|
||||
|
||||
- name: The capsule-signing key
|
||||
env:
|
||||
KEY: ${{ secrets.CAPSULE_SIGN_KEY }}
|
||||
run: | # ci/pki/make-ca.sh; kernel/Makefile signs with SIGN_KEY
|
||||
if [ -n "$KEY" ]; then
|
||||
f="${RUNNER_TEMP:-/tmp}/capsule-signing.key"
|
||||
(umask 077; printf '%s\n' "$KEY" > "$f")
|
||||
echo "SIGN_KEY=$f" >> "$GITHUB_ENV"; echo "The capsules will be signed."
|
||||
else
|
||||
echo "::warning::No CAPSULE_SIGN_KEY secret: the capsules are built unsigned."
|
||||
fi
|
||||
|
||||
- name: Acceptance amd64
|
||||
run: scripts/nightly.sh accept amd64
|
||||
- name: Acceptance aarch64
|
||||
|
||||
@@ -14,7 +14,8 @@ on:
|
||||
tags: ['v*']
|
||||
|
||||
concurrency:
|
||||
group: qemu # one QEMU at a time on the runner: shared with acceptance.yml
|
||||
group: qemu # every workflow shares this one group: one run at a time,
|
||||
# a runner-image rebuild included (Captain Bob, 2026-11-07)
|
||||
cancel-in-progress: false
|
||||
|
||||
jobs:
|
||||
@@ -33,6 +34,18 @@ jobs:
|
||||
fetch-depth: 0
|
||||
lfs: false
|
||||
|
||||
- name: The capsule-signing key
|
||||
env:
|
||||
KEY: ${{ secrets.CAPSULE_SIGN_KEY }}
|
||||
run: | # ci/pki/make-ca.sh; kernel/Makefile signs with SIGN_KEY
|
||||
if [ -n "$KEY" ]; then
|
||||
f="${RUNNER_TEMP:-/tmp}/capsule-signing.key"
|
||||
(umask 077; printf '%s\n' "$KEY" > "$f")
|
||||
echo "SIGN_KEY=$f" >> "$GITHUB_ENV"; echo "The capsules will be signed."
|
||||
else
|
||||
echo "::warning::No CAPSULE_SIGN_KEY secret: the capsules are built unsigned."
|
||||
fi
|
||||
|
||||
- name: The tag names the tree's version
|
||||
run: |
|
||||
tree="v$(sed -n 's/^LITHOS_VERSION *?= *//p' kernel/Makefile)"
|
||||
|
||||
@@ -17,6 +17,10 @@ on:
|
||||
paths: ['ci/runner-image/**', 'Makefile']
|
||||
workflow_dispatch:
|
||||
|
||||
concurrency:
|
||||
group: qemu # every workflow shares this one group (Captain Bob, 2026-11-07: a
|
||||
cancel-in-progress: false # runner-image rebuild blocks other jobs, always): one run at a time
|
||||
|
||||
jobs:
|
||||
image:
|
||||
name: Build and publish the runner image
|
||||
@@ -44,7 +48,9 @@ jobs:
|
||||
tag=$(git rev-parse --short=12 HEAD)
|
||||
ctx=$(mktemp -d) # not the repository: 7 GB of context
|
||||
cp -r Makefile boards ci/runner-image/Dockerfile "$ctx/"
|
||||
docker build -t "$img:$tag" "$ctx"
|
||||
tok=$(mktemp); printf '%s' "$TOKEN" > "$tok" # the HOL-Library heap's download (Dockerfile)
|
||||
docker build --secret id=pkgtoken,src="$tok" -t "$img:$tag" "$ctx"
|
||||
rm -f "$tok"
|
||||
echo "$TOKEN" | docker login gitea.starshipos-f18.org -u rajames --password-stdin
|
||||
docker push "$img:$tag"
|
||||
echo "Published $img:$tag"
|
||||
|
||||
@@ -1,5 +1,18 @@
|
||||
# Changelog
|
||||
|
||||
## 2026-11-07 — LithosAnanke v4.0.0-alpha.1: the first alpha release
|
||||
|
||||
The first alpha of the kernel, `v4.0.0-alpha.1`: v4, StarForth's F18 engine, is the system every
|
||||
board boots by default, with v3 a boot argument away. The kernel's version goes from 2.1.0 to the
|
||||
4.x working line (Captain Bob, 2026-11-07); the engine stays 3.2.0. Accepted in full before the tag:
|
||||
amd64, aarch64 and riscv64 to `[zuse@Hera] ok>` with POST 538/538 and one `dict_hash`
|
||||
(`0xfec8c47cfc6f437f`), the PC stick loaded high, `test-32` (39 programs, 0 failures), and the
|
||||
Isabelle/HOL proofs. An alpha: the v4.0.0 milestone's own definition -- parity with v3's vocabulary,
|
||||
K=1.0 measured on v4, the hosted mesh, Verilator -- is still open, and the capsules are unsigned until
|
||||
the StarshipOS CA is made (FABRIC-3.md XLVI). Also today: CI in a prebuilt runner image, the
|
||||
nightly's proofs no longer able to hold back its images, and the .com and .org websites. Full record:
|
||||
`docs/fabric/FABRIC-3.md` XLVII.
|
||||
|
||||
## 2026-11-07 — CI jobs start ready: the runner image
|
||||
|
||||
The CI jobs now run in `lithosananke-runner` (`ci/runner-image`, #120), an image with everything
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Executable
+81
@@ -0,0 +1,81 @@
|
||||
#!/bin/bash
|
||||
# make-ca.sh -- the StarshipOS capsule-signing PKI, made once, on the CI box (Captain Bob,
|
||||
# 2026-11-07: "New root CA on the CI box. Valid StarshipOS rather than snake oil intermediate").
|
||||
#
|
||||
# StarshipOS Root CA Ed25519, 20 years, self-signed. Its key never leaves this box:
|
||||
# not in the repository, not in Gitea, not in any image.
|
||||
# StarshipOS Capsule Signing Ed25519, 10 years, signed by the root; CA:TRUE, pathlen:0.
|
||||
# Its certificate is built into every image (capsules/pki/
|
||||
# starshipos-intermediate.der) and checks each capsule at boot;
|
||||
# its key signs the capsules (mkcapsule --sign-key), in CI from
|
||||
# the repository secret CAPSULE_SIGN_KEY.
|
||||
#
|
||||
# Replaces the offline LithosAnanke Root CA and its snakeoil intermediate (FABRIC-2.md,
|
||||
# Milestone 6) for every build. Run as root:
|
||||
#
|
||||
# sudo ci/pki/make-ca.sh [dir] # dir defaults to /var/lib/starshipos-ca
|
||||
#
|
||||
# It refuses to overwrite an existing CA. When it is done it prints the two certificates (public:
|
||||
# paste them where they are wanted) and says how to put the signing key into Gitea. With
|
||||
# GITEA_TOKEN set (a token that may administer the repository), it stores the secret itself.
|
||||
set -euo pipefail
|
||||
umask 077
|
||||
dir=${1:-/var/lib/starshipos-ca}
|
||||
repo=${GITEA_REPO:-rajames/LithosAnanke}
|
||||
api=${GITEA_API:-https://gitea.starshipos-f18.org/api/v1}
|
||||
|
||||
command -v openssl >/dev/null || { echo "make-ca: needs openssl" >&2; exit 1; }
|
||||
[ -e "$dir/root/root.key" ] && { echo "make-ca: $dir already holds a CA; not overwriting it" >&2; exit 1; }
|
||||
mkdir -p "$dir/root" "$dir/signing"
|
||||
cd "$dir"
|
||||
|
||||
cat > ca.cnf <<'CNF'
|
||||
[ req ]
|
||||
distinguished_name = dn
|
||||
prompt = no
|
||||
[ dn ]
|
||||
[ root_ext ]
|
||||
basicConstraints = critical, CA:TRUE
|
||||
keyUsage = critical, keyCertSign, cRLSign
|
||||
subjectKeyIdentifier = hash
|
||||
[ signing_ext ]
|
||||
basicConstraints = critical, CA:TRUE, pathlen:0
|
||||
keyUsage = critical, keyCertSign, cRLSign, digitalSignature
|
||||
subjectKeyIdentifier = hash
|
||||
authorityKeyIdentifier = keyid:always
|
||||
CNF
|
||||
|
||||
# the root
|
||||
openssl genpkey -algorithm ed25519 -out root/root.key
|
||||
openssl req -new -x509 -key root/root.key -days 7305 -config ca.cnf -extensions root_ext \
|
||||
-subj "/O=StarshipOS/CN=StarshipOS Root CA" -out root/root.pem
|
||||
|
||||
# the capsule-signing intermediate, signed by the root
|
||||
openssl genpkey -algorithm ed25519 -out signing/signing.key
|
||||
openssl req -new -key signing/signing.key -config ca.cnf \
|
||||
-subj "/O=StarshipOS/CN=StarshipOS Capsule Signing" -out signing/signing.csr
|
||||
openssl x509 -req -in signing/signing.csr -CA root/root.pem -CAkey root/root.key \
|
||||
-CAcreateserial -days 3652 -extfile ca.cnf -extensions signing_ext -out signing/signing.pem
|
||||
openssl x509 -in signing/signing.pem -outform DER -out signing/starshipos-intermediate.der
|
||||
openssl verify -CAfile root/root.pem signing/signing.pem
|
||||
|
||||
chmod 700 root signing; chmod 600 root/* signing/*
|
||||
|
||||
if [ -n "${GITEA_TOKEN:-}" ]; then
|
||||
python3 -c 'import json,sys; print(json.dumps({"data": open(sys.argv[1]).read()}))' signing/signing.key |
|
||||
curl -fsS -o /dev/null -X PUT -H "Authorization: token $GITEA_TOKEN" -H 'Content-Type: application/json' \
|
||||
"$api/repos/$repo/actions/secrets/CAPSULE_SIGN_KEY" -d @- &&
|
||||
echo "make-ca: stored the signing key as $repo's secret CAPSULE_SIGN_KEY"
|
||||
else
|
||||
echo "make-ca: put $dir/signing/signing.key, whole, into $repo's Actions secret CAPSULE_SIGN_KEY"
|
||||
echo " (Settings -> Actions -> Secrets), or run again with GITEA_TOKEN set -- after"
|
||||
echo " removing $dir, since it refuses to overwrite a CA."
|
||||
fi
|
||||
echo
|
||||
echo "=== The root certificate (public) -- $dir/root/root.pem"
|
||||
cat root/root.pem
|
||||
echo "=== The capsule-signing certificate (public) -- $dir/signing/signing.pem"
|
||||
cat signing/signing.pem
|
||||
echo "=== Fingerprints"
|
||||
openssl x509 -in root/root.pem -noout -fingerprint -sha256 -subject -enddate
|
||||
openssl x509 -in signing/signing.pem -noout -fingerprint -sha256 -subject -issuer -enddate
|
||||
@@ -1,7 +1,8 @@
|
||||
# The CI runner image (#120): gitea/runner-images' Ubuntu 24.04 with Node -- which
|
||||
# actions/checkout and upload-artifact run on -- plus everything the jobs install at their start:
|
||||
# what `make ARCH=amd64,aarch64,riscv64 init INIT_DOCS=0` installs (taken from the Makefile
|
||||
# itself, not copied, so the two cannot drift), and Maven and a JRE for the publish steps.
|
||||
# itself, not copied, so the two cannot drift), Maven and a JRE for the publish steps, and
|
||||
# Isabelle's HOL-Library already built, for the proofs.
|
||||
#
|
||||
# Built by .gitea/workflows/runner-image.yml, from a context of the Makefile, boards/ and this file.
|
||||
FROM gitea/runner-images:ubuntu-24.04-v26.11.03
|
||||
@@ -11,4 +12,19 @@ WORKDIR /opt/starship-init
|
||||
RUN make --no-print-directory ARCH=amd64,aarch64,riscv64 init INIT_DOCS=0 \
|
||||
&& DEBIAN_FRONTEND=noninteractive apt-get install -y -qq maven default-jre-headless \
|
||||
&& rm -rf /var/lib/apt/lists/* /opt/starship-init/build/cache/downloads
|
||||
# HOL-Library, prebuilt, into Isabelle's own heaps, so the proofs build only the StarForth session
|
||||
# (~2.2 GiB, under a minute). Built from scratch it takes ~5.3 GiB (nightly 174 was killed doing it),
|
||||
# and capped it still needs ~2.6-3.3 GiB: more than the server has. So it is built once, elsewhere,
|
||||
# by the same Isabelle2025-2, and fetched from this repository's package registry, its checksum
|
||||
# pinned here (FABRIC-3.md XLVII). Isabelle ships its own HOL heap the same way. The token is a
|
||||
# build secret (runner-image.yml): it is in neither the image nor its history.
|
||||
ARG HOL_LIBRARY_URL=https://gitea.starshipos-f18.org/api/packages/rajames/generic/isabelle-hol-library/Isabelle2025-2/hol-library-Isabelle2025-2.tar.xz
|
||||
ARG HOL_LIBRARY_SHA256=bb24784664def9379e5db27f88802e3679b8e1c628177f6fbe7084e999cb339e
|
||||
RUN --mount=type=secret,id=pkgtoken \
|
||||
curl -fsSL -H "Authorization: token $(cat /run/secrets/pkgtoken)" -o /tmp/hol-library.tar.xz "$HOL_LIBRARY_URL" \
|
||||
&& echo "$HOL_LIBRARY_SHA256 /tmp/hol-library.tar.xz" | sha256sum -c - \
|
||||
&& heaps=$(isabelle getenv -b ISABELLE_HEAPS_SYSTEM) && mkdir -p "$heaps" \
|
||||
&& xz -dc /tmp/hol-library.tar.xz | tar -C "$heaps" -xf - \
|
||||
&& rm /tmp/hol-library.tar.xz \
|
||||
&& test -s "$heaps/polyml-5.9.2_x86_64_32-linux/HOL-Library"
|
||||
WORKDIR /
|
||||
|
||||
@@ -6061,3 +6061,107 @@ four conflicts resolved to the branch's files (`92ca805e`).
|
||||
- The first scheduled nightly's publish to Nexus (#17).
|
||||
- The Pi 5 and Mars images booted on their boards (#27, #28); a Pi 4 port (#26).
|
||||
- Revoke the access token `claude-session-20261106` (Settings, Applications).
|
||||
|
||||
## XLVI. The StarshipOS CA: capsules signed in CI, by a root on the CI box (2026-11-07)
|
||||
|
||||
### 1. Found
|
||||
|
||||
Every image built anywhere but Captain Bob's machine carried unsigned capsules: CI, the
|
||||
acceptance runs, the nightly bound for Nexus, a release, the demo. The capsule-signing key -- the
|
||||
snakeoil intermediate of the offline LithosAnanke Root CA (FABRIC-2.md, Milestone 6) -- lived only
|
||||
there, `kernel/Makefile`'s `SIGN_KEY` named its path, and a missing signature is a warning by
|
||||
design (2026-08-26), so they booted: `V4: capsule v4:sys:core.f18 signature: missing (unsigned)`
|
||||
in every accepted log (`logs/20261106-004933`). And `mkcapsule` signed with whatever key it was
|
||||
given: a key that is not the embedded certificate's makes every signature INVALID, which refuses
|
||||
Mama.
|
||||
|
||||
### 2. Ruled
|
||||
|
||||
Captain Bob, 2026-11-07: "New root CA on the CI box. Valid StarshipOS rather than snake oil
|
||||
intermediate."
|
||||
|
||||
### 3. Built
|
||||
|
||||
- `ci/pki/make-ca.sh`, run once on the CI box: **StarshipOS Root CA** (Ed25519, 20 years,
|
||||
self-signed; its key stays on that box, in `/var/lib/starshipos-ca`) and **StarshipOS Capsule
|
||||
Signing** (Ed25519, 10 years, issued by the root, `CA:TRUE, pathlen:0`). It refuses to
|
||||
overwrite a CA, prints both certificates, and stores the signing key as the repository secret
|
||||
`CAPSULE_SIGN_KEY` (or says how).
|
||||
- The image carries `capsules/pki/starshipos-intermediate.der` in place of the snakeoil
|
||||
intermediate; the kernel finds it by one name, `CAPSULE_SIGNING_CERT_NAME` (`capsule_sig.h`).
|
||||
- `mkcapsule` checks the signing key against that certificate before it writes anything, and
|
||||
refuses a key that is not its, or a key with no certificate to check.
|
||||
- `SIGN_KEY` has no default (`kernel/Makefile`, `v4/Makefile`): CI sets it from the secret (a step
|
||||
in `acceptance.yml`, `build.yml`, `nightly.yml`, `release.yml`); unset, the capsules are built
|
||||
unsigned, as before.
|
||||
|
||||
What it is not: the kernel still does not check the intermediate against a root at boot
|
||||
(`x509_ed25519.h`; `ACL.4th`'s `ACL-CA-KEY` is still 0). A signature proves a capsule matches the
|
||||
certificate in the same image. That is unchanged by this, and a ruling of its own.
|
||||
|
||||
### 4. Verified
|
||||
|
||||
With a CA made by `make-ca.sh` in a scratch directory (not the real one): `openssl verify` of the
|
||||
chain OK; `make-ca.sh` refuses a second run; `mkcapsule` with the signing key -- "signing key
|
||||
matches"; with the root's key -- refused; with a key and no certificate -- refused; with no key --
|
||||
unsigned, as before. The acceptance with the real certificate is the PR's.
|
||||
|
||||
## XLVII. LithosAnanke v4.0.0-alpha.1: the first alpha release (2026-11-07)
|
||||
|
||||
### 1. Ruled
|
||||
|
||||
Captain Bob, 2026-11-07: "next on the list is do a tag/release of v4.0.0" -- then, on what the number
|
||||
names: "StarForth version stays the same ... Kernel is 4.0.0. This is our first alpha release." The
|
||||
tag names the kernel (`release.yml`: `v<LITHOS_VERSION>`), so:
|
||||
|
||||
- `LITHOS_VERSION` 2.1.0 -> **4.0.0-alpha.1**; the tag is `v4.0.0-alpha.1`; Nexus takes
|
||||
`org.starship:kernelImage:4.0.0-alpha.1` and `org.starship:documentation:4.0.0-alpha.1`.
|
||||
- The engine's `VERSION` stays **3.2.0**.
|
||||
- The versioning policy (`kernel/Makefile`, FABRIC-3.5.md XXX): 4.x is a working line (even major).
|
||||
v3.0.0, the first LTS, is no longer the next number; an LTS line takes the next odd major when
|
||||
XXX.5's criteria are met. Alphas are numbered: a release repository takes each version once.
|
||||
- The v4.0.0 milestone is unchanged: its definition (v4 equivalent to v3, K=1.0 on all three host
|
||||
ISAs, a hosted mesh, Verilator co-simulation) is what 4.0.0 itself will be; nine of its issues
|
||||
are open. This is an alpha of it.
|
||||
- The release is built and proved here first (this session, 15 GiB), its logs committed; the
|
||||
server's release run follows once it can pass -- the proofs need HOL-Library in the runner image.
|
||||
The capsules are unsigned for this release.
|
||||
|
||||
### 2. Verified (this session, `b7534107`, before the tag)
|
||||
|
||||
- amd64 (`logs/20261107-150809`), aarch64 (`-151023`), riscv64 (`-151359`): `LithosAnanke
|
||||
v4.0.0-alpha.1 <arch>`, `[zuse@Hera] ok>`, `PARITY:V4_POST tests=538 pass=538 fail=0`,
|
||||
`POST: PASSED`, Zuse identity confirmed, `PARITY:V4_SYSTEM word_count=317
|
||||
dict_hash=0xfec8c47cfc6f437f` on all three.
|
||||
- The PC stick loaded high (`logs/20261107-151539`): the same, from the stick, no fault.
|
||||
- `make -C v4 test-32`: 39 programs, 0 failures.
|
||||
- The Isabelle/HOL proofs (`logs/20261107-152312/isabelle`).
|
||||
- Each v4 capsule logs `signature: no root key (cert not found/parseable)`: the kernel looks for the
|
||||
StarshipOS Capsule Signing certificate (XLVI), which is not in the tree until `ci/pki/make-ca.sh`
|
||||
has run. A warning, as "missing (unsigned)" was before; nothing is refused.
|
||||
|
||||
### 3. The StarshipOS CA, and acceptance again (`4ca935d8`)
|
||||
|
||||
`ci/pki/make-ca.sh` ran on the CI box (2026-11-07 16:50 UTC): the StarshipOS Root CA there, the
|
||||
signing key in the secret `CAPSULE_SIGN_KEY`, and the certificate -- O=StarshipOS, CN=StarshipOS
|
||||
Capsule Signing, issued by the root, 2026-11-07 to 2036-11-06, `CA:TRUE, pathlen:0`, SHA-256 of the
|
||||
DER `13a28dda...029b9a6c` -- in the tree as `capsules/pki/starshipos-intermediate.der`, the snakeoil
|
||||
intermediate out of it. The tree changed, so the protocol ran again here: amd64
|
||||
(`logs/20261107-165611`), aarch64 (`-165817`), riscv64 (`-170149`) -- POST 538/538,
|
||||
`dict_hash=0xfec8c47cfc6f437f` on all three; the stick loaded high (`-170326`); `test-32`, 39
|
||||
programs, 0 failures; the proofs (`-171020`). Each capsule now logs `signature: missing (unsigned)`:
|
||||
the kernel found and read the StarshipOS certificate (it said "no root key" without it), and this
|
||||
session has no key to sign with. CI signs with the secret: the PR's acceptance and the release are
|
||||
where every capsule first verifies.
|
||||
|
||||
### 4. HOL-Library, prebuilt
|
||||
|
||||
The runner image was to build HOL-Library itself (XLVI's companion change, `4ae1f759`); the server
|
||||
cannot: from scratch it peaks at ~5.3 GiB, and with Poly/ML capped at 1.6 GiB the build still needs
|
||||
Isabelle's Java side at ~1 GiB (at 384 MiB it ran out and hung) -- 2.6-3.3 GiB against the server's
|
||||
3.8 GiB in all, ~2.3 GiB free with both wikis stopped. So the heap built here by the same
|
||||
Isabelle2025-2 (HOL-Library and its build database) is a package in this repository's registry,
|
||||
`generic/isabelle-hol-library/Isabelle2025-2/hol-library-Isabelle2025-2.tar.xz` (45 MB, SHA-256
|
||||
`bb247846...e999cb339e`), and the image fetches it into Isabelle's system heaps, checksum pinned,
|
||||
its token a Docker build secret. Shown portable first: a fresh Isabelle home holding only that heap
|
||||
checks the StarForth session without rebuilding HOL-Library (24 s).
|
||||
|
||||
+14
-8
@@ -89,6 +89,12 @@ endif
|
||||
# v2.2.0 — amd64 bare-metal bring-up (Beelink SER5)
|
||||
# v2.x — further working releases; riscv64 / aarch64 board bring-up
|
||||
# v3.0.0 — FIRST LTS, when and only when FABRIC-3.5.md §XXX.5's 5 criteria are met
|
||||
# v4.0.0-alpha.1 — the first alpha release (Captain Bob, 2026-11-07: "Kernel is 4.0.0. This is
|
||||
# our first alpha release"): v4, the F18 engine, the default system. The kernel goes
|
||||
# from v2.1.0 straight to the 4.x working line (even: breaking changes land here);
|
||||
# v3.0.0, the first LTS, is no longer the next number -- an LTS line takes the next
|
||||
# odd major when §XXX.5's criteria are met. The engine stays 3.2.0. Alphas are
|
||||
# numbered (-alpha.N); a release repository takes each version once.
|
||||
# LITHOS_VERSION (kernel) and VERSION (embedded StarForth engine) are independent
|
||||
# and do not auto-sync (§XXX.4) — do not infer a relationship if they ever coincide.
|
||||
# Engine VERSION bumps at tag time by what actually changed (§XXX.6): major = any
|
||||
@@ -97,7 +103,7 @@ endif
|
||||
# the messaging layer was replaced by kernel-Hermes, PLOT/FB-* relocated to Hestia —
|
||||
# all dictionary-visible, no FORTH-79 word semantics changed.
|
||||
VERSION ?= 3.2.0
|
||||
LITHOS_VERSION ?= 2.1.0
|
||||
LITHOS_VERSION ?= 4.0.0-alpha.1
|
||||
|
||||
# ==============================================================================
|
||||
# BUILD PATHS
|
||||
@@ -207,7 +213,8 @@ MKCAPSULE_SRC = tools/mkcapsule.c tools/pkcs8_ed25519.c \
|
||||
kernel/src/crypto/ed25519.c \
|
||||
kernel/src/crypto/fe25519.c \
|
||||
kernel/src/crypto/scalar25519.c \
|
||||
kernel/src/crypto/sha512.c
|
||||
kernel/src/crypto/sha512.c \
|
||||
kernel/src/crypto/x509_ed25519.c
|
||||
MKCAPSULE_BIN = $(BUILD_DIR)/tools/mkcapsule
|
||||
# mkartemis: formats and signs an Artemis partition at build with the kernel's own
|
||||
# block-subsystem and artemis_sig code (tools/mkartemis.c), built as v4/Makefile builds them.
|
||||
@@ -215,12 +222,11 @@ MKARTEMIS_SRC = tools/mkartemis.c kernel/src/artemis_sig.c \
|
||||
$(addprefix v3/src/,block_subsystem.c blkio_ram.c blkio_file.c log.c \
|
||||
platform/platform_init.c platform/linux/time.c)
|
||||
MKARTEMIS_BIN = $(BUILD_DIR)/tools/mkartemis
|
||||
# Milestone 6 (Phase 8): the snakeoil intermediate's private key, generated
|
||||
# offline outside this repo entirely (see FABRIC-2.md's Phase 8 §Milestone 6
|
||||
# writeup) -- not present in CI or a fresh checkout, so signing is skipped
|
||||
# gracefully ($(wildcard ...) below) rather than failing the build. Override
|
||||
# with `make SIGN_KEY=/path/to/key.pem ...` on a machine that holds it.
|
||||
SIGN_KEY ?= /home/rajames/CLionProjects/lithosananke-ca/intermediate/snakeoil-intermediate.key
|
||||
# The capsule-signing key: "StarshipOS Capsule Signing"'s private key (ci/pki/make-ca.sh,
|
||||
# FABRIC-3.md XLVI). CI sets SIGN_KEY from the secret CAPSULE_SIGN_KEY; elsewhere set it by hand
|
||||
# (`make SIGN_KEY=/path/to/signing.key ...`). Unset or absent, the capsules are built unsigned,
|
||||
# which boots with a warning per capsule. mkcapsule refuses a key that is not the certificate's.
|
||||
SIGN_KEY ?=
|
||||
SIGN_KEY_ARGS = $(if $(wildcard $(SIGN_KEY)),--sign-key $(SIGN_KEY),)
|
||||
CAPSULE_GENERATED = $(BUILD_DIR)/capsule_generated.c
|
||||
CAPSULE_GENERATED_OBJ = $(BUILD_DIR)/capsule_generated.o
|
||||
|
||||
@@ -171,7 +171,8 @@ typedef struct {
|
||||
*
|
||||
* Milestone 6 (Phase 8): each capsule's payload bytes (the same bytes
|
||||
* content_hash already covers), signed by mkcapsule at build time with
|
||||
* the snakeoil intermediate's private key. has_sig=0 for a capsule built
|
||||
* the capsule-signing key (StarshipOS Capsule Signing, capsule_sig.h;
|
||||
* the snakeoil intermediate's until 2026-11-07). has_sig=0 for a capsule built
|
||||
* before this feature existed or otherwise unsigned -- a real, distinct
|
||||
* state, not "signature is all-zero bytes" (which sig[64] full of 0x00
|
||||
* would otherwise look ambiguous with). Indexed 1:1 with
|
||||
|
||||
@@ -22,6 +22,12 @@
|
||||
|
||||
#include "starkernel/capsule.h"
|
||||
|
||||
/* The certificate whose key the capsules are signed with: "StarshipOS
|
||||
* Capsule Signing", issued by the StarshipOS Root CA (ci/pki/make-ca.sh;
|
||||
* FABRIC-3.md XLVI), replacing the snakeoil intermediate of Milestone 6.
|
||||
* mkcapsule refuses to sign with a key that is not this certificate's. */
|
||||
#define CAPSULE_SIGNING_CERT_NAME "pki:starshipos-intermediate.der"
|
||||
|
||||
typedef enum {
|
||||
CAPSULE_SIG_OK = 0, /* has_sig=1, and it verifies */
|
||||
CAPSULE_SIG_MISSING, /* has_sig=0 -- not signed at all */
|
||||
@@ -31,9 +37,9 @@ typedef enum {
|
||||
|
||||
/*
|
||||
* Verify capsule descs[index]'s Ed25519 signature against the embedded
|
||||
* snakeoil intermediate cert's public key (capsule name
|
||||
* "pki:snakeoil-intermediate.der", found and parsed once, cached for
|
||||
* every later call this boot -- the cert doesn't change mid-boot).
|
||||
* capsule-signing certificate's public key (CAPSULE_SIGNING_CERT_NAME,
|
||||
* found and parsed once, cached for every later call this boot -- the
|
||||
* cert doesn't change mid-boot).
|
||||
*
|
||||
* descs/names/sigs must be the same three parallel arrays
|
||||
* (capsule_get_descriptors()/capsule_get_names()/capsule_get_signatures()),
|
||||
|
||||
@@ -6,9 +6,10 @@
|
||||
*
|
||||
* x509_extract_ed25519_pubkey() only ever reads SubjectPublicKeyInfo --
|
||||
* no signature verification, no chain validation, no extension parsing.
|
||||
* That's the capsule-PKI use case (Milestone 6): the embedded snakeoil
|
||||
* intermediate cert is trusted because it's baked into the trusted build,
|
||||
* never re-verified against the offline root CA at boot.
|
||||
* That's the capsule-PKI use case (Milestone 6): the embedded capsule-
|
||||
* signing cert (StarshipOS Capsule Signing since 2026-11-07, the snakeoil
|
||||
* intermediate before it) is trusted because it's baked into the trusted
|
||||
* build, never re-verified against its root CA at boot.
|
||||
*
|
||||
* x509_verify_signature()/x509_extract_serial() (added 2026-08-28,
|
||||
* FABRIC-2.md §F.7/§F.17) are for CERTVERIFY -- a regular user's cert,
|
||||
|
||||
@@ -4,8 +4,6 @@
|
||||
#include "starkernel/ed25519.h"
|
||||
#include <string.h>
|
||||
|
||||
#define SNAKEOIL_CERT_NAME "pki:snakeoil-intermediate.der"
|
||||
|
||||
/* Cached once per boot: the cert doesn't change mid-boot, and every
|
||||
* capsule birth (Mama, then every child VM) would otherwise re-find and
|
||||
* re-parse the same cert. -1 = not yet attempted, 0 = failed, 1 = ready. */
|
||||
@@ -20,7 +18,7 @@ static int find_and_cache_pubkey(const CapsuleDesc *descs,
|
||||
|
||||
pubkey_state = 0; /* assume failure unless every step below succeeds */
|
||||
for (uint32_t i = 0; i < desc_count; i++) {
|
||||
if (strcmp(names[i].name, SNAKEOIL_CERT_NAME) == 0) {
|
||||
if (strcmp(names[i].name, CAPSULE_SIGNING_CERT_NAME) == 0) {
|
||||
const CapsuleDesc *cert_desc = &descs[i];
|
||||
if (x509_extract_ed25519_pubkey(arena_base + cert_desc->offset,
|
||||
(size_t)cert_desc->length,
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user