Repository navigation
Candidate: add the selected-capacity admission helper - #801
Conversation
Complete the selected-capacity production entry and add pineforge-selected-admit, a small command-line program that checks a caller's capacity bounds on the Source and the selected inputs of a run before the first writer consumes them. Production entry: the five selected-capacity observers are bound through the native materializer, and actual Source records and CSV bytes are accounted with the existing reserve primitive. Input-sensitive tests cover the field limits, the exact failure arguments, the byte accounting and the production binding. Helper: it reads a versioned request descriptor (tools/selected_admit/ DESCRIPTOR-V1.md specifies the request, the result and the manifest), takes custody of each input by descriptor number, size and digest, parses it with the existing selected-capacity reader, calls the product entry, and answers with one result document and an exit status. The Source stage forwards each record only after it is admitted, and refuses a forward descriptor that is the same file as its stdout or stderr (exit 41); the Selected stage counts the selected pass and retains nothing. The helper and its manifest (size, sha256, build identity, schema digests, stages) install to bin/ and share/pineforge/. The sha256 of the spec is compiled into the manifest, so a change to the spec changes the manifest. The spec also lists what the Source stage holds in memory (the record window and the reader's copy of one field, each up to the record cap, a chunk and the process base) with one measured figure, and what the helper reads from the environment and the file system: GLIBCXX_TUNABLES at start, and, for a calendar zone that is not UTC-like, TZ and, per libc, TZDIR and the zone file under the zone database root. Tests: descriptor, custody, stage and manifest tests, the Source-stage parity test, an import-list test and a calendar test. The import-list test reads the undefined symbols of the built helper with nm and fails if it imports one of its list of 41 process, thread, session, socket, descriptor-duplication, signalling, system-call or library-loading functions, other than dlopen (one RTLD_NOLOAD lookup of the engine's own image) and recvmsg (the run-quota endpoint). The two allowed names are pinned in the test, a glibc fortified or internal spelling of a forbidden name counts as the name, an nm line that cannot be parsed stops it, and a listing without pread, poll and __cxa_begin_catch, which the helper builds measured so far import, is rejected as empty, truncated or unrelated; having them proves neither completeness nor which file nm read. The calendar test runs the Selected stage with New York four-hour script bars across the two clock changes of 2024: the open of the date's own season is admitted, the open of the other season is refused with the neighbouring bar opens that civil-time arithmetic gives, and a zone database root that holds no zone makes the zone unsupported. Inventory: the allocation-site inventory gets the three new Source-stage groups and five site rows, the unreviewed ceiling goes from 1410 to 1413 and the exact-union pin to 1356 + 57 + 184, the five selected limit routes of the ownership manifest are corrected, and the CMakeLists.txt line citations in five documents are re-anchored (three citations that named a neighbouring line now name the line they describe). Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
| # Retain the decoy outside the install location; delete no file. | ||
| configure_decoy.rename(root / "retained-configure-decoy") | ||
| self.run_command(["cmake", "--install", str(build)]) | ||
| binary = check_install(configure_prefix, chosen_sha, True) |
| configure() | ||
| build_all() | ||
| self.run_command(["cmake", "--install", str(build)]) | ||
| binary = check_install(configure_prefix, chosen_sha, False) |
| import subprocess | ||
| import sys | ||
| import tempfile | ||
| import unittest |
| while position < len(data): | ||
| count = os.write(input_write, data[position:position + 4096]) | ||
| position += count | ||
| except BrokenPipeError: |
| position += count | ||
| except BrokenPipeError: | ||
| pass | ||
| except BaseException as error: |
| total += len(chunk) | ||
| if total >= len(HEADER): | ||
| resume.set() | ||
| except BaseException as error: |
| self.assertGreater(count, 0) | ||
| written[0] += count | ||
| pending = pending[count:] | ||
| except BaseException as error: |
| if not chunk: | ||
| break | ||
| forwarded.append(chunk) | ||
| except BaseException as error: |
…utral names The registration file of the helper's unit tests, the fence around its script tests in tests/CMakeLists.txt, and the CTest label of all seven tests carried a name derived from a work card. They are now selected-admit-helper and selected_admit_helper. The registrations are otherwise unchanged, and nothing else in the tree named the old file or label. Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
There was a problem hiding this comment.
Graphify reviewed this change.
No issues found by static checks — no coupling regressions or blocking issues in the code graph. That is not the same as safe to merge: see what was not checked.
Not checked: tests were not run; no formal proof of the changed code.
Graphify review — findings
Adds a pineforge-selected-admit helper executable, installed to a fixed bin/ path alongside a generated share/pineforge/pineforge-selected-admit.manifest.json. The manifest records the helper's size and SHA-256, the version and git SHA, the dirty flag, the descriptor-spec and failure-catalog hashes, and the supported stages. CMake builds the real helper plus a test-identity twin under PINEFORGE_BUILD_TESTS, and the source stage is only included when stage_source.cpp exists, otherwise the manifest lists just selected. Adds a selected-capacity Source stage to the kernel: a streambuf-backed record window that reads the source in chunks and refuses records over a byte bound, with a result carrying a reason and message. Supporting units add source-row, byte-check and product-check logic to selected-capacity. Registers the three new Source-stage allocation sites (chunk buffer, record window, stored message) in the CR150 source-bounds gate as unreviewed, raising the unreviewed ceiling from 1410 to 1413. The diff also touches the native-engine, parity and Pine-to-native docs, whose content is not visible in the truncated diff.
Review partial — this diff was larger than one review pass covers, so later files were not reviewed; some findings may be missing.
Analysis details — impact, health, verification
Impact & health
Graphify review
Impact — 967 functions depend on the 786 functions this change touches.
Health — this change adds coupling hotspots:
- worse:
native_run_spec_digest()— 17 callers, 3 callees - new:
parse()— 6 callers, 8 callees - new:
check_install()— 5 callers, 5 callees - worse:
run_driver()— 1 callers, 15 callees - new:
grid_neighbours()— 4 callers, 3 callees - new:
expect_byte_refusal()— 4 callers, 3 callees - new:
render_result()— 1 callers, 11 callees - new:
execute_stage_source()— 1 callers, 6 callees - …and 4 more — each is listed as a finding
Verification — 967 functions in the blast radius were not formally verified this run (proofs are advisory here).
Gate & verification
graphify gate
PASS — objectively clean (no health regressions, tests not run — proofs not run this pass (advisory)). Grounded, not self-assessed.
Advisory (not blocking):
- verification_scope: 846 function(s) in the blast radius were not formally verified this run
Test selection
Test selection
1411 of 1411 test file(s) selected (100%) via static blast radius.
Escalated to a full run for safety (
noncode-change,uncovered-code) — the selection is not trustworthy on its own (see below). CI should run the whole suite.
benchmarks/tests/test_aggregate.py— full-run-safetybenchmarks/tests/test_check_provenance.py— full-run-safetybenchmarks/tests/test_compare.py— full-run-safetybenchmarks/tests/test_public_names.py— full-run-safetybenchmarks/tests/test_run_all.py— full-run-safetybenchmarks/tests/test_run_strategy_feeds.py— full-run-safetydocker/pineforge_sink_finalize_test.py— full-run-safetydocker/pineforge_sink_replay_rq_test.py— full-run-safetydocker/pineforge_sink_replay_test.py— full-run-safetydocker/pineforge_sink_to_json_test.py— full-run-safetydocker/quota_columns_test.py— full-run-safetydocker/quota_convert_test.py— full-run-safetydocker/quota_finalize_test.py— full-run-safetydocker/replay_rq_engine_test.py— full-run-safetydocker/run_json_artifact_window_test.py— full-run-safetydocker/run_json_bin_test.py— full-run-safetydocker/run_json_bounded_transport_test.py— full-run-safetydocker/run_json_bulk_equity_fuzz_test.py— full-run-safetydocker/run_json_bulk_equity_test.py— full-run-safetydocker/run_json_codes_test.py— full-run-safetydocker/run_json_converter_metadata_test.py— full-run-safetydocker/run_json_converter_session_test.py— full-run-safetydocker/run_json_diagnostics_test.py— full-run-safetydocker/run_json_equity_scan_test.py— full-run-safetydocker/run_json_fused_test.py— full-run-safetydocker/run_json_harnesses_test.py— full-run-safetydocker/run_json_metrics_only_test.py— full-run-safetydocker/run_json_misc2_test.py— full-run-safetydocker/run_json_misc_test.py— full-run-safetydocker/run_json_pfbar_test.py— full-run-safetydocker/run_json_provenance_test.py— full-run-safetydocker/run_json_quota_supervisor_test.py— full-run-safetydocker/run_json_replay_test.py— full-run-safetydocker/run_json_selected_sink_test.py— full-run-safetydocker/run_json_sink_lexical_test.py— full-run-safetydocker/run_json_sink_summary_test.py— full-run-safetydocker/run_json_sink_test.py— full-run-safetydocker/run_json_sink_vectors_test.py— full-run-safetydocker/run_json_spool_work_test.py— full-run-safetydocker/run_json_stringio_test.py— full-run-safetydocker/run_json_symbol_feeds_test.py— full-run-safetydocker/run_json_syminfo_test.py— full-run-safetydocker/run_json_trade_scan_test.py— full-run-safetydocker/run_json_window_budget_test.py— full-run-safetydocker/run_json_wrapper_work_test.py— full-run-safetyinclude/pineforge/native_run_spec.hpp— full-run-safetyscripts/derive_corpus_feeds_self_test.py— full-run-safetyscripts/fingerprint_self_test.py— full-run-safetyscripts/run_corpus_self_test.py— full-run-safetyscripts/test_abi_receipt_skips.py— full-run-safety- … and 1361 more
non-code file(s) changed (
CMakeLists.txt,ci/cr150-source-bounds.yaml,ci/cr150-source-sites.json,cmake/PineForgeSelectedAdmitManifest.cmake,docs/adr/0001-kernel-adapter-boundary.md…) → running the full suite for safety (a code graph can't see config/fixture/data deps)
changed code file(s) with no mapped test (
docs/adr/0001-kernel-adapter-boundary.md,docs/design/native-feature-parity.md,docs/pages/contributing-llm.md,docs/pages/native-engine.md,docs/pages/pine-to-native.md…) — a coverage gap or a missing link — running the full suite rather than only the selected tests
Selection is safe under the controlled-regression assumption; always-run tests + a periodic full run are the backstops. Advisory — it never changes the check verdict.
Docs that may be stale (advisory)
AGENTS.md§ What this repo is (lines 5-11): references changed symbolssourceAGENTS.md§ Layout (lines 26-41): references changed symbolssourceAGENTS.md§ Local-only tests (no CI job runs them) (lines 71-82): references changed symbolsselectedAGENTS.md§ Conventions (lines 103-116): references changed symbolssourceAGENTS.md§ Safety rules (lines 117-127): references changed symbolssourceCHANGELOG.md§ Unreleased (lines 8-206): references changed symbolsdrain,textCHANGELOG.md§ 1.9.1 — 2026-10-31 (lines 207-329): references changed symbolssourceCHANGELOG.md§ Closed-trade reads (lines 330-380): references changed symbolstextCHANGELOG.md§ run_json and CLI (lines 1126-1218): references changed symbolscalendarCHANGELOG.md§ State hashes (lines 1305-1370): references changed symbolsdigest,source
…and 10 more.
· 10 grounded finding(s) anchored inline below; 2 more finding(s) on lines outside this diff (see the check run).
| FOUR_HOURS_MS = 4 * HOUR_MS | ||
|
|
||
|
|
||
| def grid_neighbours(start_ms, offset_hours): |
There was a problem hiding this comment.
grid_neighbours()
high coupling complexity (Ca·Ce = 12).
Grounded coupling-delta finding (deterministic), not an LLM guess.
| std::vector<std::uint64_t> lengths; | ||
| }; | ||
|
|
||
| Parsed parse(Memory& memory, const std::string& digest, std::uint64_t cap, |
There was a problem hiding this comment.
parse()
fans out to 8 callees (efferent coupling); 6 callers depend on it (afferent coupling).
Grounded coupling-delta finding (deterministic), not an LLM guess.
| } | ||
| } // namespace | ||
|
|
||
| int main() { |
There was a problem hiding this comment.
main()
fans out to 9 callees (efferent coupling).
Grounded coupling-delta finding (deterministic), not an LLM guess.
| self.assertEqual(manifest["helper"]["bytes"], str(len(data))) | ||
| self.assertEqual(manifest["helper"]["sha256"], sha(data)) | ||
|
|
||
| def check_install(prefix, expected_sha, dirty): |
There was a problem hiding this comment.
check_install()
high coupling complexity (Ca·Ce = 25).
Grounded coupling-delta finding (deterministic), not an LLM guess.
| CHECK(!result.plan_attempted); | ||
| } | ||
|
|
||
| void equality_includes_headers_all_roles_and_actual_newlines() { |
There was a problem hiding this comment.
equality_includes_headers_all_roles_and_actual_newlines()
fans out to 8 callees (efferent coupling).
Grounded coupling-delta finding (deterministic), not an LLM guess.
| } | ||
| } | ||
|
|
||
| void empty_source_and_auxiliary_headers_are_charged() { |
There was a problem hiding this comment.
empty_source_and_auxiliary_headers_are_charged()
fans out to 6 callees (efferent coupling).
Grounded coupling-delta finding (deterministic), not an LLM guess.
| check_primary_prefix(run, 1); | ||
| } | ||
|
|
||
| void expect_byte_refusal(Run& run, std::uint64_t limit, std::uint64_t used, |
There was a problem hiding this comment.
expect_byte_refusal()
high coupling complexity (Ca·Ce = 12).
Grounded coupling-delta finding (deterministic), not an LLM guess.
| return true; | ||
| } | ||
|
|
||
| inline DecodeStatus decode_descriptor(std::string_view bytes, Stage stage, |
There was a problem hiding this comment.
decode_descriptor()
fans out to 9 callees (efferent coupling).
Grounded coupling-delta finding (deterministic), not an LLM guess.
| return j.finish(); | ||
| } | ||
|
|
||
| inline std::string render_result(const Outcome& out) { |
There was a problem hiding this comment.
render_result()
fans out to 11 callees (efferent coupling).
Grounded coupling-delta finding (deterministic), not an LLM guess.
| return sc::DriverReason::InternalError; | ||
| } | ||
|
|
||
| inline Outcome execute_stage_source(const Descriptor& d, const Seam& seam = Seam{}) { |
There was a problem hiding this comment.
execute_stage_source()
fans out to 6 callees (efferent coupling).
Grounded coupling-delta finding (deterministic), not an LLM guess.
The private-fixture reads check reads the add_test arguments of tests/CMakeLists.txt and refuses a variable that starts with _pf_ unless it saw that variable set in the files it reads. The manifest test took its expected stages from _pf_sa_stages_json, which the root CMakeLists.txt sets, so the check stopped on it and test_private_fixture_reads and its controls failed in every build that runs the full suite. The pull request always carries tools/selected_admit/stage_source.cpp, so the root sets that variable to ["source","selected"]; the test now gets exactly that text, and it still compares it with the stages in the built helper's manifest. Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
…rule CMakeLists.txt takes the sha256 of tools/selected_admit/DESCRIPTOR-V1.md into the selected-admit helper's manifest at configure time, so a change to that page changes a build output. The docs-only rule called every Markdown file outside its excluded trees documentation, and test_no_cmake_file_reads_documentation (the docs-only-tests stage of preflight) failed on exactly this page: Lists differ: ['tools/selected_admit/DESCRIPTOR-V1.md'] != []. The page joins PROOF_READS, the list of documentation inputs that proof jobs read, so a change to it runs every proof leg. The pinned list in the rule's test, the scan test that now requires the page among the CMake reads it must see, and the sentence in docs/ci.md that counts the excluded files are updated with it. A new test replays the page in real git histories: an edit, a rename away, a rename onto its path and a deletion all run the proof legs, and another Markdown page of the same directory stays documentation. Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
… pin it with a calendar test The spec page said that a bare name "that is also a valid POSIX rule" is accepted as a POSIX rule when no usable zone file is found for it. What the helper applies is its own check (tz_posix_spec_accepted in src/native_calendar.cpp), not whatever a C library calls valid, so the page now names that check in both places where it states the exception. The calendar test pinned that a named zone is refused when the zone database root is missing, but nothing pinned the other half of the sentence. The new row runs the bare name EST5EDT under a missing root: the session opens of a mid-winter and a mid-summer date are admitted, the other season's open is refused as unaligned with the true grid neighbours, and the named zone America/New_York under the same root is the control (refused where the C library reads the root, admitted where it does not). Only mid-season dates are used, because the rule set a bare POSIX name without an explicit rule follows near a transition is the C library's default. Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
…ranch Brings the train branch (train/engine-1.11.1) into this branch, so that the branch can be merged into the train branch as a member change. Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
…#825) Include #797, #804, #817, #801 and #816: closed-trade cache placement, fill-time drawdown halt and flatten, reversal exit sizing, selected-capacity admission, and the percent default quantity cap. Document the intentional replacement of these earlier descriptions: - docs/design/native-feature-parity.md, introduced by 91d65ad: the old `update_risk_state(bar.close)` once per script bar at the close mark description is obsolete after #804. The cell now describes the fill-time peak, closing-fill threshold, halt latch and immediate flatten. Preserve MG10-a and MG10-b as HISTORICAL, measured on engine f5e929d, before the #804 change, with their values, claim status and grade unchanged. - docs/pages/memory-management.md, introduced by ba14721: "Storage is private: a global ordinal chooses one four-way set" no longer describes placement below the cap after #797 (653be41). Row n owns slot n while retained rows fit the cap; above it the existing four-way sets apply. Crossing the cap invalidates hot rows while retaining allocated pages. - docs/pages/memory-management.md, introduced by 69cddc9: "Page growth preserves entries through the 64/128/256 boundaries." is replaced by the current 256-slot page-boundary rule, which preserves entries through every page boundary within the cap. Re-anchor the remaining documentation citations and move the private-fixture registration evidence anchor from line 3470 to the actual token at line 3473. Preserve its row, predicate and reason; no new parity result or closed surface is claimed. Closes #804, closes #805. Co-Authored-By: Claude Opus 5.5 <[email protected]>
Candidate build, not ready to merge. This pull request is four commits made on
mainas it stood ata4472324. Its head (33125563) is a member of the 1.11.1 engine train: the newermain(f5e929df) is merged on the train branch, not in this pull request, which has no merge commit. The results below ran on these four commits. The four commits are: the helper with its tests (9dab4ef8); a second commit that only gives the helper's CMake registration file, its fence and its test label neutral names (ecff2566); a third that changes one line, the expected stages the manifest test is given (e7105555); and a fourth that lists the helper's spec page among the pages a proof job reads, in the rule that decides which changes skip the proof jobs (33125563). It completes the selected-capacity production entry thatmainonly declares today and addspineforge-selected-admit, a small command-line program that checks a caller's capacity bounds on the Source and the selected inputs of a run before the first writer consumes them. It merges only through the normal gates: CI green, the parity check, and a review of the final head.What it adds
pineforge-selected-admitreads a versioned request descriptor and its inputs from inherited file descriptors, takes custody of each input by descriptor number, size and digest, applies the caller's five capacity bounds with the product entry, and prints one result document with an exit status per outcome. The Source stage forwards each record only after it is admitted, and refuses a forward descriptor that is the same file as its stdout or stderr (exit 41, before any read); the Selected stage counts the selected pass and retains nothing.tools/selected_admit/DESCRIPTOR-V1.mdspecifies the request, the result and the manifest; its two example result documents show what the helper prints. The spec also lists what the Source stage holds in memory (the record window and the reader's copy of one field, each up to the record cap, a chunk and the process base) with one measured figure, and what the helper reads from the environment and the file system:GLIBCXX_TUNABLESat start and, for a calendar zone that is not UTC-like,TZand, per C library,TZDIRand the zone file under the zone database directory.bin/pineforge-selected-admitand its manifest toshare/pineforge/pineforge-selected-admit.manifest.json. The manifest records the size and sha256 of the helper, the build identity and the sha256 of the spec (descriptor.spec_sha256), which is taken at configure time, and the stages the helper offers.test_selected_admit_manifestconfigures, builds and installs the engine in a second tree (always a Release build), then checks the installed manifest against the installed helper: its--describeoutput, the size and sha256 of the file, the build identity, the spec and failure-catalog digests, the stages, a probe of the Source stage and five Selected-stage requests: three carry an identity the helper must refuse (exit 40), two carry the matching identity and are answeredno_requested_fields(exit 10). The requests use empty bounds and a header-only CSV; the test does not exercise admission with real bounds and records.test_selected_admit_importsreads the undefined symbols of the test-identity build of the helper (the same sources with a fixed test identity unit; this test does not read the shipped target) withnmand fails if it imports one of its list of 41 process, thread, session, socket, descriptor-duplication, signalling, system-call or library-loading functions, other thandlopen(oneRTLD_NOLOADlookup of the engine's own image) andrecvmsg(the run-quota endpoint); a glibc fortified (__name_chk) or internal (__name) spelling of a name counts as the name. The two allowed names are pinned in the test, a line of thenmlisting that cannot be parsed stops it and the secondnmoption is not tried, and a listing withoutpread,polland__cxa_begin_catch(a fortified spelling counts), which the helper builds measured so far import, is rejected as empty, truncated or unrelated; having them proves neither that the listing is complete nor which filenmread. It reads symbol tables only.test_selected_admit_calendarruns the Selected stage with a New York calendar of four-hour script bars, which are anchored at the session open, across the two clock changes of 2024. The open of the date's own season is admitted; the open of the other season is refused withboundary_unalignedand the neighbouring bar opens that civil-time arithmetic gives; a zone database directory that holds no zone makes the zone unsupported; a UTC calendar ignores the directory. Every expected instant is derived in the test. It needs the system zone database and fails, not skips, without it. Only a glibc build of the engine readsTZDIR, so on any other host the two missing-directory rows expect the admitted answer.1356 + 57 + 184. The five selected limit routes of the ownership manifest are corrected, and theCMakeLists.txtline citations in five documents are re-anchored (three citations that named a neighbouring line now name the line they describe).CMakeLists.txttakes the sha256 of the spec pagetools/selected_admit/DESCRIPTOR-V1.mdinto the helper's manifest at configure time, so a change to that page changes a build output. The page is now listed inPROOF_READSinscripts/ci_docs_only.py(the pages a proof job reads, which never count as documentation), its pinned list and the scan that finds pages read by CMake are updated, anddocs/ci.mdcounts six such files instead of five.Checks run before opening
Each result names the head it ran on and says what kind it is. Historical results ran on the first commit and are not repeated on the later heads. Focused results are a chosen set run on the named head. CLOUD results are full verify profiles on x86_64 cloud machines. A historical result is not evidence for a later head unless a focused or CLOUD item below says so.
Historical: first commit (
9dab4ef8), one Linux arm64 hostfork;dup2,pthread_create,socketandsystem;syscall; a fortifiedrecvfrom(__recvfrom_chk, which the version without the spelling rule passed); or onlyputs; against a stand-innmthat prints a line that is not annmline; and against a copy of the test whose allow-list has a third name.TZDIRforced to a missing directory.ci/with a ceiling of 1412 failed with exactly one ceiling finding, and the previous exact-union pin failed with1597 != 1594and nothing else.Focused: second commit (
ecff2566), one Linux arm64 hostctest -N -L selected_admit_helperlists the seven helper rows (registration only: nothing was built or run for them) and the old label lists none; the list of all tests with their commands and properties is the first commit's apart from that label. The registration file now sorts earlier, so 73 rows get new CTest numbers; no name, command or property changes.CLOUD: second commit (
ecff2566), x86_64 cloud machines (spot instances, 112 vCPU)test_private_fixture_readsandtest_private_fixture_reads_controls(2 of 1469 rows in debug, 2 of 784 in kernel, 2 of 1581 in release, 2 of 1440 in the sanitizer build). The private-fixture reads check refuses a CMake variable that begins with_pf_in a test command unless it saw that variable set in the files it reads, and the manifest test was registered with--expected-stages "${_pf_sa_stages_json}". That registration comes from the first commit and the second leaves it as it was; none of the focused runs above included these two rows. In the release and sanitizer builds the seven helper tests, the registration checker and its controls passed.test_no_cmake_file_reads_documentationinscripts/test_ci_docs_only.pyreportedLists differ: ['tools/selected_admit/DESCRIPTOR-V1.md'] != [](the fourth commit fixes this). The unittest shards of the same preflight (547 tests in 8 shards) passed, and so did the documentation build.Focused: third commit (
e7105555), one Linux arm64 host, Release${_pf_sa_stages_json}in that registration by the literal["source","selected"]. The literal mirrors the value that theCMakeLists.txtin the repository's base directory sets for the helper's stages:["selected"]at line 348, replaced at line 352 by["source","selected"]whentools/selected_admit/stage_source.cppexists, as it does in this pull request. The test still compares the literal with thestagesof the manifest of the built helper, so a change on either side fails it.test_private_fixture_readsandtest_private_fixture_reads_controls, the two rows that failed in the CLOUD builds of the second commit, pass; the configured manifest test command carries exactly["source","selected"].["selected"]or["selected","source"]for this tree it fails at the comparison with the manifest's stages; with the stage list changed in a copy of thatCMakeLists.txtit fails at the comparison of the manifest with the helper's own--describeoutput; on a copy of the tree withouttools/selected_admit/stage_source.cppit fails given["source","selected"]and passes given["selected"].ctest -N -L selected_admit_helperlists the same seven rows and the old label lists none; the 26 documentation and source guards and the net documentation-revert check end as on the second commit (the native-versions check skips for want of private fixtures).CLOUD: third commit (
e7105555), x86_64 cloud machinesFocused: fourth commit (
33125563), one Linux arm64 hosttools/selected_admit/DESCRIPTOR-V1.mdamong the pages a proof job reads (PROOF_READSinscripts/ci_docs_only.py), with the check that reads it:CMakeLists.txttakes its sha256 into the helper's manifest andtest_selected_admit_manifestcompares the installed manifest with it.scripts/test_ci_docs_only.pyfails on the parent's tree withLists differ: ['tools/selected_admit/DESCRIPTOR-V1.md'] != []; the new test file fails on the parent's rule (both pinned tests and the new test of the page) and passes on the new tree (27 tests). Through the rule's command line a change to the page alone is docs-only on the parent and not on the new tree; a documentation page and another Markdown page of the same directory stay docs-only. The new test replays the page in real git histories: an edit, a rename away, a rename onto its path and a deletion all run the proof jobs.docs/ci.mdkeeps its length, which the preflight pins.Not run for this head: the CLOUD verify profiles on x86_64, the parity sweep, any macOS build, and the review of the final head; the train gate runs them once on the train head (the members combined on
main), not on this head alone. The hosted CI legs of this pull request run on every push; their results are on its checks page and are not listed here. The manifest test builds its second tree as Release only, so the Debug, kernel and sanitizer profiles of the full suite run it without building the helper in those modes.🤖 Generated with Claude Code