Skip to content

PR CI acceleration, SPEC-009, and the repairs of #756 and #757 - #759

Draft
speak-agent wants to merge 11 commits into
mainfrom
feat/pr-ci-acceleration
Draft

speak-agent wants to merge 11 commits into
mainfrom
feat/pr-ci-acceleration

Conversation

@speak-agent

Copy link
Copy Markdown
Member

Design record: .agents/docs/2026-10-02-pr-ci-acceleration-and-the-toolchain-specification-design.md.

This pull request is in progress. It carries, in one change:

Measured before the change (seven commits, 2026-10-01): 30 to 37 builds of mcpp per commit, 44 to 49 percent of 417 to 568 runner minutes; the 20-slot limit reached on every commit; a documentation-only commit costing 436 runner minutes; 24 e2e tests that ran on no runner.

Add SPEC-009 (docs/specs/toolchain-maintenance.md), the toolchain
specification approved in review on 2026-10-02: support tiers, the single
line table, whole-line moves, provenance, what supporting a line means,
the compiler-defect register, host platform releases, mirrors, the order
and the gate (G1 to G6, 10 percent) for moving a default, machines that
already have a default, mcpp building with what it gives, and the
conformance checks C1 to C7. Each rule carries an implementation status
and, where the status is not "implemented", the current behaviour.

SPEC-006 section 7 becomes a reference to SPEC-009 section 10 (v0.6); the
order of moving a C-library binding is carried into SPEC-009 section 10.10.
The specification index and both documentation indexes list SPEC-009.
… caches, timed shards and a coverage check

ci.yml classifies the change, runs the documentation checks, builds mcpp once per host (build.yml) and calls the per-area workflows, which take that build through use-built-mcpp instead of building their own. Caches are restored by every job and saved only by one job per key on a push to main; target/ is no longer cached. The e2e shards are assigned by measured duration (tests/e2e/timings) and write per-test reports that check_e2e_coverage.py reads: every test runs on some host, is run by a dedicated job, or is excused with a reason. run_all.sh grants llvm on Linux and probes musl and mingw-cross by family rather than by release.
…d, and each path dependency is classified by its own package (#757, #756)

#757. build.ninja names the engine that wrote it by absolute path, and the
emitter assumed that a new engine plans the graph again because the version
is a fingerprint input. No fast path computes a fingerprint, so after an
upgrade that removed the previous install the recorded graph was replayed and
every action started a program that no longer existed.

- BuildCacheEntry records the engine that wrote the graph: its version and
  mcpp_exe_path(), the function the emitter writes into the graph (now
  exported from mcpp.build.ninja so the two cannot be spelled apart). An
  entry that predates the field declines once ("the recorded build predates
  the engine identity").
- The gates the three fast paths share are one function,
  admit_recorded_build: the engine, the runtime binding and environment key,
  the fingerprint directory, the graph's existence, mode and request tag, the
  freshness of the runtime, the manifest and the project's sources, the
  recorded path-dependency roots, the xlings payloads, the toolchain named by
  path, and the artifact snapshot. try_fast_build, try_fast_workspace_build
  and try_fast_run call it and keep only their own gates (the selection, a
  program to run, a runner, the run tier). A field added to the record is
  checked in one place.

#756. The freshness sweep classified every path-dependency tree with the
consumer's extension table, so a provider's `.ixx` (declared only by the
provider) was a file of no interest and an edit to its host module was
replayed as "no work".

- The plan records each root with its own package's module_extensions and
  device_extensions (DepSourceRoot), from the effective manifest.
- The record carries them in a count-prefixed `depSources=` block; the block
  that listed the paths alone is read past and left unrecorded, so such an
  entry declines once.
- dep_sources_newer_than classifies the files below each root with that
  root's table.

Tests: e2e 878 (an engine moved to another path does not replay the old
graph; the record written before the field declines once; `mcpp run`), e2e
879 (a provider's `.ixx` reaches the project, run and workspace fast paths
with a consumer that declares nothing; an aged record declines once), and
unit tests of the engine decision, the admission order, the record's round
trip and the per-root sweep.
admit_recorded_build reads the `$mcpp` binding of build.ninja (read_engine_binding) and declines a graph that runs another engine, which the record alone cannot see when another install's --configure-only rewrote the graph. e2e 878 gains section E; three unit tests cover the reader. The version is 2026.10.2.1, with its CHANGELOG entry.
…hat falls back to the whole CI, a concurrency group per push to main, cache keys that name the install list, a step for the shard's installs, and a record that leaves a tab-holding root unrecorded
…and a 5-line tighten so src/build/prepare/plan.cpp is back under the 2,500-line gate

The third CI round (run 36946677551) had two failures from the
#756/#757 commit's +12 lines:

- Windows clang+MSVC STL would not compile a literal returned directly to
  std::optional<std::string> in engine_declined_because (execute.cppm:189).
  std::string(...) makes the conversion explicit and identical on every
  STL.

- src/build/prepare/plan.cpp went from 2,491 to 2,503 lines, three over
  the check_file_lengths.sh cap. The new rootOf/recorded lambdas in
  step13_source_packages carry DepSourceRoot (a comment is redundant
  with the struct's own), and the two are tight enough to put the file
  back at 2,498. No semantic change.

Local unit tests: 20/20 BuildCacheRecord tests pass (BuildCacheRecord,
DepSourcesNewerThan, ReadEngineBinding).

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant