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
130 changes: 127 additions & 3 deletions .agents/docs/2026-09-28-ecosystem-design-and-optimisation-plan.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
---
subject: design
status: active
status: landed
---

# An ecosystem design for mcpp and xlings: one authority per fact, and the work that follows from it

**Status:** active, revision 3 (2026-09-28). The design is settled; §7 divides it
into tasks and is the implementation record.
**Status:** landed, revision 4 (2026-09-28). The design is settled; §7 divides it
into tasks, and §8 records their implementation: mcpp 2026.9.28.2 and xlings
2026.9.28.2 are released and indexed.

- **Revision 1** proposed the design and seven decisions.
- **Revision 2** records the reviewer's answers: D1 to D7 are settled as
Expand All @@ -16,6 +17,8 @@ into tasks and is the implementation record.
- **Revision 3** divides the workstreams into tasks per repository, with the
dependencies between them and the criterion of each (§7). Facts found while
dividing them, which change no decision, are recorded in §7.4.
- **Revision 4** records the implementation (§8): where it departed from §7,
nine findings, the before and after reading of each task, and a self-review.

**Input.** The review `2026-09-28-ecosystem-review-of-two-days-of-mcpp-and-xlings.md`
(cited below as "the review §n"), the #717-#726 round's records, and the
Expand Down Expand Up @@ -687,4 +690,125 @@ implementing it, and the readings.
failed on the Windows row and found it. The detector accepts both spellings,
the comment in `cli.cppm` states the exception, and the CHANGELOG lists the
one re-run.
- **F7. §7.4 named the wrong sibling of #729.** It listed the LLVM step of
`ci-windows.yml` among the builds piped into `tee` without `pipefail`; that
step runs under `shell: bash`, which GitHub starts with `-eo pipefail`, and
is not affected. The lint's reading of the workflows before the change is
seven W1 problems: in `ci-linux.yml` the LLVM, musl-gcc and GCC cold-rebuild
steps and two example steps, and in `ci-fresh-install.yml` two template
steps. A list written from reading the files is the claim; the lint's output
is the reading.
- **F8. The release gate's first reading was of its own harness.** The first
release run of 2026.9.28.2 (36363585412) failed the GalTranslPP canary before
it built anything: `release_canaries.py` started `bash` by name, and a Windows
program that does so gets `System32\bash.exe`, the WSL launcher, because the
loader searches the system directory before `PATH`. The gate held and no tag
was created. The workflow now names the step's bash (`CANARY_BASH`), the
runner has tests, and the canaries were dispatched on the fix's branch before
the release was dispatched again (#731).
- **F9. A packaging revision reaches a consumer when its index does.** The
GalTranslPP canary, dispatched on #731's branch after `qt-base` revision 1
was published, built, ran and packed the project with the candidate, and
stated once that `xim-x-qt-base\6.11.1\bin` ships the MSVC C++ runtime:
the resolver placed the toolset's set instead, as WS1 specifies. The payload
was revision 0 because the job restores the whole mcpp home from CI's cache,
its index copy included, and that copy predates the revision; by that index
the installed payload is current. A consumer receives revision 1 on the
first use after its index refreshes (GalTranslPP's own CI caches the
payloads and not the index; its reading follows the release).

### 8.3 Readings

**Before and after, per task.** Each criterion of §7 was read against the
released 2026.9.28.1 (xlings 2026.9.28.1) and against this round's versions.

| Task | Criterion | 2026.9.28.1 | 2026.9.28.2 |
|---|---|---|---|
| X1 | the index build script runs once per `update` (E2E-91 S6; sandbox) | 2 runs | 1 run |
| X2 | a store hit reads "is in the store", then "active: a -> b" | "is already installed", "upgraded" | as specified |
| X3 | every `download_progress` event names its stream (E2E-123 P3; sandbox) | no `stream` | named, bounded by the elapsed time |
| X4 | off a terminal, the xim index download prints two lines (E2E-123 P1; sandbox, CN mirror) | 162 lines (769 in a CI log) | 2 lines |
| X5 | the marker; #617's handoff; #624's nested home (E2E-120 S6, E2E-124; sandbox) | no marker; "package file not found" | as specified |
| M1 | e2e 819 L1 to L6; e2e 820 W1 to W5 on the Windows row (VS 2026, MSVC 14.51.36231) | `--crt` unknown | pass |
| M2 | e2e 820 W6; e2e 799 D; the measurement (run 36361809507) | the tools do not start as actions; `--path-prepend` unknown | the tools start as actions on the Visual Studio row and on the masked row (managed [email protected]), and do not start directly |
| M3 | e2e 118 on the Windows row | asserted only the missing depfile | the rebuild is asserted and passes |
| M4 | e2e 818 criteria 5 and 6; e2e 820 W7; e2e 821 | 0 statements (818); A1 fails (821) | once; once at `[workspace.build]`; once per run of the edge |
| M5 | the lint on the workflows before and after the change | 7 W1 problems | 0 |
| M6 | the docs check on the Linux, macOS, Windows and bare Windows rows | no `defaultToolchain` | [email protected], [email protected], [email protected] and [email protected]: 0 problems on each row |
| M7 | unit `ConditionalOrder.*`; the sandbox section #728 | lexical order | specificity |
| M8 | the canaries; `verify-published.sh` | not present | see F8 and the sandbox table below |
| I1, I2 | the static test; the Windows install tests of `qt-base` and `qt` (openxlings/xim-pkgindex#898) | the test fails at `qt` and `qt-base` | both recipes install and pass their checks with revision 1 |
| N1 | the full sweep with mcpp 2026.9.28.2 (run 36376460690) | pinned to 2026.9.28.1 | 22 shards green (linux default 6, linux llvm 9, macos 2, windows 5) |
| N2 | `red_members.py selftest` (seven cases) | not present | pass; on the full sweep, "No member failed." |

**CI.** mcpp#730's last head (`feb5743f`): every workflow concluded success;
the two jobs of the xcode-27 image fail as known red (#669). The two earlier runs
on the branch found F4, F6, the fast path that e2e 821 assumed on every host
(it serves only ELF products, #400), and the measurement's three harness
defects; each was fixed on the branch.

**Sandbox readings.** `tests/release/verify-published.sh` in fresh SubOS
sandboxes (`xlings subos use <n> --sandbox`), with the CN mirror set for xlings
and for mcpp, against what the index publishes:

| mcpp | xlings | ok | failed | not run | The failures |
|---|---|---|---|---|---|
| 2026.9.28.1 | 2026.9.28.1 | 15 | 12 | 2 | every section this round adds, each with the reading of §8.3's second column |
| 2026.9.28.1 | 2026.9.28.2 | 20 | 7 | 2 | the seven mcpp sections: mcpp's registry runs its pinned xlings 2026.9.28.1 and carries no marker (two); no `defaultToolchain`; the lexical order; the three `place-dlls` legs (`--crt` unknown) |
| 2026.9.28.2 | 2026.9.28.2 | 27 | 0 | 2 | none |

The two sections not run are Windows behaviour, read on the Windows CI rows
(e2e 820, e2e 118, the measurement). Every section kept from 2026.9.28.1
(#717, #720, #723, #724, #725, the progress of an index refresh) passes in
all three runs.

**GalTranslPP on Windows.** The real project the review started from, read
three ways with mcpp 2026.9.28.2, each with the LLVM row ([email protected]) over the
Visual Studio 2026 toolset (MSVC 14.51.36231) on `windows-2025`:

| Reading | Build, run, pack | The runtime beside the program |
|---|---|---|
| the release's canary (the candidate, CI's cached mcpp home) | 4 of 4 commands held; `GalTransl++ CLI v3.1.1` | `qt-base` revision 0 from the cached home: its copy is stated once as a packaging fault, and the toolset's set is placed (F9) |
| the project's CI, pin 2026.9.28.2 (Sunrisepeak/GalTranslPP#3, `0681f59`) | success in 41 minutes | no runtime copy in `qt-base`'s `bin`: nothing is stated; the package carries the set the build placed |
| the same, without the #718 workaround (`229f0d1`, run 36378870254) | success in 35 minutes; no statement that a CRT word is redundant | the model alone chooses the dynamic CRT: the packages carry `MSVCP140*` and `VCRUNTIME140*` beside GPPCLI and GPPGUI |

### 8.4 Self-review

**Architecture.** Each fact that §1 set out to give one authority now has one:
the files beside a PE program (`mcpp.build.runtime_placement`, read by the
plan, `place-dlls` and `mcpp pack`), the order of conditional tables
(`mcpp.manifest.cfg_selector`, read by both manifest readers), the host's
default toolchain (`pins::host_default_toolchain`, read by the first run,
`self env` and the docs check), and a home (`home_identity::is_home`, read by
every xlings reader). Two statements remain second copies by construction:
`verify-published.sh` embeds the PE synthesiser of `tests/e2e/_synth_pe.py`,
because a sandbox sees no checkout, and the index keeps its own list of red
members, because the owner of a failure is a fact of the index.

**Crossings.** The pull-request template's table was filled before CI and
still missed one crossing (F6: the action `PATH` against the stability of an
action's command line). The table asks which invariants a change crosses; a
change to a generated command line crosses every test and comment that reads
that command, and those are found by searching for the old spelling, not by
thinking of invariants.

**Stability.** The release gate works and costs time: the GalTranslPP canary
builds its vcpkg dependencies without a cache on `main`, about fifty minutes,
before any archive is built. Its cache is saved per run, so later releases
from `main` restore it. The measurement workflow renames system files on a
disposable runner and restores them from bash in an `always()` step.

**User experience.** A project that wrote the #718 workaround
(`dialect_cxxflags = ["-fms-runtime-lib=dll"]`) is told once that the word is
redundant; GalTranslPP carries it. Off a terminal, xlings still passes the
sub-index build scripts' frames through (openxlings/xlings#629).

**Compatibility.** On Windows the first build after the upgrade re-runs each
action once and, for GNU-dialect compiles, rebuilds once; a program whose
search directories carry an older runtime copy receives the toolset's. No
index descriptor changes meaning under D7 (§8.3).

**Open after this round.** openxlings/xlings#629 (the frames), mcpp #669 (the
xcode-27 image's SDK), and the reach of a packaging revision, which is the
reach of the consumer's index (F9) and is not a defect.

4 changes: 2 additions & 2 deletions .agents/docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ Records that declare one. Everything else is listed by date below.

### design

- [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) — active
- [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
- [The compile database, `emit build-database`, and #701/#702: triage against the specifications, and one design](2026-09-26-compile-database-and-issue-699-design.md) — landed
- [Issues #693 to #696: triage against mcpp's contracts, and one repair plan](2026-09-25-issues-693-696-triage-and-repair-plan.md) — landed
- [Workspace inheritance, flag scoping and the published form: a unified repair plan (#690)](2026-09-25-issue-690-workspace-build-inheritance-consistency.md) — landed
Expand Down Expand Up @@ -107,7 +107,7 @@ Records that declare one. Everything else is listed by date below.
### 2026-09

- [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
- [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) — active
- [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
- [Eight reports after 2026.9.27.1: implementation plan](2026-09-27-eight-reports-implementation-plan.md) — active
- [Eight reports after 2026.9.27.1: what each one is, where it belongs, and one optimisation plan](2026-09-27-eight-reports-by-home-and-one-optimisation-plan.md) — active
- [The compile database, `emit build-database`, and #701/#702: triage against the specifications, and one design](2026-09-26-compile-database-and-issue-699-design.md) — landed
Expand Down
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,8 @@
mcpp 构建它们,`release.yml` 的打 tag 任务依赖其结果;`tests/release/verify-published.sh` 在沙箱
中验证已发布的 mcpp 与 xlings,每个发布项一节,并保留此前各版本的小节;PR 模板要求列出每条新规则
所跨越的既有不变量与位于交点的测试。
canary 以路径调用运行该步骤的 bash(`CANARY_BASH`):Windows 上按名字启动的 `bash` 是 System32 中的
WSL 启动器,本版本第一次发布运行因此在 GalTranslPP canary 处停止,未创建 tag(#731)。
- **测量任务。** `measure-windows-tool-crt.yml` 在带 Visual Studio 与屏蔽 Visual Studio 的两个
Windows 行上隐藏系统的 C++ 运行时,测量 Qt 的宿主工具能否只经 action 的 `PATH` 启动(设计 §2.9),
它是从 `xim:qt-base` 中移除运行时副本的前提。
Expand Down
Loading