|
| 1 | +--- |
| 2 | +subject: build-progress-and-scheduling |
| 3 | +status: active |
| 4 | +--- |
| 5 | + |
| 6 | +# BMI publication, compiler capacity and active download budgets |
| 7 | + |
| 8 | +Audience: maintainers closing the 2026.11.5.2 candidate and reviewing PR #889. |
| 9 | +This record separates three failures exposed during candidate validation. |
| 10 | +It does not qualify a diagnostic object substitution as a released binary. |
| 11 | + |
| 12 | +## Failure boundaries |
| 13 | + |
| 14 | +| Failure | Confirmed cause | Owner | |
| 15 | +|---|---|---| |
| 16 | +| An importer cannot find a BMI after its interface is touched | GCC unlinks the old final path before renaming the new BMI; an absent identity was accepted as publication | Core detached compilation | |
| 17 | +| A build exceeds its requested compiler count | Extra Ninja slots serve publication and join edges, while ordinary compilers bypass the detached semaphore | Core Ninja scheduling | |
| 18 | +| A newly activated download is immediately considered stalled | Its queued state was observed earlier; starting without a source attempt or byte change retained the queue-entry timestamp | Core provider progress tracking | |
| 19 | + |
| 20 | +No compiler toolchain payload, plugin semantic or timeout constant is changed |
| 21 | +by these corrections. |
| 22 | + |
| 23 | +## BMI publication |
| 24 | + |
| 25 | +GCC 16.1 tracing shows an `unlink(final)` immediately before |
| 26 | +`rename(temporary, final)`. The observed interval was approximately 26 |
| 27 | +microseconds. A changed identity alone is therefore insufficient: publication |
| 28 | +requires a present file with a changed identity. The adapter still preserves |
| 29 | +the previous BMI for equivalence checking and failure recovery. |
| 30 | + |
| 31 | +The causal control amplifies only that existing unlink interval to 200 |
| 32 | +milliseconds. The previous core reproduces the candidate failure: the middle |
| 33 | +module cannot read the core module. Replacing only the detached-compilation |
| 34 | +implementation makes the same real GCC workload succeed. A separate |
| 35 | +deterministic publisher confirms the boundary: the old phase returns zero |
| 36 | +while the BMI is absent; the corrected phase returns only after publication. |
| 37 | + |
| 38 | +An exit status of zero without the required BMI is diagnosed as a failure. |
| 39 | +The previous BMI is restored. E2E 234 retains its cold execution, graph-shape, |
| 40 | +incremental build and stale-token assertions, and adds both publication cases. |
| 41 | + |
| 42 | +## Shared compiler permits |
| 43 | + |
| 44 | +The candidate generated `sched_cap = 8`, while its scheduling policy allows |
| 45 | +48 Ninja slots. The BMI supervisor used that semaphore; ordinary C/C++ |
| 46 | +compilation and compiler-driven scanning did not. A full local candidate |
| 47 | +build exceeded eight compiler processes and encountered memory-pressure |
| 48 | +kills. Its interrupted output is not build qualification. |
| 49 | + |
| 50 | +The selected correction retains one actual compiler budget. Under the |
| 51 | +detached strategy, ordinary built-in compilation and scanning use an internal |
| 52 | +argv executor holding the same permit until the real child exits. BMI |
| 53 | +supervisors continue to hold their permit across early publication and code |
| 54 | +generation. Join edges acquire no permit. A holder never waits for another |
| 55 | +permit, so waiting joins cannot form a permit dependency cycle. |
| 56 | + |
| 57 | +The internal executor introduces no user mode and no argument serialization. |
| 58 | +It receives the compiler's actual argv, inherits the existing streams and |
| 59 | +returns its status. Existing response files retain their original owner and |
| 60 | +encoding. Ordinary completion and interrupt cleanup release a permit once; |
| 61 | +release cannot remove a permit already acquired by another compiler. |
| 62 | +Failure to create or acquire the semaphore is reported rather than followed |
| 63 | +by an unbounded compile. A failed supervisor start releases its permit. |
| 64 | + |
| 65 | +The mixed control uses a real generated Ninja graph and GCC 16.1. A driver |
| 66 | +records active invocations and remains alive briefly after BMI publication, |
| 67 | +amplifying overlap with ordinary C and C++ units. With a requested cap of |
| 68 | +one, the previous graph reaches six active drivers. Corrected controls use |
| 69 | +caps of one and two, retain the extra Ninja slots, and observe peaks of |
| 70 | +exactly one and two. They also check no-op builds, ordinary compiler failure, |
| 71 | +a module failure after BMI publication, subsequent recovery, ordinary |
| 72 | +compiler cancellation, child termination and permit cleanup. E2E 234 retains |
| 73 | +the full-set stale-token reclamation check. |
| 74 | + |
| 75 | +These local controls use selected recompiled objects and an extracted copy of |
| 76 | +the production dispatch branch. They establish causality and small-load |
| 77 | +behavior. The complete current sources still require the ordinary CI build |
| 78 | +and all required checks before release. |
| 79 | + |
| 80 | +## Download activation and deadline reasons |
| 81 | + |
| 82 | +The pinned xlings 2026.10.26.1 provider reports queued files in each batch |
| 83 | +with `started = false`. Once a worker obtains a slot, `started` becomes true |
| 84 | +before a source attempt or byte count necessarily changes. That transition |
| 85 | +starts the active budget. Waiting in the queue consumes no active budget; |
| 86 | +repeated samples of an already active file do not renew it. A byte increase |
| 87 | +or source change retains its existing renewal semantics. |
| 88 | + |
| 89 | +An isolated provider invocation retained raw NDJSON from one download stream. |
| 90 | +Replaying the same 347 snapshots through the actual C++ provider modules gives: |
| 91 | + |
| 92 | +| Module | Expired snapshots | First expiration | |
| 93 | +|---|---:|---:| |
| 94 | +| Previous state machine | 11 | 95.751 seconds | |
| 95 | +| Corrected activation transition | 0 | none | |
| 96 | + |
| 97 | +The first false expiration belongs to a queued entry activated at 95.751 |
| 98 | +seconds with source attempt zero. Its inherited age was 95.651 seconds. |
| 99 | +With queue time excluded, the maximum active idle interval at the observed |
| 100 | +snapshots is 7.735 seconds. The isolated network invocation reached its |
| 101 | +150-second observer budget; it was stopped by the experiment, not by a |
| 102 | +provider progress deadline, and does not establish a completed graphics run. |
| 103 | + |
| 104 | +The failed candidate CI log contains rendered status rather than raw NDJSON. |
| 105 | +Its timing is consistent with activation of the final queued entries. It |
| 106 | +does not identify which raw file state first expired, and is not presented as |
| 107 | +proof of a particular file's network behavior. Progress on an independent |
| 108 | +download remains insufficient to renew a genuinely stalled file. |
| 109 | + |
| 110 | +The provider source was followed through its HTTP implementation: the |
| 111 | +connect and idle environment budgets are consumed below the downloader |
| 112 | +wrapper. They remain eight and thirty seconds, respectively; the parent's |
| 113 | +per-file budget remains forty-five seconds. No budget is increased to hide |
| 114 | +the state error. Progress timeouts now identify the file, interval and source |
| 115 | +attempt; process deadlines remain distinct. Time-injected unit cases cover |
| 116 | +queue waits longer than forty-five seconds, genuine per-file stalls, source |
| 117 | +fallback and completion. |
| 118 | + |
| 119 | +## Qualification sequence |
| 120 | + |
| 121 | +The local controls precede the complete PR CI. The graphics job is accepted |
| 122 | +only after its shader, rendered-image and pixel assertions actually run. |
| 123 | +After every required check succeeds, an independent ecosystem review |
| 124 | +precedes merge and release. Published tags remain unchanged. |
| 125 | + |
| 126 | +Plugin PR #52 has independently passed all six jobs against the published |
| 127 | +2026.11.5.1 core. Its final public core pin and real subproject-sidecar fixture |
| 128 | +follow ordinary installation of the new release, in the same plugin PR. |
| 129 | + |
| 130 | +Public records contain synthetic assertions and aggregate evidence. Raw |
| 131 | +provider streams, user logs, usernames and private paths remain outside the |
| 132 | +repository and pull-request description. |
0 commit comments