Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
9c5ba12
a lock records one entry per identity, spelled as 2026.9.28.3 spelled…
speak-agent Sep 29, 2026
8f63e6b
a bare key of a path or git dependency states only the short name, an…
speak-agent Sep 29, 2026
a62de28
docs: the build output refinement design (revision 3 of the build pro…
speak-agent Sep 29, 2026
3cb6a3a
a build names each package when it does work, and the status row is d…
speak-agent Sep 29, 2026
e4854d8
docs: the build output design records review rounds 8 and 9: the four…
speak-agent Sep 29, 2026
d7491c1
--play-game plays snake, stack or runner in the status row, and the e…
speak-agent Sep 29, 2026
938bcbf
2026.9.30.1: the docs and CHANGELOG state the build output of revisio…
speak-agent Sep 29, 2026
a56f81f
docs: the build output design states the record and the announcement …
speak-agent Sep 29, 2026
6ea9ba0
a download bar outside a report is drawn when its download starts; th…
speak-agent Sep 29, 2026
bf7ab6a
repository layout: the Windows resource script of mcpp.exe moves to d…
speak-agent Sep 29, 2026
8fad76c
e2e 845 records the terminal's mode from a shell in the session: macO…
speak-agent Sep 29, 2026
08b6c0e
e2e 845 does not compare PENDIN, which the BSD kernel sets whenever I…
speak-agent Sep 29, 2026
f95d8e7
docs: the build output design of revision 3 is landed (#743, 2026.9.3…
speak-agent Sep 29, 2026
fcc0fad
--play-game reads keys only in the terminal's foreground, and a key s…
speak-agent Sep 29, 2026
6bd9038
docs: the build output design states that decisions D3 and D4 were no…
speak-agent Sep 29, 2026
72a9a51
docs: the build output design records decision D3 as no change
speak-agent Sep 29, 2026
83af60d
Finished states how the time was spent from one minute, names the lon…
speak-agent Sep 29, 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
3 changes: 3 additions & 0 deletions .agents/docs/2026-09-29-build-progress-display-design.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@ status: landed
# Build progress: each step's line states its outcome, and one status line states the build

- Status: landed (revision 2). Implemented in #742, released as 2026.9.29.5
(the parts listed in section 6 of
`2026-09-30-build-output-refinement-design.md` are replaced by revision 3,
#743, 2026.9.30.1)
- Date: 2026-09-29
- Origin: the cross-verification of #742 on the validation project (run
36562019799). `mcpp build --workspace` printed its last `Compiling` line at
Expand Down
1,531 changes: 1,531 additions & 0 deletions .agents/docs/2026-09-30-build-output-refinement-design.md

Large diffs are not rendered by default.

4 changes: 3 additions & 1 deletion .agents/docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ superseded_by: 2026-09-07-....md # when status is superseded
---
```

318 records.
319 records.

## By subject

Expand All @@ -30,6 +30,7 @@ Records that declare one. Everything else is listed by date below.

### design

- [Build output, revision 3: every package that does work is named, the live display is one line drawn in one write, and a repeated warning is stated once per file](2026-09-30-build-output-refinement-design.md) — landed
- [The workspace as the unit of build: one graph per configuration, one scheduler, product directories, and a reusable graph module](2026-09-29-workspace-build-graph-design.md) — landed
- [Build progress: each step's line states its outcome, and one status line states the build](2026-09-29-build-progress-display-design.md) — landed
- [An ecosystem design for mcpp and xlings: one authority per fact, and the work that follows from it](2026-09-28-ecosystem-design-and-optimisation-plan.md) — landed
Expand Down Expand Up @@ -109,6 +110,7 @@ Records that declare one. Everything else is listed by date below.

### 2026-09

- [Build output, revision 3: every package that does work is named, the live display is one line drawn in one write, and a repeated warning is stated once per file](2026-09-30-build-output-refinement-design.md) — landed
- [The workspace as the unit of build: one graph per configuration, one scheduler, product directories, and a reusable graph module](2026-09-29-workspace-build-graph-design.md) — landed
- [Build progress: each step's line states its outcome, and one status line states the build](2026-09-29-build-progress-display-design.md) — landed
- [Two days of mcpp and xlings: a review of what merged, what is known, and what is open](2026-09-28-ecosystem-review-of-two-days-of-mcpp-and-xlings.md) — active
Expand Down
2 changes: 1 addition & 1 deletion .github/actions/bootstrap-mcpp/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ inputs:
# `package.name`, so one of the two was simply unreachable — and which one
# depended on the machine, which is why CI failed on `compat:lua` on
# Windows and `mcpplibs.capi:lua` on Linux. Never pin below that.
default: '2026.9.29.1'
default: '2026.9.30.1'
cache-target:
description: also restore/save target/ (build artifacts + BMIs)
required: false
Expand Down
2 changes: 1 addition & 1 deletion .github/actions/setup-macos-llvm/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ inputs:
# Floor imposed by the index, not a routine bump — see
# .github/actions/bootstrap-mcpp/action.yml for why 0.4.69 is required
# (two packages named `lua` in one repo need openxlings/xlings#381).
default: '2026.9.29.1'
default: '2026.9.30.1'
image:
description: >
The runner label the job runs on (macos-15, xcode-27). It is part of the
Expand Down
4 changes: 2 additions & 2 deletions .github/tools/check_modules_wiring.sh
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ fi
# The two xmake source lists must actually carry the glob. Asserted by content
# rather than by trusting the loop above: a renamed pattern would leave every
# per-module check passing while compiling nothing.
for f in scripts/bootstrap-macos.sh .github/workflows/bootstrap-macos.yml \
for f in tools/bootstrap-macos.sh .github/workflows/bootstrap-macos.yml \
bench/projects/mcpp/xmake.lua; do
[[ -f "$f" ]] || { bad "$f is missing"; continue; }
grep -qF 'modules/*/src/**.cppm' "$f" \
Expand All @@ -109,7 +109,7 @@ done

# The vendored json header is reached through a private include dir. Its path
# appears in three places and has already moved once.
for f in scripts/bootstrap-macos.sh .github/workflows/bootstrap-macos.yml \
for f in tools/bootstrap-macos.sh .github/workflows/bootstrap-macos.yml \
bench/projects/mcpp/xmake.lua; do
grep -qF 'modules/libs/src/json' "$f" \
|| bad "$f does not add the json include dir (modules/libs/src/json)"
Expand Down
8 changes: 4 additions & 4 deletions .github/workflows/aur-publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ jobs:
TRIGGER: ${{ github.event_name }}
MANUAL_PUBLISH: ${{ inputs.publish }}
# Repository variable, absent until a human has watched one publish
# succeed. See "Arming the automatic triggers" in scripts/aur/README.md.
# succeed. See "Arming the automatic triggers" in tools/aur/README.md.
AUTOPUBLISH: ${{ vars.AUR_AUTOPUBLISH }}
run: |
args=(
Expand All @@ -67,7 +67,7 @@ jobs:
--summary "$GITHUB_STEP_SUMMARY"
)
[[ -z "$REQUESTED_TAG" ]] || args+=(--tag "$REQUESTED_TAG")
python3 scripts/aur/reconcile_mcpp_bin.py "${args[@]}"
python3 tools/aur/reconcile_mcpp_bin.py "${args[@]}"

# An unattended push to a third-party service must be ARMED, not
# inherited from a merge. `schedule` fires every six hours off the
Expand Down Expand Up @@ -102,7 +102,7 @@ jobs:
install -dm700 "$HOME/.ssh"
install -m600 /dev/null "$HOME/.ssh/aur"
printf '%s\n' "$AUR_SSH_PRIVATE_KEY" > "$HOME/.ssh/aur"
install -m600 scripts/aur/aur.archlinux.org.known_hosts "$HOME/.ssh/known_hosts"
install -m600 tools/aur/aur.archlinux.org.known_hosts "$HOME/.ssh/known_hosts"
ssh-keygen -lf "$HOME/.ssh/known_hosts" -E sha256 \
| grep -F 'SHA256:RFzBCUItH9LZS0cKB5UE6ceAYhBD5C8GeOBip8Z11+4'
install -m600 /dev/null "$HOME/.ssh/config"
Expand Down Expand Up @@ -145,7 +145,7 @@ jobs:
# EVERY OTHER NON-ZERO CODE STILL FAILS. A refused downgrade (3) and
# a permanent error (2) are this repository's problem and stay red.
set +e
python3 scripts/aur/reconcile_mcpp_bin.py "${args[@]}"
python3 tools/aur/reconcile_mcpp_bin.py "${args[@]}"
rc=$?
set -e
if [[ "$rc" == "75" ]]; then
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/bootstrap-macos.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ jobs:
# Dormant (workflow_dispatch only), but kept in step with the rest —
# check_version_pins.sh holds it there. Floor: 0.4.69, below which the
# index cannot resolve two packages that share a short name.
XLINGS_VERSION: '2026.9.29.1'
XLINGS_VERSION: '2026.9.30.1'
steps:
- uses: actions/checkout@v4

Expand Down
6 changes: 3 additions & 3 deletions .github/workflows/ci-fresh-install.yml
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@ jobs:
env:
XLINGS_NON_INTERACTIVE: '1'
run: |
curl -fsSL https://raw.githubusercontent.com/openxlings/xlings/main/tools/other/quick_install.sh | bash -s v2026.9.29.1
curl -fsSL https://raw.githubusercontent.com/openxlings/xlings/main/tools/other/quick_install.sh | bash -s v2026.9.30.1
echo "$HOME/.xlings/subos/current/bin" >> "$GITHUB_PATH"

- name: Install mcpp and config mirror
Expand Down Expand Up @@ -315,7 +315,7 @@ jobs:

- name: Install xlings + mcpp
run: |
curl -fsSL https://raw.githubusercontent.com/openxlings/xlings/main/tools/other/quick_install.sh | bash -s v2026.9.29.1
curl -fsSL https://raw.githubusercontent.com/openxlings/xlings/main/tools/other/quick_install.sh | bash -s v2026.9.30.1
# Deliberately NOT writing to $GITHUB_PATH here. On container
# images that declare no PATH in their config (opensuse/
# tumbleweed), appending a single dir to GITHUB_PATH makes the
Expand Down Expand Up @@ -416,7 +416,7 @@ jobs:
# (older ones carry minos=15 and refuse to start).
# v0.4.51+: in-process sha256 — this image has no sha256sum
# binary, so pinned fetches failed before it.
curl -fsSL https://raw.githubusercontent.com/openxlings/xlings/main/tools/other/quick_install.sh | bash -s v2026.9.29.1
curl -fsSL https://raw.githubusercontent.com/openxlings/xlings/main/tools/other/quick_install.sh | bash -s v2026.9.30.1
echo "$HOME/.xlings/subos/current/bin" >> "$GITHUB_PATH"

- name: Install mcpp and config mirror
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/ci-linux-e2e.yml
Original file line number Diff line number Diff line change
Expand Up @@ -384,7 +384,7 @@ jobs:

- name: Bootstrap xlings + released mcpp
run: |
curl -fsSL https://raw.githubusercontent.com/openxlings/xlings/main/tools/other/quick_install.sh | bash -s v2026.9.29.1
curl -fsSL https://raw.githubusercontent.com/openxlings/xlings/main/tools/other/quick_install.sh | bash -s v2026.9.30.1
export PATH="$HOME/.xlings/subos/current/bin:$PATH"
xlings update
xlings install mcpp -y -g
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/cross-build-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ jobs:
# release assets were uploaded in a broken state (records present,
# blobs missing → 404 on GET); re-uploaded clean. The stale-INDEX
# half is handled by the marker-clear below.
XLINGS_VERSION: '2026.9.29.1'
XLINGS_VERSION: '2026.9.30.1'
run: |
tarball="xlings-${XLINGS_VERSION}-linux-x86_64.tar.gz"
bash "$GITHUB_WORKSPACE/.github/tools/fetch_release.sh" \
Expand Down Expand Up @@ -289,7 +289,7 @@ jobs:
- name: Bootstrap mcpp via xlings
env:
XLINGS_NON_INTERACTIVE: '1'
XLINGS_VERSION: '2026.9.29.1'
XLINGS_VERSION: '2026.9.30.1'
run: |
tarball="xlings-${XLINGS_VERSION}-linux-x86_64.tar.gz"
bash "$GITHUB_WORKSPACE/.github/tools/fetch_release.sh" \
Expand Down
6 changes: 3 additions & 3 deletions .github/workflows/pypi-publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ name: pypi-publish
# CREDENTIALS: none stored. Publishing uses PyPI Trusted Publishing (OIDC):
# PyPI trusts this repository + workflow file + the `pypi` environment, and
# the job exchanges its GitHub OIDC token for a short-lived upload token.
# One-time setup is in scripts/pypi/README.md.
# One-time setup is in tools/pypi/README.md.
#
# ARMING: the automatic trigger builds, verifies and reports, and publishes
# only when the repository variable PYPI_AUTOPUBLISH is `true`, for the reason
Expand All @@ -25,7 +25,7 @@ on:
# latest release on every platform. A pull request never publishes.
pull_request:
paths:
- scripts/pypi/**
- tools/pypi/**
- tests/scripts/test_pypi_wheels.py
- .github/workflows/pypi-publish.yml
workflow_dispatch:
Expand Down Expand Up @@ -116,7 +116,7 @@ jobs:
echo "mcpp-bin $version from $tag; publish=$publish" >> "$GITHUB_STEP_SUMMARY"

- name: Build wheels from the release manifest
run: python3 scripts/pypi/build_wheels.py --tag "${{ steps.resolve.outputs.tag }}" --out dist
run: python3 tools/pypi/build_wheels.py --tag "${{ steps.resolve.outputs.tag }}" --out dist

- name: Check metadata
run: |
Expand Down
18 changes: 9 additions & 9 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ jobs:
# Pin xlings to a known-good version. The upstream install
# script always grabs `latest` (no version override), so we
# download + self-install manually to avoid broken releases.
XLINGS_VERSION: '2026.9.29.1'
XLINGS_VERSION: '2026.9.30.1'
run: |
if [ ! -x "$HOME/.xlings/subos/default/bin/xlings" ]; then
tarball="xlings-${XLINGS_VERSION}-linux-x86_64.tar.gz"
Expand Down Expand Up @@ -322,7 +322,7 @@ jobs:
- name: Bootstrap mcpp via xlings
env:
XLINGS_NON_INTERACTIVE: '1'
XLINGS_VERSION: '2026.9.29.1'
XLINGS_VERSION: '2026.9.30.1'
run: |
tarball="xlings-${XLINGS_VERSION}-linux-x86_64.tar.gz"
bash "$GITHUB_WORKSPACE/.github/tools/fetch_release.sh" \
Expand Down Expand Up @@ -393,7 +393,7 @@ jobs:
# below are pinned to the same version as XLINGS_VERSION; they are
# NOT interpolated from it, so check_version_pins.sh scans for them
# explicitly (they were absent from the old lock-step comment).
XLA="xlings-2026.9.29.1-linux-aarch64.tar.gz"
XLA="xlings-2026.9.30.1-linux-aarch64.tar.gz"
# NOT fetch_release.sh: this asset is OPTIONAL and the `if` is the
# point — an arch with no prebuilt xlings must fall through quietly,
# while the helper retries a 404 five times before giving up. The one
Expand All @@ -402,9 +402,9 @@ jobs:
# cover it.
if curl -fsSL --retry 3 --retry-delay 2 --retry-all-errors \
--connect-timeout 20 --max-time 600 -o "/tmp/$XLA" \
"https://github.com/openxlings/xlings/releases/download/v2026.9.29.1/$XLA"; then
"https://github.com/openxlings/xlings/releases/download/v2026.9.30.1/$XLA"; then
tar -xzf "/tmp/$XLA" -C /tmp
XLBIN=$(find /tmp/xlings-2026.9.29.1-linux-aarch64 -path '*/bin/xlings' -type f | head -1)
XLBIN=$(find /tmp/xlings-2026.9.30.1-linux-aarch64 -path '*/bin/xlings' -type f | head -1)
if [ -n "$XLBIN" ]; then
mkdir -p "$STAGING/$WRAPPER/registry/bin"
cp "$XLBIN" "$STAGING/$WRAPPER/registry/bin/xlings"
Expand Down Expand Up @@ -482,7 +482,7 @@ jobs:
- name: Bootstrap mcpp via xlings
env:
XLINGS_NON_INTERACTIVE: '1'
XLINGS_VERSION: '2026.9.29.1'
XLINGS_VERSION: '2026.9.30.1'
run: |
if [ ! -x "$HOME/.xlings/subos/default/bin/xlings" ]; then
WORK=$(mktemp -d)
Expand Down Expand Up @@ -665,7 +665,7 @@ jobs:
shell: bash
env:
XLINGS_NON_INTERACTIVE: '1'
XLINGS_VERSION: '2026.9.29.1'
XLINGS_VERSION: '2026.9.30.1'
run: |
# Captured before the `cd` below, in POSIX form: this step never
# returns to the workspace, and GITHUB_WORKSPACE is a backslash
Expand Down Expand Up @@ -818,7 +818,7 @@ jobs:
> "$AUDIT_ROOT/release.json"
gh release download "$TAG" --repo "$GITHUB_REPOSITORY" \
--dir "$AUDIT_ROOT/assets"
python3 scripts/release/generate_manifest.py \
python3 tools/release/generate_manifest.py \
--release-json "$AUDIT_ROOT/release.json" \
--assets-dir "$AUDIT_ROOT/assets" \
--version "$VERSION" \
Expand Down Expand Up @@ -856,7 +856,7 @@ jobs:
gh release download "$TAG" --repo "$GITHUB_REPOSITORY" \
--dir "$AUDIT_ROOT/final-assets"
test -f "$AUDIT_ROOT/final-assets/mcpp-release.json"
python3 scripts/release/generate_manifest.py \
python3 tools/release/generate_manifest.py \
--release-json "$AUDIT_ROOT/final-release.json" \
--assets-dir "$AUDIT_ROOT/final-assets" \
--version "$VERSION" \
Expand Down
92 changes: 92 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,98 @@
> Each `## [<version>]` section is that release's notes. Entries are written in English
> from 2026.9.28.3 on; earlier entries remain as written.

## [2026.9.30.1] - 2026-09-30

This release revises what a build prints, from a report on `mcpp build` in the
xlings repository with 2026.9.29.5
(`.agents/docs/2026-09-30-build-output-refinement-design.md`): a package is
named when it does work, the live display is one status row drawn in one
write, and a bare key of a path dependency is no longer reported. It also
records one lock entry per identity again.

### Added

- **A screen in the status row.** Beside the phase, 24 braille cells play one
of four animations, chosen per command: a chomper whose position is the
progress, a snake that eats a food in the colour of each package that
starts, Tetris on its side whose stack is the progress, and an emitter whose
ions build the progress bar. Each takes its tempo from the build: slow
while mcpp works, faster as steps finish, still while the build waits.
`MCPP_PROGRESS` names one, or `plain` (the row without the screen) or `off`
(no live row) (e2e 843; `mcpp.ui.dots_screen`).
- **`--play-game[=NAME]`** on `build`, `run` and `test` plays `snake`, `stack`
or `runner` on the screen while the build runs, steered from the keyboard at
a speed of its own. The best round is stated after `Finished`. Keys are
read without echo; Ctrl-C still stops the build, and the terminal's mode is
restored when the build ends or is interrupted. Where standard input or
output is not a terminal, or mcpp runs as a background job, one line says
why and the build proceeds (e2e 845). An arrow with a modifier is read as
the arrow, and a sequence for any other key is skipped whole
(`TerminalKeys` unit tests).
- **`last N running`.** Once ninja has no step left to start (its `%u`
reaches 0), the status row states how many steps remain, all of them
running.

### Fixed

- **The live display no longer flickers.** A frame reached the terminal in two
or three writes (stdout is line-buffered, and a line above the region was
erase, text, redraw), and every frame erased the region before drawing it:
in one build of xlings, 184 of 202 frames left in two parts. A frame now
leaves in one write that overwrites the rows in place, with autowrap off for
the status row, so a terminal that draws East Asian ambiguous characters
wide clips the row instead of wrapping it. The row is first drawn half a
second into the command, so the first lines of output no longer push it
down (e2e 843).
- **A dependency the global cache serves is named when its units are
placed.** Its staging steps ran in a pass of their own that nothing read,
so such a package never completed and the folded dependency line waited
for ninja to exit (27 s late in a first build of xlings), after the root's
line (e2e 842).
- **The phase returns to planning after the build programs.** The status
line read `Running build programs` for as long as planning continued.
- **A planned build leaves a committed `mcpp.lock` unchanged.** Since
2026.9.29.1 a planned build of a workspace root wrote the dependencies of a
`[dependencies.<ns>]` table under a second spelling with another hash,
beside the entries already there; the lock now holds one entry per
identity, spelled as 2026.9.28.3 spelled it, and a lock that holds two is
reduced to one by the next planned build (e2e 844).

### Behaviour changes

- **A package is named once, when it does work**: `Compiling <package>` when
the first of its steps that is not a dependency scan finishes, or when its
first `check` or `prepare` action starts, and `Cached <package> (N units)`
when the global cache places its units. The line states no outcome and does
not change; nothing is folded, and a package with nothing to do has no line
(`--verbose` names it `Fresh`, and states each package's steps and span as
`Compiled`) (e2e 842).
- **A package inside the project is named by its short name, version and
directory** (`platform v0.1.0 (modules/platform)`); any other by its
identity, with `(index <name>)`, `(git <kind> <ref>)` or its relative
directory. On a terminal the name's colour states the source: the official
index cyan, another index magenta, git blue, the project's own packages the
default colour.
- **A build program has a line when it runs or fails**; a reused program has
one under `--verbose`. The folded `build.mcpp N dependencies` line is gone.
- **A failure names its package**: `error: build failed in <package>`.
- **`Finished` states how the time was spent from one minute**, where it did
from ten seconds; below a minute it states the profile and the total alone.
The longest step, when it took at least a quarter of the build, is named
by its source file for a compile (`longest slow: src/main.cpp 1m08s`), not
by its object file. A build with nothing to do states the profile's
descriptor as a full build does (`Finished dev [unoptimized + debuginfo]
in 0.02s`): the step record's header carries it for the fast path.
- **The status row is aligned with the verbs** (` Building 612/707 · 0:35`),
its phases are `Planning`, `Running`, `Building`, `Stopping` and `Checking`,
and no blank row separates it from the output.
- **A bare key of a path or git dependency states only the short name.** Its
adoption of the namespace the manifest declares is no longer reported; a
key that states a namespace the manifest contradicts is reported once per
consumer manifest, named by its path, with the TOML that states the
declared identity (e2e 679, 713; package-identity §4.2).
- **The bundled xlings is 2026.9.30.1.**

## [2026.9.29.5] - 2026-09-29

This release completes the workspace build graph in the commands around the
Expand Down
Loading
Loading