Skip to content

fix(container): [#2853] cap the Cargo jobs of the image build - #2854

Open
josecelano-bot wants to merge 14 commits into
torrust:developfrom
josecelano-bot:2853-container-build-jobs-limit
Open

josecelano-bot wants to merge 14 commits into
torrust:developfrom
josecelano-bot:2853-container-build-jobs-limit

Conversation

@josecelano-bot

@josecelano-bot josecelano-bot commented Nov 13, 2026 •

Copy link
Copy Markdown
Contributor

Summary

The container image build had no Cargo job limit, so on a many-core machine BuildKit ran dozens of rustc processes at once and exhausted the RAM (two OOM kills on a 32-thread workstation). This caps the Cargo jobs of every compiling stage with CARGO_BUILD_JOBS, default 4, overridable with --build-arg.

Closes #2853. The maintainer accepted the measured slowdown on the self-hosted runner (below) for acceptance criterion AC6; the specification still shows AC6 as TODO and is updated in the close-out after merge.

Changes

  • Containerfile: ARG CARGO_BUILD_JOBS=4 plus ENV in the chef base stage (every stage that compiles Rust and derives from it), and the same declaration in the tester base stage, because its cargo binstall of cargo-nextest can fall back to a source compile.
  • contrib/dev-tools/containers/docker-build.sh: passes CARGO_BUILD_JOBS as a build argument when set.
  • docs/containers.md: new "Memory and CPU Use" section.
  • contrib/dev-tools/experiments/container-build-jobs/: measurement script, raw samples and report.md.
  • docs/issues/open/2853-container-build-jobs-limit/: the specification, the manual verification evidence and implementation-retrospective.md (what made this review slow, with proposals for the review process).
  • docs/pr-reviews/pr-2854-review/PR-REVIEW.md: the review audit record.

Measured evidence

Release image, uncached, one build at a time on a 32-thread machine:

CARGO_BUILD_JOBS Wall time rustc at peak RSS Peak rustc RSS
4 (default) 836 s 4 10.4 GiB
8 499 s 8 19.8 GiB
16 346 s 17 35.5 GiB

Self-hosted runner (8 vCPU, 16 GB), Build Tracker Image step: 814 s, 842 s and 824 s in three runs of this PR at 4 jobs, against 721 s, 723 s and 749 s in three uncapped develop runs. That is about 13% slower (827 s against 731 s on average). The runs built different commits and the cache state was not checked, so the comparison is rough. container.yaml is unchanged; it can pass a higher value for that runner if wanted. GitHub-hosted runners have 4 vCPUs and are not affected.

Known failing check

Test (Docker) (release) fails on this PR in the step Run Persistence Transition Regression, after the image build passes. The same step fails on develop at this branch's merge base (run 43299605132), so it is not caused by this change.

Out of scope: BuildKit max-parallelism, Docker daemon memory limits and a cap on concurrent builds (machine setup).

🤖 Generated with Claude Code

josecelano-bot and others added 3 commits November 13, 2026 09:44
…iner build jobs limit

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…with CARGO_BUILD_JOBS

Default 4, overridable with --build-arg; docker-build.sh passes the variable on.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…he image build

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

The independent tester stage lacks the compilation job cap, and interrupting the measurement script leaves its background build running without memory protection.

2 open issues
What changed in this PR

This PR addresses #2853 by limiting Cargo parallelism during container image builds, reducing memory pressure on many-core machines while allowing explicit overrides.

Changes:

  • Defaults Cargo builds in chef-derived stages to four jobs and forwards overrides through the build script.
  • Documents memory guidance and measurements for 4, 8, and 16 jobs.
  • Adds the measurement script, raw results, issue specification, and verification evidence.
File Description
Containerfile Sets the default Cargo job limit in the shared builder stage.
contrib/​dev-tools/​containers/​docker-build.sh Forwards the optional job-limit override.
docs/​containers.md Explains defaults, overrides, and memory estimates.
contrib/​dev-tools/​experiments/​container-build-jobs/​measure.sh Measures build duration and memory with a watchdog.
contrib/​dev-tools/​experiments/​container-build-jobs/​REPORT.md Records results and explains the chosen default.
contrib/​dev-tools/​experiments/​container-build-jobs/​results/​jobs-4.samples.tsv Stores raw four-job measurements.
contrib/​dev-tools/​experiments/​container-build-jobs/​results/​jobs-4.summary.txt Summarizes the four-job run.
contrib/​dev-tools/​experiments/​container-build-jobs/​results/​jobs-8.samples.tsv Stores raw eight-job measurements.
contrib/​dev-tools/​experiments/​container-build-jobs/​results/​jobs-8.summary.txt Summarizes the eight-job run.
contrib/​dev-tools/​experiments/​container-build-jobs/​results/​jobs-16.samples.tsv Stores raw sixteen-job measurements.
contrib/​dev-tools/​experiments/​container-build-jobs/​results/​jobs-16.summary.txt Summarizes the sixteen-job run.
docs/​issues/​open/​2853-container-build-jobs-limit/​ISSUE.md Defines scope, acceptance criteria, and implementation progress.
docs/​issues/​open/​2853-container-build-jobs-limit/​manual-verification-evidence.md Records build and override verification.

Review effort: Balanced

Comment thread Containerfile Resolved

@da2ce7 da2ce7 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed at ca14aeb82678811657a578f765a920c2c118edc0. Recomputed from the bytes at this head, against the merge base ec1f58ec9; git merge-tree against develop ec1f58ec9 writes tree 708abd537, identical to the head tree, so the merge is clean.

Process: a bug fix with an implementation-plus-spec branch, so fix-bug, create-issue, commit-changes, open-pull-request and write-markdown-docs govern it. The spec has every template section and valid v1 frontmatter; the evidence file misses the records fix-bug asks for (F2, F3).

The change against its claim: the ARG/ENV in chef reaches every compiling stage (all derive from chef; tester, gcc and runtime do not), and docker-build.sh passes the variable only when it is set. The three result rows, the 40%/31% savings, the 1.7x ratio and the 2.2-2.6 GiB per job recompute from the raw samples. Two report statements do not (F4, F5), AC6 is marked DONE with its condition unmet while the description closes the issue (F1), and one spec risk contradicts the Containerfile (F6). A changed value rebuilds the whole image, which the docs omit (F7).

Consistency: links resolve, related artifacts and skill links exist, the ADR paths and the self-hosted runner statement check out, and no word was added to the dictionary.

Hygiene: three Conventional subjects with the [#2853] reference, author equals committer, git diff --check clean, the skill's commit-id check prints nothing, and the closing-keyword scan matches only Closes #2853 in the description. Each commit has one attribution footer line (no rule in the tree on it).

Findings: F1 Major; F2-F7 Minor; F8-F11 Nit.

Checked, no finding: stage derivation; docker-build.sh with and without the variable; the measure.sh watchdog and summary arithmetic; summary files against samples; frontmatter fields against the validator's profile; table shapes and fences.

Checks

On the loop's compute node at this head, against the merge base ec1f58ec9 (receipt server-gates-kranich-813): the repository's pre-commit gate and lint roster exit 0 and the tree left clean. No Rust package changes, so no package tests apply; the image build itself was not run here. F1 checked against the bytes at posting: .github/workflows/container.yaml at this head passes no build argument and does not mention CARGO_BUILD_JOBS, while the spec's status table marks AC6 DONE and the description says Closes #2853. F6 checked: Containerfile line 36 is FROM docker.io/library/rust:slim-trixie AS tester. GitHub checks at this head at posting time: "Package Coverage (${{ matrix.package }}): completed/skipped; Package Coverage Regression: completed/success; Docker E2E: completed/skipped; Unit (stable): completed/success; Unit (nightly): completed/success; Workspace Packaging: completed/success; Documented Clippy Allows: completed/success; Shipped Features: completed/success; Layer Boundary Bans: completed/success; Security Scan: in_progress/pending; Generate Coverage Report: completed/success; Discover Package Coverage: completed/success; Docs Lint: completed/success; Build on windows-latest (nightly): completed/success; Build on windows-latest (stable): completed/success; Build on macos-latest (nightly): completed/success; Build on ubuntu-latest (stable): completed/success; Build on ubuntu-latest (nightly): completed/success; Build on macos-latest (stable): completed/success; Test (Docker) (release): in_progress/pending". At posting, develop is ec1f58ec9.

Comment thread Containerfile Resolved
Comment thread Containerfile Resolved
…ge, trap measure.sh signals

- tester installs cargo-nextest via cargo binstall, which can fall back to a
  source compile; give it the same CARGO_BUILD_JOBS default/override as the
  chef-derived stages.
- measure.sh now traps INT/TERM and terminates its background build before
  exiting, instead of leaving it running with no watchdog.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@josecelano

Copy link
Copy Markdown
Member

ACK 334decb

@josecelano
josecelano requested review from da2ce7 and a balanced review from Copilot November 13, 2026 10:38
…hmetic, evidence, docs nits

- report.md (renamed from REPORT.md, F10): compute peak rustc count and peak
  RSS from the same sample row instead of independent column maxima, which
  mixed two different moments (F4); correct the release target's stage
  overlap to at most two concurrent compiling stages, matching the
  Containerfile's dependency graph (F5); measure.sh's summary now reports
  the joint figures.
- ISSUE.md: fix the tester/chef CARGO_BUILD_JOBS risk statement, which
  contradicted itself (F6); AC6/T6 held at IN_PROGRESS pending the real
  self-hosted run at this head, added M4 for it (F1); fixed the progress-log
  timestamps (F8); fixed the heading-case nit (F11).
- docs/containers.md: document that a changed value invalidates the build
  cache from chef/tester onward (F7); fixed the script-path example (F9) and
  the heading-case nit (F11) in docker-build.sh.
- manual-verification-evidence.md: added the fix-bug reproduction
  classification (Infeasible, with the attempted commands, blocking
  constraint and substitute evidence) and named the exact commits measured
  (F2); added the no-flag default verification for both chef and tester,
  which an explicit --build-arg equal to the default does not prove (F3);
  added a V4 placeholder for the self-hosted runner result.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>

@da2ce7 da2ce7 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed at 334decbf9f6ad47117440a1158e8cac0a3218fbf. Recomputed from the bytes at this head, against the merge base ec1f58ec9; git merge-tree against develop ec1f58ec9 writes tree a91ce8a71, identical to the head tree, so the merge is clean.

Process: one new commit, a fast-forward of ca14aeb82 touching Containerfile and measure.sh. It answers the two threads of the earlier automated review; the eleven threads of my last review have no reply, and the head carries no review audit record (F12).

The change against its claim: tester now declares the same ARG/ENV before its cargo binstall, so a source-compile fallback is capped, and the value now also reaches test and test_debug, which derive from tester. The trap in measure.sh is installed once build_pid is set, sends TERM to the build client, waits and exits; the watchdog path is unchanged. Both do what the commit body says. The spec, the description and the chef comment still say that only chef carries the cap (F13).

Prior findings: none of the files behind F1 to F11 changed, so all eleven stand as posted, F1 still Major. F6 changes shape: its bullet now says the test stages are not capped, and at this head they are.

Consistency: no link, path or dictionary change.

Hygiene: Conventional subject with [#2853], body matches the diff, author equals committer, git diff --check clean, the skill's commit-id check prints nothing, and the closing-keyword scan matches only Closes #2853 in the description. Each commit has one attribution footer line (no rule in the tree on it).

Findings: F12 Minor, F13 Minor; F1 to F11 open.

Checked, no finding: trap quoting and timing under set -u; the background build ignoring SIGINT, so the trap is what stops it; the deferred trap during sleep 2; tester stage order; the trial merge.

Checks

On the loop's compute node at this head, against the merge base ec1f58ec9 (receipt server-gates-kranich-816): the repository's pre-commit gate and lint roster exit 0 and the tree left clean. The PR has no review audit record at this head (F12), so the audit validator was not run in the gate. No Rust package changes, so no package tests apply; the image build itself was not run here. F12 checked at posting: docs/pr-reviews/pr-2854-review/PR-REVIEW.md is absent at 334decbf9, and two review replies on the forge read "Fixed in 334decb". GitHub checks at this head at posting time: "Package Coverage (${{ matrix.package }}): completed/skipped; Package Coverage Regression: completed/success; Test (Docker) (release): in_progress/pending; Generate Coverage Report: in_progress/pending; Discover Package Coverage: completed/success; Build on ubuntu-latest (stable): completed/success; Build on ubuntu-latest (nightly): completed/success; Build on macos-latest (nightly): completed/success; Build on windows-latest (stable): completed/success; Build on windows-latest (nightly): completed/success; Build on macos-latest (stable): completed/success; Docs Lint: completed/success; Docker E2E: completed/skipped; Workspace Packaging: completed/success; Unit (nightly): in_progress/pending; Documented Clippy Allows: completed/success; Shipped Features: completed/success; Unit (stable): in_progress/pending; Layer Boundary Bans: completed/success; Security Scan: in_progress/pending". At posting, develop is ec1f58ec9.

Comment thread Containerfile Resolved
Comment thread Containerfile Resolved
… add audit record

- Containerfile, ISSUE.md: the chef-stage comment and the Goal/Scope/T3 text
  said the cap lived only in chef, or that stages outside it needed nothing,
  although tester now declares its own ARG/ENV (R1). Named both base stages
  consistently wherever this is described.
- Added docs/pr-reviews/pr-2854-review/PR-REVIEW.md per the process-pr-review
  skill, covering R1, R2 and F1-F13, started late (logged in its Processing
  Log) since the first two replies predated it.
- Rewrote the PR description to match.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

The documentation overstates the two-stage compilation bound and incorrectly implies that changing CARGO_BUILD_JOBS always forces a cold build despite retained caches.

2 open issues
2 resolved since last review

Review effort: Balanced

Comment thread docs/containers.md Resolved
…d reply URLs

Table rows needed single-space cell padding to match the validator's regex;
filled in every finding's Reply URL (previously a placeholder) and
simplified F6's Resolution reference to one commit subject, per
docs/templates/PR-REVIEW-TEMPLATE.md. validate-audit-record.py now reports
status ok, 15 rows, 0 failures.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@josecelano

Copy link
Copy Markdown
Member

ACK 03c6c7e

@josecelano

Copy link
Copy Markdown
Member

ACK 3d9dfeb

@da2ce7 da2ce7 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed at 3d9dfebc6d0419eca073c49eeaf7d34c223bbe05. Recomputed from the bytes at this head, against the merge base ec1f58ec9; git merge-tree against develop ec1f58ec9 writes tree f0da7ca88, identical to the head tree, so the merge is clean.

Process: three commits since my last review, 523914617 (answers to F1 to F11), 03c6c7e9e (wording and the audit record) and 3d9dfebc6 (audit table and reply URLs). The audit record now passes the validator's checks, run offline against this head's review comments: 15 rows, 0 failures. Two newer threads from the automated review, R3 and R4, are open and not yet in the record; both hold against the bytes.

Prior findings: F1 to F7, F9 to F13 are resolved. AC6 is TODO with M4 tracking the runner check, the description says Related to #2853, and the chef comment, scope bullet and T3 row name both base stages. F8 stays open although its row says FIXED: the 08:50 entry still says the 4-job run started then, and the 10:55 entries sit in a 10:46 commit.

The change against its claim: the F4 fix rewrote the three committed run summaries into the new measure.sh format, and the 16-job drop matches neither the run nor the script (F14). The report states a runner measurement it does not contain (F15). The skill's commit-id check prints four branch ids (F16), and small report wording issues remain (F17). Some audit entries overstate (F19), and F6's resolution reference now names a commit that did not touch its bullet (F20).

Consistency: links and the renamed path resolve, and the spec's related artifacts exist.

Hygiene: Conventional subjects with [#2853], author equals committer, git diff --check clean, and the closing-keyword scan finds no match in the description or commit messages. Each commit has one attribution footer line (no rule in the tree on it).

Findings: F14 Major; F15, F16, F19 Minor; F17, F20 Nit; F8 Nit still open.

Checked, no finding: the new measure.sh awk against the unchanged samples; the V2 commands against the stage layout; each Reply URL sits on its own thread; every resolution subject exists on the branch; table shapes and fences.

Checks

On the loop's compute node at this head, against the merge base ec1f58ec9 (receipt server-gates-kranich-822): the repository's pre-commit gate and lint roster exit 0 and the tree left clean; the repository's audit validator on pr-2854-review exit 0 (15 rows, 2 log entries, no failures). At the previous head 03c6c7e9e the same validator exited 1 with 16 failures (receipt server-gates-kranich-821). No Rust package changes, so no package tests apply; the image build itself was not run here. F14 checked against the bytes at posting: jobs-16.summary.txt read peak_used_delta_gib=33,0 at ca14aeb82 and reads peak_used_delta_gib=32,9 at this head, and (49323728 - 14758164) kB is 32.96 GiB. Read on the forge: 15 review threads are resolved and 2 are open (the automated reviewer's newer R3 and R4). GitHub checks at this head at posting time: "Docker E2E: completed/skipped; Layer Boundary Bans: queued/pending; Unit (stable): queued/pending; Unit (nightly): queued/pending; Shipped Features: queued/pending; Workspace Packaging: queued/pending; Documented Clippy Allows: queued/pending; Test (Docker) (release): queued/pending; Build on ubuntu-latest (nightly): queued/pending; Build on windows-latest (nightly): queued/pending; Build on ubuntu-latest (stable): queued/pending; Build on macos-latest (nightly): queued/pending; Build on windows-latest (stable): queued/pending; Build on macos-latest (stable): in_progress/pending; Docs Lint: queued/pending; Discover Package Coverage: queued/pending; Generate Coverage Report: queued/pending; Security Scan: queued/pending". At posting, develop is ec1f58ec9.

… 16-jobs delta to 33.0

The F4 fix overwrote results/jobs-{4,8,16}.summary.txt with a differently
formatted recomputation instead of leaving the runs' own output in place,
and that recomputation had a precision-loss bug: it rebuilt the baseline
from the already-rounded GiB figure in the old summary instead of the exact
kB baseline on the summary's first line, which gave 32.9 GiB for the
16-jobs peak MemAvailable drop instead of the correct 33.0.

- Restored the three summary files to exactly what each run printed (as
  committed in a3aaab7, before the F4 regeneration).
- Corrected report.md's 16-jobs delta cell to 33.0 and added a sentence
  stating which of its columns are copied unmodified from the run output
  and which are recomputed from the raw samples.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Warning

Copilot couldn't run its full agentic review because it didn't start before the timeout. Make sure your repository has a runner available, or add a copilot-code-review.yml file specifying one with the runs-on attribute. See the docs for more details.

Copilot review overview

6 open issues

Review effort: Lite

@da2ce7 da2ce7 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed at 0ebea338740e4e691dc22022714e10870d039ec4. Recomputed from the bytes at this head, against the merge base ec1f58ec9; git merge-tree against develop ec1f58ec9 writes tree 8bf826362, identical to the head tree, so the merge is clean.

Process: one new commit, a fast-forward of 3d9dfebc6, answering F14 with a reply and an audit row. The audit record passes the validator's checks, run offline against this head's review comments: 16 rows, 3 log entries, 0 failures. F15 to F20 have no reply yet, and the automated review's R3, R4 and four newer comments are open and not yet in the record.

Prior findings: F14 is resolved. The three run summaries have the same blob ids as when the runs were first committed, and report.md:45 now reads 33.0 GiB, which the samples give (32.964). F1 to F7 and F9 to F13 stay resolved. Still open and non-blocking, with their files unchanged except the moved report lines:

  • F8 Nit (progress-log times);
  • F15 Minor (report.md:100, the runner run without data);
  • F16 Minor (the commit-id check still prints four ids, and PR-REVIEW.md:245-246 add a3aaab735);
  • F17 Nit (report wording);
  • F19 Minor (audit entries overstate);
  • F20 Nit (F6's resolution reference).

The change against its claim: the commit restores the summaries and corrects the one cell, as its message says. Its account of the 32.9 (a baseline rebuilt from the rounded 47.0 GiB) recomputes to 32.93. The new Method sentence says the peak rustc RSS is not in the summary files, but each carries it (F21).

Verdict: no finding here makes the merged bytes wrong, but the record is not complete. Eleven threads are open: F15 to F20 have no reply yet, and the automated review's R3, R4 and four newer comments are neither answered nor in the record. As in earlier rounds, the verdict stays a comment, without ACK, until each open thread has a reply and a row and the validator passes over them.

Hygiene: Conventional subject with [#2853], body matches the diff, author equals committer, git diff --check clean, and the closing-keyword scan finds no match. Each commit has one attribution footer line (no rule in the tree on it).

Findings: F21 Nit; F8, F15, F16, F17, F19, F20 open as posted.

Checked, no finding: summary blobs against the commit that added them; the table against the restored summaries and the samples; the F14 audit row against its thread and reply; the description, unchanged.

Checks

On the loop's compute node at this head, against the merge base ec1f58ec9 (receipt server-gates-kranich-827): the repository's pre-commit gate and lint roster exit 0 and the tree left clean; the repository's audit validator on pr-2854-review exit 0 (16 rows, 3 log entries, no failures), though it checks only the rows the record has. No Rust package changes, so no package tests apply. F14's fix checked against the bytes at posting: the three results/jobs-*.summary.txt blobs at this head are the same objects as at ca14aeb82, where the runs first committed them. Read on the forge: 16 review threads are resolved and 11 are open. GitHub checks at this head at posting time: "". At posting, develop is ec1f58ec9.

…chor, stage overlap, audit accuracy

Copilot (R3, R4, and a newer unlabeled review) and da2ce7 (F15-F17, F19, F20)
found more issues after the previous push:

- measure.sh: anchor the running-build check to the PID field with awk
  instead of a whole-line grep (R-equivalent high severity, could miss a
  concurrent build); export LC_ALL=C so its printf/awk output is no longer
  locale-dependent.
- report.md: scope the two-stage overlap bound to the two workspace
  branches only, since tester's own source-install fallback is independent
  of and concurrent with both; fix the 2.09-2.60 GiB/job range (was
  2.2-2.6); stop claiming the earlier measure.sh divided anything (it only
  printed two maxima); drop the unsupported stage-handoff explanation for
  the process-count spike; remove a duplicated sentence; reword the runner
  bullet to state the actual job duration is pending instead of naming a
  run with no measurement in it.
- docs/containers.md: a changed CARGO_BUILD_JOBS value misses the next
  layer's cache (a different key), it does not discard what was cached for
  other values.
- Replaced every remaining branch commit id with its Conventional Commit
  subject in ISSUE.md and the audit record.
- PR-REVIEW.md: corrected its own Processing Log timestamps (no entry
  claims an event before its commit), fixed a mislabeled F1/F2 that meant
  R1/R2, corrected F6's and F8's resolution references, and removed a false
  claim that editing the early replies would lose their thread.
- manual-verification-evidence.md: quoted last-updated-utc.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>

@da2ce7 da2ce7 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed at 8bc30c0863e1d30d801e7fab56118253122e58e1. Recomputed from the bytes at this head, against the merge base ec1f58ec9; git merge-tree against develop ec1f58ec9 writes tree 210a460e9, identical to the head tree, so the merge is clean.

Process: one new commit, a fast-forward of 0ebea3387, with a reply, a resolved thread and an audit row for every finding raised before it. The audit record passes the validator's checks, run offline against this head's review comments: 27 rows, 4 log entries, 0 failures. One thread is open: F21 from my previous review was posted while this commit was being made, and it has no reply and no row yet. The record's audit-local F21 to F24 name the automated comments, so my F21 and this review's F22 and F23 need new audit IDs under the skill's collision rule.

Prior findings: F15, F17 and F20 are resolved, as are R3 and R4 from the automated review. Three rows say FIXED but are not fixed at this head (F22):

  • F8: ISSUE.md:124 still says the 4-job run started at 08:50.
  • F16: the skill's commit-id check still prints 334decbf9 (PR-REVIEW.md:233) and a3aaab735 (PR-REVIEW.md:258-259).
  • F19: the two 11:05 UTC Processing Log entries are unchanged and still sit in a 10:52:06 commit.

F21 stays open: report.md:24-25 still says the peak RSS is not in the summaries, and now contradicts line 61.

The change against its claim: export LC_ALL=C and the PID filter awk '$1 != self' do what the message says. The filter never removes a line in practice, since pgrep -af does not match the script's own command line. The overlap section now scopes "at most two" to the workspace branches and names the tester fallback. The cache paragraph now distinguishes a new key from pruning. The progress log and the report cite commit subjects. One new report sentence overstates (F23).

Hygiene: Conventional subject with [#2853], body matches the diff, author equals committer, git diff --check clean, and the closing-keyword scan finds no match. Each commit has one attribution footer line (no rule in the tree on it).

Verdict: COMMENT, no ACK, while the F21 thread has no reply and no audit row; no finding blocks.

Findings: F22 Minor, F23 Nit; still open: F8 Nit, F16 Minor, F19 Minor, F21 Nit.

Checked, no finding: every Reply URL against its thread; the locale export ahead of all numeric output; the PID filter; the reworded cache paragraph; the summaries, unchanged since round 4.

Checks

On the loop's compute node at this head, against the merge base ec1f58ec9 (receipt server-gates-kranich-833): the repository's pre-commit gate and lint roster exit 0 and the tree left clean; the repository's audit validator on pr-2854-review exit 0 (27 rows, 4 log entries, no failures), though it checks only the rows the record has. No Rust package changes, so no package tests apply. F22 checked against the bytes at posting: ISSUE.md line 124 still says the 4-job run started at 08:50, while the F8 row records it fixed. Read on the forge: 27 review threads are resolved and 1 is open. GitHub checks at this head at posting time: "". At posting, develop is ec1f58ec9.

…ps, report accuracy

da2ce7 found that two things from the previous round weren't actually
fixed, plus an audit-record self-check collision:

- report.md's Method section still claimed peak rustc RSS was absent from
  the restored summaries (only the count-at-peak-RSS figure is new) and
  still called printing the two independent maxima 'wrong' (only dividing
  one by the other was); the Stage overlap section claimed cargo binstall
  fetches from crates.io (it doesn't) and that the measured runs are shown
  not to have fallen back to a source compile (no build log was kept to
  show that).
- ISSUE.md's 08:50 entry still said the 4-job measurement started then (it
  started 08:31); two remaining bare branch commit hashes in the audit
  record's prose are now a commit subject and a plain description.
- The audit record's own Processing Log had two entries timestamped after
  the commit that contains them, describing events (replies) that in fact
  happened after that commit: left them as written (their content was
  accurate) and appended a correction instead of rewriting in place, per
  the skill's own rule.
- da2ce7 independently reused F21-F23 for three new findings, colliding
  with this record's existing Copilot F21-F23; reassigned as F25-F27 with
  the reviewer's original id recorded in each.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
da2ce7
da2ce7 previously approved these changes Nov 13, 2026

@da2ce7 da2ce7 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed at 3c8f86749c290a1a2e13fc3c6a91cee5ff38cae9. Recomputed from the bytes at this head, against the merge base ec1f58ec9; git merge-tree against develop ec1f58ec9 writes tree 68510757f, identical to the head tree, so the merge is clean.

Process: one new commit, a fast-forward of 8bc30c086. All 30 threads now have a reply and an audit row and are resolved. My F21 to F23 are recorded as audit-local F25 to F27 under the skill's collision rule, so this review's own F25 again collides; the author can map it the same way. The audit record passes the validator's checks, run offline against this head's review comments: 30 rows, 5 log entries, 0 failures.

Prior findings: F21, F23 and F8 are resolved: the Method paragraph now copies the peak RSS from the summaries and recomputes only the count, the overlap paragraph states the no-fallback point as an assumption, and ISSUE.md:124 no longer dates the 4-job run at 08:50. F19 is resolved by the appended correction, the form the skill prescribes. F22 is resolved for F8 and F19. F16 stays open: the skill's commit-id check still prints 334decbf9 and a3aaab735, now from the F26 row's Concern (PR-REVIEW.md:418), which quotes them while that row's verification line says no branch id remains.

The change against its claim: the report, spec and audit edits do what the message says, except for the F16 residue above. The new correction entry is stamped before the replies it reports, and one of its sentences does not parse (F25).

Consistency: the Method, "Per-process memory" and overlap paragraphs now agree with each other and with the restored summaries. Links and paths resolve.

Hygiene: Conventional subject with [#2853], body matches the diff, author equals committer, git diff --check clean, and the closing-keyword scan finds no match. Each commit has one attribution footer line (no rule in the tree on it).

Verdict: no finding blocks. The Containerfile and the scripts are unchanged since the earlier rounds, every figure a reader relies on recomputes from the samples, and F16 and F25 are wording in the audit record, repairable before or after merge.

Findings: F25 Nit; F16 Minor still open.

Checked, no finding: the reworded Method paragraph against the three summaries (10,4 / 19,8 / 35,5); the overlap paragraph; the 08:50 entry; each Reply URL against its thread.

Checks

On the loop's compute node at this head, against the merge base ec1f58ec9 (receipt server-gates-kranich-837): the repository's pre-commit gate and lint roster exit 0 and the tree left clean; the repository's audit validator on pr-2854-review exit 0 (30 rows, 5 log entries, no failures). No Rust package changes, so no package tests apply; the image build itself was not run here. F16 checked against the bytes at posting: line 418 of PR-REVIEW.md still quotes 334decbf9 and a3aaab735. Read on the forge: all 30 review threads are answered and resolved. GitHub checks at this head at posting time: "". At posting, develop is ec1f58ec9.

@da2ce7

da2ce7 commented Nov 13, 2026

Copy link
Copy Markdown
Contributor

ACK 3c8f867 — the report's figures recompute from the raw samples, every review thread has a reply and an audit row that passes the validator's checks, and the trial merge against develop is clean

@josecelano

Copy link
Copy Markdown
Member

ACK 3c8f867

@josecelano
josecelano requested review from da2ce7 and a balanced review from Copilot November 13, 2026 13:04
…d commit hashes

Appends a correction to the 11:40 UTC Processing Log entry (wrong timestamp,
one sentence that does not parse) instead of rewriting it, records that 16
review replies were edited to cite commit subjects, and removes the two
branch commit hashes quoted in the F26 Concern, so the open-pull-request
commit-id check prints nothing.

Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@da2ce7 da2ce7 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed at 71fc307040a79920d6e1f9843e17e78756656229. Recomputed from the bytes at this head, against the merge base ec1f58ec9; git merge-tree against develop ec1f58ec9 writes tree 6b3209bc2, identical to the head tree, so the merge is clean.

Process: one new commit, a fast-forward of 3c8f86749, touching only the audit record. The record passes the validator's checks, run offline against this head's review comments: 30 rows, 7 log entries, 0 failures. All 31 threads have a reply and are resolved. The thread of my F25 from the previous review has no audit row (F28).

Prior findings: F16 and F25 are resolved.

  • The skill's commit-id check, run in this head's worktree with UPSTREAM_REMOTE=work, prints nothing.
  • The 11:40 UTC entry is left as written, with an appended correction that gives the 11:42:12-17 reply times and restates the sentence that did not parse.
  • The capture confirms the 13:17 entry's account of the reply edits. Sixteen replies show updated_at 13:16:05-13:16:28. Each now cites a subject on this branch and no hex id. Their earlier texts in the previous capture read "Fixed in" with a branch id (R1, R2), "the commit addressing this review round" (eleven, created 11:24:17-39) and "the commit addressing this round" (three).

The change against its claim: the message matches the diff. The F12 row now records the reply edits. The F16 row cites the three commits that together removed the ids, and all three subjects exist on this branch. The F26 Concern names no hash.

Hygiene: Conventional subject with [#2853], body matches the diff, author equals committer, git diff --check clean, and the closing-keyword scan finds no match. Each commit has one attribution footer line (no rule in the tree on it).

Verdict: COMMENT, no ACK, until the F25 thread has its row; no finding blocks, and the code and the report are unchanged since the previous review.

Findings: F28 Minor.

Checked, no finding: every Reply URL against its thread; each edited reply's text against the branch subjects; the two 13:17 entries against the capture's timestamps; the description, unchanged.

Checks

On the loop's compute node at this head, against the merge base ec1f58ec9 (receipt server-gates-kranich-839): the repository's pre-commit gate and lint roster exit 0 and the tree left clean; the repository's audit validator on pr-2854-review exit 0 (30 rows, 7 log entries, no failures), though it checks only the rows the record has. This push changes only the audit record, so no package tests apply. F28 checked against the bytes at posting: no line of PR-REVIEW.md cites the comment id 4562957889. Read on the forge: all 31 review threads are answered and resolved. GitHub checks at this head at posting time: "". At posting, develop is ec1f58ec9.

josecelano-bot and others added 3 commits November 13, 2026 13:27
…view retrospective

- Evidence V4 and report.md: the Build Tracker Image step on the self-hosted
  runner took 814, 842 and 824 s in three runs of this PR (4 jobs) against
  721, 723 and 749 s in three uncapped develop runs, about 13% slower. M4 is
  done; AC6 stays TODO until the maintainer accepts that or asks for a
  higher value in the workflow.
- implementation-retrospective.md: what made the review of PR torrust#2854 slow
  (nine reviews, 31 findings, 5 of them on the 61 shipped lines) and ten
  proposals for a more deterministic review process.

Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
…ation lines

Adds the row and detail entry for the last finding after its reply and
resolution, and updates the F1 and F15 verification lines, which said the
runner result was pending, to match the tree.

Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
Adds the row, detail entry and log entry for the finding that asked for the
F28 row, after its reply and resolution. Removes two counts from the
retrospective pointer in ISSUE.md, which later reviews had made stale.

Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>

@da2ce7 da2ce7 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed at 9a69a6c09e7394043d573f34b9fcf771a207aa22. Recomputed from the bytes at this head, against the merge base ec1f58ec9; git merge-tree against develop ec1f58ec9 writes tree bdc11cc1a, identical to the head tree, so the merge is clean.

Process: three commits since my last review: 82d8af309 (runner times and a retrospective), 26012748a (the F28 row) and 9a69a6c09 (the F29 row). All 32 threads have a reply, a row whose Source URL cites the thread, and a resolution. The audit record passes the validator's checks, run offline against this head's review comments: 32 rows, 9 log entries, 0 failures. The skill's commit-id check prints nothing.

Prior findings: F28 is resolved. The F28 row records my earlier F25, and the F29 row records my previous F28, with its review, severity, reply and resolution subject matching the capture. Its 13:32 log entry sits in a 13:32:43 commit, after the 13:32:09 reply it reports.

The change against its claim: the runner figures are internally consistent. The means are 827 s and 731 s, a 96 s (13%) difference, and V4, report.md, the AC6 row and the description agree on them and on their limits. The run ids and times come from the forge and cannot be recomputed offline. M4 and T6 are DONE, and AC6 stays TODO with the decision left to the maintainer. The description links the issue without a closing keyword. The retrospective's tree counts recompute: 61 shipped lines, 1,816 added lines in 14 files, 832 sample lines, a 454-line record, 4/16/11 severities and 8 pushes. Its review counts do not (F30). The spec's pointer to it no longer repeats them.

Hygiene: Conventional subjects with [#2853], bodies match their diffs, author equals committer, git diff --check clean, and the closing-keyword scan finds no match. Each commit has one attribution footer line (no rule in the tree on it).

Verdict: the shipped change is unchanged since the second round, every figure a reader relies on recomputes, and the record is complete for every thread. F30 is wording in the retrospective and does not block.

Findings: F30 Nit.

Checked, no finding: the F1 and F15 verification lines against V4; every Reply URL against its thread; the new links; the Markdown shape of the changed files.

Checks

On the loop's compute node at this head, against the merge base ec1f58ec9 (receipt server-gates-kranich-841): the repository's pre-commit gate and lint roster exit 0 and the tree left clean; the repository's audit validator on pr-2854-review exit 0 (32 rows, 9 log entries, no failures). These pushes change documentation only, so no package tests apply; the image build itself was not run here. Read on the forge at posting: all 32 review threads are answered and resolved. GitHub checks at this head at posting time: "". At posting, develop is ec1f58ec9.

adds 1,816 lines in 14 files: the rest is the experiment (script, report and 832 lines of raw
samples), the issue specification, the evidence file and the 454-line review audit record.

The review took nine reviews (six by `da2ce7`, three by the automated reviewer) and eight pushes

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[Nit][F30] The review counts were stale when this file was committed (13:27:29Z).

At 13:26:00Z da2ce7 posted a seventh review and the automated reviewer a fourth, and a 32nd finding followed (answered at 13:32:09Z, recorded as F29). So "nine reviews (six by da2ce7, three by the automated reviewer)", "31 findings, all answered and resolved" (line 38), "The last thread was resolved at 13:21 UTC" (line 40), "the same 31 findings" (line 67) and "all 31 findings" (line 241) describe an earlier moment. State the time the counts were taken, or update them. The tree-derived counts (61, 1,816, 14, 832, 454, 4/16/11, 8 pushes) all recompute.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed: the counts were taken before the two reviews of 13:26:00 UTC and the retrospective was committed at 13:27:29 UTC, so "nine reviews" and "31 findings" were already stale. The maintainer decided to defer this: it will be corrected in the close-out after merge (state the time the counts were taken and the final totals), together with its row in the audit record. No push is made for it now, so the approved head stays as reviewed. Leaving this thread open until that correction lands.

@da2ce7

da2ce7 commented Nov 13, 2026

Copy link
Copy Markdown
Contributor

ACK 9a69a6c — every review thread has a reply, an audit row and a resolution, the record passes the validator's checks, the commit-id check is empty, the report's figures recompute and the trial merge against develop is clean

@josecelano

Copy link
Copy Markdown
Member

ACK 9a69a6c

This branch was successfully deployed

1 active deployment
coverage — 9a69a6c0 Deployed Nov 13, 2026 by josecelano-bot via Generate Coverage Report #3152
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.

Limit the Cargo parallelism of the container image build by default

4 participants