From 0316573226393dc1966667e8d88e29cb7d72e39e Mon Sep 17 00:00:00 2001 From: rajames Date: Fri, 6 Nov 2026 17:13:30 +0000 Subject: [PATCH 1/2] docs: FABRIC-3.md XLV and CHANGELOG -- one process from developer to master (2026-11-06) The day's record, in FABRIC-3.md's own form (ruled, found, built, verified, open): the review's three v4 bugs; the logs and DoE CSVs put into LFS; make init with syft and Isabelle2025-2; the Doxygen fix; the nightlies, the release and the Nexus coordinates (org.starship:kernelImage and :documentation, classifier by board); the runner's Debian 11 default found and every job moved to Ubuntu 24.04; the acceptance gate and master's protection; the StarForth repository archived as a tag and deleted, this one renamed LithosAnanke; Gitea's labels, milestones, issues #4-#29 and PR #30; what is still open. CHANGELOG.md: the same, in one paragraph. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01GE3SDvQn5EoxdGufk84zz2 --- CHANGELOG.md | 15 +++++ docs/fabric/FABRIC-3.md | 119 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 134 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index fdaa8579..9d569aff 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,20 @@ # Changelog +## 2026-11-06 — One process from developer to master: the acceptance gate, the nightlies to Nexus, one repository + +Every pull request into `master` now runs the acceptance protocol (`acceptance.yml`): the three +ISA boots, the PC stick loaded high, `test-32`, through the same `scripts/nightly.sh` stages a +developer runs by hand. `master` is protected: no direct pushes, and nothing merges unless that +check passed. The nightly (03:00 UTC) runs the same protocol plus the proofs and publishes the +board images to Nexus as `org.starship:kernelImage:2.1.0-SNAPSHOT` (classifiers `pc`, `raspi5`, +`milkv`, `logs`); the documents follow at 04:00 as `org.starship:documentation`; a `v` +tag publishes a release. CI jobs now run on Ubuntu 24.04 -- the runner's default was Debian 11, +where every job had failed. `make ARCH= init` installs the whole toolchain, syft and +Isabelle2025-2 included; the Doxygen API reference builds again. Three v4 bugs fixed (line input +on both front ends; a refused store moving A or P). The StarForth repository's history is kept as +the tag `archive/starforth-2026-09-17` and the repository deleted; this one is renamed +`LithosAnanke`. Full record: `docs/fabric/FABRIC-3.md` XLV. + ## 2026-10-09 — StarForth v4.0.0 Step 6e review and wire refinement Implemented whole-message handling on the engine wire (`d5cd6460`), ensured nodes only process one message at a time (`b1d09af0`), and refined message processing logic (`6a7d0aa2`, `f1419e73`). Fixed wake-up order, room checks, and overflow issues during message transit (`83694b18`). diff --git a/docs/fabric/FABRIC-3.md b/docs/fabric/FABRIC-3.md index 7bd35c0f..d41d95c9 100644 --- a/docs/fabric/FABRIC-3.md +++ b/docs/fabric/FABRIC-3.md @@ -5942,3 +5942,122 @@ and a 3 GiB boot added to acceptance. Not covered by QEMU: a load above 4 GiB (OVMF keeps images below it). The relocation check covers that case statically -- no 32-bit absolute is left to break there. + +## XLV. One process from the developer to master: the acceptance gate, the nightlies, Nexus, and Gitea used as more than a repo (2026-11-06) + +**Ruled** (Captain Bob, 2026-11-06). What a developer runs by hand, what a pull request into +`master` runs, and what the nightly runs are one process -- the acceptance protocol -- and +"failures should not be allowed to be merged to master". Neither agile nor waterfall: the +**Captain Bob method**. The images go to Nexus nightly as +`org.starship:kernelImage:-SNAPSHOT`. The StarForth repository goes; LithosAnanke +holds everything. Gitea is used for issues, milestones, a project board and pull requests -- not +its wiki: the `.org` XWiki is the project's entry point, the `.com` its public face. + +### 1. The review, and three bugs fixed + +A static review of the v4 golden model (2026-11-02) found, among smaller things, three bugs, fixed +in `fd208825`: the hosted front end ran the tail of an over-long line as a line of its own; the +bare-metal line editor cut a line silently at 255 characters and ran it; and a store the node +itself refuses (to "any port", "which port", How or Have) went on to move A (`!+`) or P (`!p`), +so `!p` landed in the next fault kind's handler. A regression test (`v4/tests/test_port.c`) fails +on the old `exec.c`. The rest of the review is filed as issues (section 7). + +### 2. Logs and DoE CSVs in LFS, as `.gitattributes` always said + +**Found.** 1,003 `.log` and DoE `.csv` files were committed as plain files although +`.gitattributes` routes them through LFS (3,944 others are pointers), so every fresh clone showed +them modified. **Built.** `git add --renormalize` (`027b144e`); each pointer's oid is the sha256 of +the file it replaced. `make init` now runs `git lfs install --local`, the cause being a checkout +without git-lfs. `master` keeps 23 such files until it is merged. + +### 3. `make ARCH=[,...] init` + +Installs what the tree needs on Debian/Ubuntu (`d8e3fa81`, `4cef0431`): the build and disk-image +tools, git-lfs, the documents' toolchain, and per ISA its QEMU, UEFI firmware and compiler. +syft 1.52.0 (the version `sbom.spdx` was made with) and Isabelle2025-2 (the version +`proof/COVERAGE.md` names) are not packaged: downloaded, checked against a SHA-256 in the +Makefile, kept in `build/cache/`, linked into `/usr/local/bin`. Isabelle publishes no sums; its are +of the archives as downloaded on 2026-11-06. `INIT_DOCS=0` leaves out TeX, Doxygen and Isabelle. +Verified: the proofs build from it (`logs/20261106-015650/isabelle`), and so do the book, the +formal volumes and -- after `5b58b0b1` -- the Doxygen API reference: `fix-doxygen-unicode.py` had +turned the Unicode characters of Doxygen's own `\doxynewunicodechar` lines into `?`, which +`newunicodechar` refuses. + +### 4. The nightlies, the release, Nexus + +`scripts/nightly.sh` is the process, a stage per step, each run the same by hand or by CI: +`accept `, `test-32`, `proofs`, `images`, `publish `, +`docs`, `publish-docs `. `accept` is `scripts/qemu_session.py zuse` (and `stick_zuse +--target qemu-stick-high`), one QEMU at a time, in the protocol's order; `stick-high` also refuses +a run whose three architectures disagree on `dict_hash`. Workflows: + +| Workflow | When | What | +|---|---|---| +| `nightly.yml` | 03:00 UTC | acceptance, `test-32`, proofs, images, then `starshipos-snapshots` | +| `nightly-docs.yml` | 04:00 UTC | the documents, then `starshipos-snapshots` | +| `release.yml` | a tag `v` | the same, to `starshipos-releases`; a tag naming another version is refused | +| `acceptance.yml` | every PR into `master` | the acceptance protocol (section 5) | +| `build.yml` | every push | the board images and `make -C v4 test`; publishes nothing | + +Coordinates, one deploy and one timestamp each (`mvn deploy:deploy-file`, maven-deploy-plugin +3.1.2, so Maven's snapshot metadata is right): + +- `org.starship:kernelImage` -- classifier `pc` (`StarshipOS.iso`: the ISO the amd64 boot + booted, byte for byte), `raspi5` (`raspi5.img.xz`, for Raspberry Pi Imager), `milkv` + (`MilkV.img.xz`, the Mars), `logs` (the run's serial logs, proof log and DoE CSVs). +- `org.starship:documentation` -- classifier `book`, `vol1`, `vol2`, `vol3`, `api`. + +The classifier is the board, not the ISA as first asked: two aarch64 boards would collide. There +is no Raspberry Pi 4 image -- there is no BCM2711 port (#26). QEMU boots the aarch64 and riscv64 +kernels, not the Pi 5 and Mars images. + +**Verified** by hand, each stage in order (`deb71fae`, `d185b644`), and both deploys against a +local `file://` repository: the timestamped files, the POMs, and `maven-metadata.xml` with a +`snapshotVersion` per classifier. **Not verified:** Nexus itself, which asks a login even to read +(#17). The first scheduled run is the test. + +### 5. The gate on `master` + +**Found** (2026-11-06). Every CI job ever run here failed at its first `apt-get`: the runner maps +`runs-on: ubuntu-latest` to `node:20-bullseye`, Debian 11 -- where one security update would not +fetch, and which has no `qemu-efi-riscv64` and a far older QEMU and compilers than the Ubuntu 24.04 +everything was tested on. **Built** (`6eadd2f5`): every job names its container, +`gitea/runner-images:ubuntu-24.04-v26.11.03` (Ubuntu 24.04 with the Node that `actions/checkout` +and `upload-artifact` run on; the dated tag so an image update cannot change a run). The first +jobs on it all passed (run 150: the three images, and `make -C v4 test` at both widths). + +`acceptance.yml` (`0fd7648a`) runs `.claude/CLAUDE.md`'s protocol on every PR into `master`, +through the same `nightly.sh` stages. `acceptance`, `nightly` and `release` share the concurrency +group `qemu`, so the runner never runs two at once: the one-QEMU rule holds in CI. `master`'s +branch protection: no push or force push by anyone; merging requires +`Acceptance / Acceptance (pull_request)`; the PR must be up to date with `master`; no approval while +there is one developer; the admin override blocked. `.claude/CLAUDE.md`'s Hard Rules say the same. + +### 6. One repository + +The StarForth repository's `master` (658 commits, last `9aebbb22`, 2026-09-17) was never part of +LithosAnanke's history. It is kept as the annotated tag `archive/starforth-2026-09-17`, verified +by a fresh fetch from LithosAnanke (same tip, same 658 commits, same first commit), and the +repository deleted. It had no issues, pull requests, releases, packages, wiki pages, secrets or +webhooks. + +The repository itself had been created as `rajames/LithosAnanake`, a typo for the project's name. +Renamed on the server to `rajames/LithosAnanke` (disk and database, Captain Bob, 2026-11-06), with a +redirect from the old name, so remotes using it still work. Earlier mentions of +`admin/LithosAnanake` in the docs record where things were at the time and are left as they are. + +### 7. Gitea + +Wiki off; description and website (the XWiki) set. Labels in scoped sets -- `kind/` and `priority/` +exclusive, `area/`, `board/`, `status/`. Milestones `v4.0.0` (JUSTIFICATION.md section 14) and +`Board bring-up`. Issues #4-#29: the v4 gaps to v4.0.0 (#4-#9), the rest of the review, the CI +items, the merge (#19), the boards (#26-#29). The project board has no API in this Gitea: it is +made in the web UI (Projects, Basic Kanban). PR #30 merges `StarForth-v4.0.0` into `master`; its +four conflicts resolved to the branch's files (`92ca805e`). + +### 8. Open + +- PR #30's acceptance run (run 153) -- the first QEMU boots on the runner. It merges when green. +- 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). From c1bc1c80418668b3bfad7dd9cde3cc892a8dc656 Mon Sep 17 00:00:00 2001 From: rajames Date: Fri, 6 Nov 2026 17:15:25 +0000 Subject: [PATCH 2/2] gitea: issue forms and a PR template, in the project's own form Issues follow the record's Found / Ruled / Built / Verified (docs/fabric/FABRIC-3.md): the reporter writes what was found and its evidence; Captain Bob rules; the commits build it; the acceptance logs verify it. A finding is not a request to fix it (.claude/CLAUDE.md). .gitea/ISSUE_TEMPLATE/ 1-bug.yaml Found, where, system (v4/v3), seen on (ISA, stick, hardware), evidence (the log lines), how found 2-work.yaml what, why (the ruling or design section), done when (with the acceptance protocol and its logs), area, priority 3-ruling.yaml the question, the options and their costs, a recommendation, where the ruling will be recorded, what waits on it 4-board.yaml board, the image booted (Nexus version or commit), what happened, the serial log, the BRINGUP.md item config.yaml blank issues still allowed; the XWiki linked for design and discussion .gitea/pull_request_template.md what and why, Closes #, acceptance (the check runs itself; hand-run logs; hardware), the record (FABRIC-3.md, CHANGELOG), no unrequested fixes Gitea reads these from the default branch: they apply once on master. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01GE3SDvQn5EoxdGufk84zz2 --- .gitea/ISSUE_TEMPLATE/1-bug.yaml | 53 +++++++++++++++++++++++++++++ .gitea/ISSUE_TEMPLATE/2-work.yaml | 40 ++++++++++++++++++++++ .gitea/ISSUE_TEMPLATE/3-ruling.yaml | 41 ++++++++++++++++++++++ .gitea/ISSUE_TEMPLATE/4-board.yaml | 38 +++++++++++++++++++++ .gitea/ISSUE_TEMPLATE/config.yaml | 6 ++++ .gitea/pull_request_template.md | 20 +++++++++++ 6 files changed, 198 insertions(+) create mode 100644 .gitea/ISSUE_TEMPLATE/1-bug.yaml create mode 100644 .gitea/ISSUE_TEMPLATE/2-work.yaml create mode 100644 .gitea/ISSUE_TEMPLATE/3-ruling.yaml create mode 100644 .gitea/ISSUE_TEMPLATE/4-board.yaml create mode 100644 .gitea/ISSUE_TEMPLATE/config.yaml create mode 100644 .gitea/pull_request_template.md diff --git a/.gitea/ISSUE_TEMPLATE/1-bug.yaml b/.gitea/ISSUE_TEMPLATE/1-bug.yaml new file mode 100644 index 00000000..77cb378e --- /dev/null +++ b/.gitea/ISSUE_TEMPLATE/1-bug.yaml @@ -0,0 +1,53 @@ +name: Bug +about: Something is wrong. Report it as found -- it is fixed only when Captain Bob says so. +title: "[bug] " +labels: ["kind/bug"] +body: + - type: markdown + attributes: + value: | + Write what was **found**, with its evidence. The rest of the issue follows the project's + record (`docs/fabric/FABRIC-3.md`): **Ruled** (Captain Bob decides whether and how it is + fixed), **Built** (the commits), **Verified** (the acceptance logs). A finding is not a + request to fix it (`.claude/CLAUDE.md`, Hard Rules). + - type: textarea + id: found + attributes: + label: Found + description: What is wrong, and what happens because of it. Concrete input and the wrong output, crash or hang. + validations: + required: true + - type: input + id: where + attributes: + label: Where + description: File and line, or the word, capsule or board. + placeholder: "v4/src/exec.c:182" + validations: + required: true + - type: dropdown + id: system + attributes: + label: System + options: ["v4 (the default)", "v3 (system=v3)", "both", "the build or CI", "not specific"] + validations: + required: true + - type: dropdown + id: isa + attributes: + label: Seen on + multiple: true + options: ["amd64", "aarch64", "riscv64", "32-bit build (test-32)", "the PC stick", "hosted", "real hardware"] + - type: textarea + id: evidence + attributes: + label: Evidence + description: The serial log (`logs///...`), the failing test, or the steps that reproduce it. Logs are the evidence; paste the lines that matter. + render: text + validations: + required: true + - type: textarea + id: how + attributes: + label: How it was found + description: A boot, a test, a review, real hardware. diff --git a/.gitea/ISSUE_TEMPLATE/2-work.yaml b/.gitea/ISSUE_TEMPLATE/2-work.yaml new file mode 100644 index 00000000..e5dc9d89 --- /dev/null +++ b/.gitea/ISSUE_TEMPLATE/2-work.yaml @@ -0,0 +1,40 @@ +name: Work item +about: A piece of planned work -- a step of a design, or something a ruling asked for. +title: "" +labels: ["kind/feature"] +body: + - type: textarea + id: goal + attributes: + label: What + description: The work, in a sentence or two. + validations: + required: true + - type: textarea + id: why + attributes: + label: Why -- the ruling or the design it comes from + description: Captain Bob's ruling (quoted, with its date) or the document and section, e.g. `docs/v4.0.0/ENGINE.md` section 5, step 3. + validations: + required: true + - type: textarea + id: done + attributes: + label: Done when + description: What will be true, and how it is shown. Every change to the kernel or v4 is accepted by the acceptance protocol -- the three ISA boots, the PC stick loaded high, test-32 -- with its logs committed. + value: | + - [ ] + - [ ] Acceptance passes, logs in `logs/` + validations: + required: true + - type: dropdown + id: area + attributes: + label: Area + multiple: true + options: ["kernel", "v4", "v3", "capsules", "proofs", "docs", "CI and build"] + - type: dropdown + id: priority + attributes: + label: Priority + options: ["must -- needed for the milestone", "should -- needed for the product", "nice to have"] diff --git a/.gitea/ISSUE_TEMPLATE/3-ruling.yaml b/.gitea/ISSUE_TEMPLATE/3-ruling.yaml new file mode 100644 index 00000000..7dc9886c --- /dev/null +++ b/.gitea/ISSUE_TEMPLATE/3-ruling.yaml @@ -0,0 +1,41 @@ +name: Ruling needed +about: A decision only Captain Bob can make -- an open question, a trade-off, a design choice. +title: "[ruling] " +labels: ["status/blocked"] +body: + - type: markdown + attributes: + value: | + Lay out the question so it can be ruled on. The ruling is recorded as it always is -- + **Ruled (Captain Bob, date)** -- in the document it belongs to, and the issue closed with a + link to that record. + - type: textarea + id: question + attributes: + label: The question + validations: + required: true + - type: textarea + id: options + attributes: + label: The options, and what each costs + description: Each choice with its consequences -- code size, speed, what it rules out later. + validations: + required: true + - type: textarea + id: recommendation + attributes: + label: Recommendation + description: Which option, and why. A recommendation, not a decision. + - type: input + id: record + attributes: + label: Where the ruling will be recorded + placeholder: "docs/v4.0.0/DECOMPOSITION.md section 3, D-4" + validations: + required: true + - type: textarea + id: waits + attributes: + label: What waits on it + description: Issues or work that cannot go on until this is ruled. diff --git a/.gitea/ISSUE_TEMPLATE/4-board.yaml b/.gitea/ISSUE_TEMPLATE/4-board.yaml new file mode 100644 index 00000000..4be15b3f --- /dev/null +++ b/.gitea/ISSUE_TEMPLATE/4-board.yaml @@ -0,0 +1,38 @@ +name: Board bring-up +about: A board on real hardware -- a first boot, a failure, a step of boards/BRINGUP.md. +title: "[board] " +labels: ["kind/feature"] +body: + - type: dropdown + id: board + attributes: + label: Board + options: ["PC (SER5)", "Raspberry Pi 5", "Raspberry Pi 4 (not ported)", "Milk-V Mars", "Zynq-7020", "other"] + validations: + required: true + - type: input + id: image + attributes: + label: Image + description: Which image was booted -- the nightly's Nexus version, or the commit it was built from. + placeholder: "kernelImage-2.1.0-20261107.030000-1-raspi5.img.xz, or 0fd7648a" + validations: + required: true + - type: textarea + id: found + attributes: + label: What happened + description: How far it got -- the last line seen on serial or screen. + validations: + required: true + - type: textarea + id: log + attributes: + label: Serial log + description: The whole log if there is one; where it is committed (`logs//...`). + render: text + - type: input + id: bringup + attributes: + label: boards/BRINGUP.md item + placeholder: "A1, S3, ..." diff --git a/.gitea/ISSUE_TEMPLATE/config.yaml b/.gitea/ISSUE_TEMPLATE/config.yaml new file mode 100644 index 00000000..0e74d1c6 --- /dev/null +++ b/.gitea/ISSUE_TEMPLATE/config.yaml @@ -0,0 +1,6 @@ +# The issue picker. A blank issue is still allowed, for anything the forms do not fit. +blank_issues_enabled: true +contact_links: + - name: Design, documentation and discussion -- the project wiki + url: https://www.starshipos-f18.org/ + about: The XWiki is the project's entry point. Issues here are for work in this repository. diff --git a/.gitea/pull_request_template.md b/.gitea/pull_request_template.md new file mode 100644 index 00000000..6e1c8148 --- /dev/null +++ b/.gitea/pull_request_template.md @@ -0,0 +1,20 @@ +## What and why + + + +Closes # + +## Acceptance + +The **Acceptance** check runs on this pull request by itself -- amd64, aarch64, riscv64, the PC +stick loaded high, test-32 -- and `master` takes nothing that has not passed it. Note here +anything it does not cover: + +- [ ] Logs from runs made by hand are committed in `logs/`, if any +- [ ] Hardware this was tried on, if any: + +## The record + +- [ ] `docs/fabric/FABRIC-3.md` has the ruling and what was built, if this is design work +- [ ] `CHANGELOG.md`, if it is a milestone +- [ ] Nothing in this PR is a fix nobody asked for (`.claude/CLAUDE.md`, Hard Rules)