Two things land together: the plan and contract draft P6 needs before it starts, and the
working notes that until now existed on exactly one machine.
1. P6's plan and contract draft (neither started; not one line of code)
docs/Disaggregated/P6-SPAWN-PLAN.md the package plan
docs/Disaggregated/P6-CONTRACT-DRAFT.md the contract draft (moves to
MG_Remote/CONTRACT-P6.md when c6 lands)
The three findings that mattered, all written into the documents:
a. P6 is SMALLER than its roadmap cell suggests. The transport primitives are already in
the tree and already tested: SocketDoorbell including hangup detection and the two
lost-wakeup fences (Doorbell.cpp:211-360, four cases in FdPassingTest), SCM_RIGHTS fd
passing, ShmSegment::Adopt, and the SurfaceOp / WindowKind schema already defined in
protocol.fbs. inproc uses a real second shm mapping rather than an alias, and
SessionRings.h:22-28 says that was done so today is not the first time it runs. P6 is
assembly plus a control plane plus a process, not "write a socket transport".
b. The evidence for "P6 is only a transport swap" has EXPIRED. It was bought by P5c, whose
audit found 59 direct memory accesses in a tree that already looked clean. P5e changed
the tree again. So the first package, a6, is a read-only audit that writes no code, and
every contract row that depends on it is marked PENDING a6 rather than decided in
advance.
c. P6 does not get a game running on the phone. ANativeWindow* is meaningless in the child,
and protocol.fbs:186-196's own comment says Android transfers the window out of band -
that band is P12. P6 lands pbuffer / surfaceless / offscreen, which is what HeadlessGL,
the split-equivalent lane and trace replay need, and which is exactly what P6's own exit
gate measures. A real window reaching the server is a named refusal. This gets its own
section because "P6 is done" would otherwise read as "the game runs now".
The contract adds rule G: a role may not name a process-local handle. It extends P5c's
rule E (a role may not name the other role's memory) from memory to identity - EGLDisplay /
EGLSurface / EGLContext / ANativeWindow* / fd number / pid / mapped address either cross as
a token this contract defines or they do not cross, and a descriptor crosses only through
SCM_RIGHTS, where the kernel renumbers it.
What P5e left for P6 gets its own section. The latch semantics are already designed
(ARCHITECTURE.md:504) and are copied unchanged. What is new is that after run-ahead the
client no longer waits while the peer process can DIE: the client holds records that were
published and will never be applied, and Android's freezer suspends the child without
closing anything. So slow and dead must be distinguishable WITHOUT a timeout threshold.
That is P6's only new design; everything else is carriage. It shares a predicate with E1's
outstanding re-specification (ID-122), and the two should be designed together.
Two gates carried over from P5e's lessons: G2 requires integration-spawn's test-name set to
match integration-split's name for name, because a differing set means the lane is quietly
running less; and the arm-proof gate requires every entry to record the child pid and
transport=spawn in its OWN private log - ID-124 established that this kind of false green
really happens, and a spawn lane that actually ran monolith would pass every other gate.
S2's shape must be settled before it is written, and the document says why: E1 is the
cautionary case.
2. The working notes move into the repository (docs/Disaggregated/notes/, 415 .md files)
ROADMAP / CURRENT_STAGE_PROGRESS / MEASUREMENTS cite ruling numbers, audit line numbers and
the provenance of gate figures from ~/w7/notes/, a directory that exists on one machine and
is under no version control. A record cited hundreds of times that lives only locally is not
a record, so it moves in whole, with its directory structure intact.
Only .md moves. Scripts, run logs, census and gate result JSON, patches, APKs and nm dumps
stay where they are: they are evidence DATA rather than documents - large, regenerated per
run, and mostly carrying absolute paths and device serials that mean something only on the
machine that produced them. The mapping and this split are written in
docs/Disaggregated/notes/README.md.
Two exceptions are recorded there too: P6's BRIEF has been promoted to a first-class
document and keeps no copy under notes/, so the two cannot drift apart; and recovered/ holds
material salvaged from failed workflow runs, which may duplicate the like-named phase
directories and is kept because a few of those were the only complete version at the time.
CI's citation lint takes docs/Disaggregated/*.md only (non-recursive), and notes/ is
deliberately outside it: those notes' file:line citations were written against their own
code heads, and resolving them against today's HEAD would fail wholesale - which is not an
error, it is their correct state as a historical record. To check one, use the revision it
declares (--rev).
3. Inconsistencies fixed in passing
- README.md's status line still said P5e was in progress while the stage table already said
closed.
- CURRENT_STAGE_PROGRESS's next-step item 1 still listed the exit gate as pending, though
(a) and (b) were run in the previous commit; rewritten to closed plus the one item that
actually remains (E1).
- ROADMAP's P6 row still had the pre-phase plan in three of its cells; it now carries the
package order, the scope boundary and the two new gates.
Checked with check_doc_citations.py: 125 citations across docs/Disaggregated/*.md, 0 problems.
24 KiB
P2 package E — p2/gates — result (v2, rework round 2)
Tree ~/w7/p2-gates, branch p2/gates, eight commits on the P2 contract commit 9c6a8a25
(refs/tags/p2/contract). Not pushed. Two new commits this round, on top of v1's aef43358.
The review scratchpad/wf5/p2-results/gates-review-v1.md rejected v1 with 2 majors and 10 minors.
Both majors are fixed. Eight of the ten minors are fixed (including the two the reviewer left
to the integrator — the G7 control's real path is now proven end to end, and the -j 4 flake's
pre-existence is now demonstrated by a control run, not argued). The two that remain are §4's D-1
and D-7, both of which are structurally outside package E and are re-declared below.
1. Commits
| sha | subject |
|---|---|
f02ca420 |
[Test] (Pipe): reproduce the handle ABA through public GL and pin the CSO content-addressing switch |
1b25f2c8 |
[Feat] (Trace): record per-frame thread CPU time beside wall time so a paired A/B can be read as CPU cost |
718818f1 |
[Feat] (Bench, Pipe): run the blend-toggle case in CI, give G7 a negative control, and record the two campaign devices |
3766d842 |
[Test] (Pipe): register the CSO control in the pull build too, so pull and push name the same tests |
bf62597c |
[CI] (Pipe): make the dirty-surface report a gate and run the push-only unit tests on the verify runtime |
aef43358 |
[Test] (Pipe): one case per CSO lane, because two of them would race on the lane's log |
07a7aa89 |
[Fix] (Test, Pipe): ask the BUILD, not the source tree, whether a control's arm exists, and probe the CSO emitter by content — majors 1 and 2, minor 4 |
71b1bd27 |
[Fix] (Trace, Bench, CI): compute p50 by the device's own median rule, fail the profile guard closed, and give the new control step its sibling's environment — minors 1, 2, 3, 6 |
Whole branch vs the contract: 17 files, +2021 / −32. This round only (aef43358..HEAD): 11 files,
+234 / −72.
Ownership (C.5): no violation. Every committed path is E's (.github/workflows/test.yml,
MobileGL/MG_Benchmark/**, MobileGL/MG_IntegrationTest/**, android-plugin/app/src/trace/cpp/**,
scripts/g7_negative_control.sh, tools/device_bench/**,
tools/trace_replay/run_android_retrace_local.py). No fixture binary touched. One uncommitted
experiment did write package A's files temporarily — declared as D-10 in §4, with the
byte-restore evidence.
2. The two majors
MAJOR 1 — the capability markers asked the source tree, not this build
Fixed in 07a7aa89, in three places.
- The whole capability block moved under
if (MOBILEGL_PIPE_PUSH)(MG_IntegrationTest/CMakeLists.txt), which is whereMGITEST_PIPE_PUSH_BUILDalready lived. A pull build now cannot setMGITEST_HANDLE_REKEY_*,MGITEST_HANDLE_ABA_IMPLEMENTEDorMGITEST_PIPE_TRACKER_PRESENTwhatever the sources contain, and says so at configure time:Integration tests: pull build - HandleRecycle.{Handles,AbaControl} and CsoContentAddressing stay registered (G2) and SKIP: every arm they assert is compiled only under MOBILEGL_PIPE_PUSH. - A second lock inside the scenario.
HandleRecycleScenario::SkipUnlessTheArmIsAssertableHere()checksMGITEST_PIPE_PUSH_BUILDfor theHandlesandAbaControlarms before the per-arm markers, exactly the shapeCsoContentAddressingScenario.cpp:207-214already carried. A hand-forced environment cannot arm an arm the library does not have. - The push-only knobs are no longer injected into pull-build lanes.
MOBILEGL_PIPE_LEGACY_MEMOS=0(Handles lanes) andMOBILEGL_PIPE_HANDLE_ABA_CONTROL=1(AbaControl lane) are set only whenMOBILEGL_PIPE_PUSHis on. Test names are unaffected — anENVIRONMENTproperty is not part of a name — so G2 still compares equal (verified below).
Verified, in build-linux (MOBILEGL_PIPE_PUSH:BOOL=OFF), with the two environments the reviewer
used to reproduce the defect:
env MOBILEGL_BACKEND_TYPE=DirectVulkan MGITEST_HANDLE_ARM=aba MOBILEGL_PIPE_PUSH=0 \
MOBILEGL_PIPE_HANDLE_ABA_CONTROL=1 MGITEST_HANDLE_ABA_IMPLEMENTED=1 \
./MobileGLIntegrationTest --gtest_filter='HandleRecycleScenario.AVertexArray*'
→ HandleRecycleScenario.cpp:289: Skipped
"the AbaControl arm needs a library built with MOBILEGL_PIPE_PUSH, and this one was not: the
{slot, gen} re-key and Features.PipeHandleAbaControl are both #if MOBILEGL_PIPE_PUSH …"
[ PASSED ] 0 tests. [ SKIPPED ] 1 test (was: 1 FAILED TEST)
env MOBILEGL_BACKEND_TYPE=DirectGLES MGITEST_HANDLE_ARM=handles MOBILEGL_PIPE_LEGACY_MEMOS=0 \
MGITEST_HANDLE_REKEY_DirectGLES=1 …
→ same skip (was: [ OK ] — a green asserting nothing)
Generated ctest environments, read out of *_tests.cmake in both builds:
build-linux (pull) |
build-push |
|
|---|---|---|
| Handles lane env | MGITEST_HANDLE_ARM=handles;__EGL_VENDOR… |
MGITEST_HANDLE_ARM=handles;MOBILEGL_PIPE_LEGACY_MEMOS=0;MGITEST_PIPE_PUSH_BUILD=1;… |
| AbaControl lane env | MGITEST_HANDLE_ARM=aba;MOBILEGL_PIPE_PUSH=0;… |
…;MOBILEGL_PIPE_HANDLE_ABA_CONTROL=1;MGITEST_PIPE_PUSH_BUILD=1;… |
MOBILEGL_PIPE_LEGACY_MEMOS=0 occurrences |
0 | 4 (2 files) |
MOBILEGL_PIPE_HANDLE_ABA_CONTROL=1 |
0 | 1 |
And the markers still arm when the packages land — simulated by copying the real files out of
the other packages' trees into this one and reconfiguring (then removing them; the tree is
byte-identical afterwards, git status shows only ?? build-retrace/):
copy p2-tracker/MG_Impl/Pipe/CsoCache.h, p2-espryt/MG_Backend/DirectGLES/SlotTables.h,
append one line naming kMGPipeSubsystemMagmaVertexInput / PipeHandleAbaControl to
MG_Backend/DirectVulkan/Renderer/VertexInputStateFactory.cpp
→ build-push: DirectGLES is keyed on {slot, gen} (SlotTables.h present)
the CSO counters have an emitter (…/MobileGL/MG_Impl/Pipe/CsoCache.h)
DirectVulkan's vertex input is keyed on {slot, gen}
MOBILEGL_PIPE_HANDLE_ABA_CONTROL has a consumer
→ build-linux: pull build - … stay registered (G2) and SKIP
(after removal + restore, both builds print the "will SKIP" verdicts again;
VertexInputStateFactory.cpp sha 0c5e2e00850dcfb2 before and after)
One place the tree contradicts the review (recorded, does not change the fix): the review's
third consequence — "MOBILEGL_PIPE_LEGACY_MEMOS=0 with every subsystem bit clear is D14's startup
Fatal{PipeLegacyMemosDisabled}" — would not actually have aborted a pull build. Both
implementations of that trap are inside #if MOBILEGL_PIPE_PUSH
(p2-espryt/.../Managers.cpp:173-197 ResolveEsprytSlotTablesArm,
p2-magma/.../MagmaPipeArms.h:13,47,79-91), so a pull build would have silently ignored the
knob rather than stopped. The fix stands on its own ground — a lane must not set a knob the build
cannot honour — but the integrator should not expect an abort as the symptom.
MAJOR 2 — G12's arming probe globbed a file package B does not create
Fixed in 07a7aa89. The probe is now a content probe over everything the tracker package
owns, not a filename:
file(GLOB MGL_ITEST_PIPE_CLIENT_SOURCES CONFIGURE_DEPENDS
"${MGL_ITEST_ROOT}/MobileGL/MG_Impl/Pipe/*.h" "…/*.cpp")
foreach(... ) # each file added to CMAKE_CONFIGURE_DEPENDS
file(STRINGS "${src}" hits REGEX "RenderStateCso(Mints|Binds)")
It looks for what the control actually reads — an emitter of CallClass::RenderStateCsoMints /
RenderStateCsoBinds — so the owning package keeps control of its file layout. Verified against
package B as it exists: ~/w7/p2-tracker's only match under MG_Impl/Pipe/ is CsoCache.h
(header-only, no Tracker.cpp), and copying that one file in arms the marker (transcript above).
On the contract tree, no MG_Impl/Pipe source names either counter, so the entries still skip —
with a reason that is now true and layout-independent: "no source under MobileGL/MG_Impl/Pipe/
names RenderStateCsoMints or RenderStateCsoBinds … this entry arms itself when they land, whatever
files that package chooses to put them in." The scenario's file header comment was corrected the
same way.
3. The minors
| # | review's finding | this round |
|---|---|---|
| 1 | format_benchmark's p50 was nearest-rank while the device median averages the two middle frames |
fixed — new series_median() transcribes SummarizeSeries (trace_replay_core.cpp:854-856); p95/p99 stay nearest rank and the docstrings now say which rule is which. Re-run pre-flight: device medianCpuMs=383.378, printed p50=383.378ms (host value 383.3785; the JSON writer rounds to 3 dp, which is the whole remaining difference). Rule check: [1,2,3]→2, [1,2,3,4]→2.5, []→-1.0 |
| 2 | the two new profiles claimed profile.sh refuses an unverified profile |
fixed — profile.sh records a simpleperf profile and pins nothing, so it needs no guard; the claim is corrected in both .env files and in README.md rather than a guard added where there is nothing to guard |
| 3 | require_verified_profile failed open on a profile that omits the key |
fixed — default is now ${PROFILE_VERIFIED:-0} in bench.sh and session.sh, odinlite.env carries PROFILE_VERIFIED=1 explicitly with the sentence that earns it, and the refusal reads "does not carry PROFILE_VERIFIED=1 (it says 0, or says nothing at all)". Verified: a /tmp profile with only DEVICE_SERIAL → rc 2 from both scripts; --allow-unverified-profile → the three [warn] lines then proceeds; devices/odinlite.env → passes the guard and reaches adb; devices/{xiaomi-adreno830,oppo-mali}.env → rc 2 |
| 4 | an unrecognised MGITEST_HANDLE_ARM silently became Legacy |
fixed — ArmNameIsRecognised() + FAIL() in SetUp, so a typo fails the fixture before the body runs. Verified: MGITEST_HANDLE_ARM=handels → 1 FAILED TEST, "unknown MGITEST_HANDLE_ARM value 'handels': the arms are handles / legacy / aba…" |
| 5 | g7_negative_control.sh had never run its real path |
fixed (proven) — see §3.1. Green before, red naming SetColorMask on the demotion, green again after the restore |
| 6 | the new CI control step was thinner than its sibling | fixed — it now carries ulimit -c unlimited, the kernel.core_pattern line and the three MOBILEGL_MAGMA_* variables, with a comment saying why it is the sibling's environment verbatim |
| 7 | the stale 2238 build-verify name count |
corrected: 2230. And a second stale figure the review did not catch: v1 quoted 918 integration-gpu entries in build-linux; the real number is 912 (contract 878 + E's 34), measured in both builds |
| 8 | pipe-gates is red on this branch alone |
still true, still declared (D-7). gen_pipe_dirty_surface.py --check exits 2 here; the flag is package B's and D.1 lands tracker first. The warning is repeated in §6 |
| 9 | the -j 4 flake's pre-existence was argued, not demonstrated |
fixed (demonstrated) — see §3.2 |
| 10 | D.2's "红 before the re-key" artefact is not produced | still true, still declared (D-1). The knob's consumer is package D's file |
3.1 The G7 negative control, run for real
Package A's five files were applied into this tree as an uncommitted simulation
(git -C ~/w7/p2-spans diff refs/tags/p2/contract..HEAD -- <5 files> | git apply, 1481 insertions),
build-push rebuilt, the control run, then everything restored:
[g7] 1 matching test(s) before the patch
[g7] RenderStateSpans\.SetterConsistency is green before the patch
[g7] demoting ColorMasks out of the pipeline half
[g7] the patched table still compiles, so the partition is still complete
[g7] negative control tripped, naming SetColorMask
[g7] restored; rebuilding
[g7] negative control tripped and the tree is green again
g7 rc=0
Restore evidence: the five files' sha256 list is identical before and after (diff empty),
git status --porcelain shows only ?? build-retrace/, build-push was rebuilt from the restored
sources and ctest -L unit is 100% tests passed, 0 failed out of 1489.
So all three halves of G7 are now proven on this tree: the refusal when the test is absent (rc 2),
the patch mechanism (--verify-patch-only, rc 0), and the control itself (rc 0, red for the right
reason). The integrator's D.3 run is now a repeat, not a first.
3.2 The -j 4 integration-gpu flake — a control run, not an argument
Selection identical to what the tree ran before package E existed (E's 24 entries excluded),
in build-linux, -j 4:
ctest -L integration-gpu -E 'HandleRecycle|CsoContentAddressing' -j 4 (run 1)
The following tests FAILED:
2354 - DirectVulkan.PrimGenReroute.…TheRerouteIsActuallyArmedWhenTheEnvironmentPinsItOn
2362 - DirectGLES.PointSizeDemotion.…TheDemotionIsActuallyArmedWhenTheEnvironmentPinsItOn
2367 - DirectVulkan.PointSizeDemotion.…TheDemotionIsActuallyArmedWhenTheEnvironmentPinsItOn
(run 2, same selection: green)
That settles it in the direction v1 claimed but did not prove: the failure reproduces with E's entries removed from the selection, and it is timing-dependent (a second run of the same selection passed). E's 24 extra processes are not the cause. It remains latent, CI is safe from it only because CI runs the label serially, and the fix (one filtered lane and one log per log-reading case, in three scenarios E does not own) is still out of this package's scope.
4. Verification — every command and what it said
All in ~/w7/p2-gates unless stated. Builds: cmake --build {build-linux,build-push,build-verify} -j 12 → rc 0, 0, 0.
4.1 Section-A gates reachable here
| gate | command | result |
|---|---|---|
| G1 | symbol_report.py --before ~/w7/p2-before-libMobileGL.so --after build-linux/libMobileGL.so --threshold 0 |
27799 -> 27799 defined symbols: 0 added, 0 removed, 4 resized, 0 renamed, .text +160 (+0.001%). The four resized are the contract's, unchanged from v1 (RenderState::RenderState() +148, SetCapability +77, IsCapabilityEnabled +29, _GLOBAL__sub_I_DirectGLES.cpp −9) — see C-2 |
| G2 | ctest -N names, pull vs push |
diff empty, 1402 each. Re-checked after the g7 rebuilds: still empty |
| G2 | ctest -L integration-gpu --no-tests=error serial, both builds |
build-linux 100% passed, 0 failed out of 912 (251 s); build-push 100% passed, 0 failed out of 912 (235 s) |
| G5 | RenderStateImpl sha, contract vs HEAD vs baseline |
all three d8fd1c48…20efe27 |
| G7 | bash scripts/g7_negative_control.sh build-push |
§3.1 — rc 0, tripped naming SetColorMask, tree green again |
| G8 | ctest --test-dir build-verify -R HandleRecycle --no-tests=error (with the CSO entries: 44) |
100% tests passed, 0 failed out of 44; the six .Legacy cases and every TheReproducerRecyclesEveryName execute and pass; the push arms skip with the reasons in §2 |
| G9 | gen_pipe_dirty_surface.py --check |
rc 2 — package B's flag (D-7) |
| G12 | ctest --test-dir build-linux -R CsoContentAddressing -j 4 |
all four skip, pull-build reason |
| G13 | grep -rc pGLContext MobileGL/MG_Backend | grep -v ':0$' |
empty |
| G13 | check_include_closure.py |
4 probes, 0 skipped, 0 problem(s) |
| G13 | gen_pipe.py --check / --self-test / git diff --exit-code -- MG_Pipe/generated |
rc 0 / 0 / 0 |
| G13 | the pipe-gates stdio alternation over MG_Backend + MG_State, verbatim from test.yml:1575 |
stdio gate clean |
| G14 | contract build-linux names vs this tree |
1368 → 1402: 0 removed, 34 added (baseline file unusable, C-1) |
4.2 Suites
| command | result |
|---|---|
ctest -L unit --no-tests=error -j 8 in build-linux / build-push / build-verify |
100% passed, 0 failed out of 1489 × 3 (16.4 s / 16.3 s / 14.3 s — the last is the measured cost of the new CI step) |
ctest --test-dir build-verify -R 'HandleRecycle|CsoContentAddressing' -j 4 |
100% passed, 0 failed out of 44 |
ctest --test-dir build-linux -R 'HandleRecycle|CsoContentAddressing' -j 4 |
34 entries, all skip with the pull-build reason |
ctest --test-dir build-bench -R DriverBench |
DriverBench Passed 1.48 s, DriverBenchStateToggle Passed 0.24 s |
| entry counts | build-linux 1402 total / 912 integration-gpu / 34 new; build-push identical; build-verify 2230 / 1740 / 44; contract build-linux 1368 / 878 |
4.3 The CPU series (D.4.1), re-pre-flighted after the p50 fix
build-retrace, one real replay of minecraft-1.17-main-menu-854 against build-linux/libMobileGL.so:
benchmark completed; frames=2, tailFrames=2, meanMs=1409.229, medianMs=1409.229, p95Ms=2801.059,
meanCpuMs=383.378, medianCpuMs=383.378, p95CpuMs=757.154, fps=0.710
format_benchmark → frames=2 total=2.8s tail=2 mean=1409.229ms median=1409.229ms p95=2801.059ms
fps=0.7 | cpu mean=383.378ms p50=383.378ms p95=757.154ms p99=757.154ms
with frameCpuTimesMs removed → … | cpu unavailable (no per-thread CPU clock in this run)
frameCpuTimesMs = [757.154, 9.603]; host series_median = 757.154 and 9.603 averaged = 383.3785
= the device's medianFrameCpuMs to the JSON's precision; host nearest-rank p95 = 757.154 =
the device's p95FrameCpuMs exactly.
5. Deviations from the brief
Carried from v1, unchanged (see gates-v1.md §4 for the full reasoning): D-2 (.Handles and
the CSO control skip structurally), D-3 (the CSO lanes register in the pull build too, for G2),
D-4 (g7_negative_control.sh patches the header, because the landed chunk table is in the
header), D-5 (the demotion is spelled as two extra boundaries), D-6 (both new device
profiles ship PROFILE_VERIFIED=0 and the two pinning scripts gained a refusal), D-8 (the
build-linux-verify arming grep accepts either entry-point name, so package B's rename does not
red it), D-9 (more commits than C.4's three).
Still open, and both are outside package E's ownership:
D-1 (blocking, unchanged) — D18's AbaControl arm cannot assert the corruption on this tree.
Features.PipeHandleAbaControl is parsed at ConfigLoader.cpp:267 and its consumers live in
MG_Backend/DirectVulkan/**, which C.5 gives to package D. (Package D's tree now does implement
it — VertexInputStateFactory.cpp names both PipeHandleAbaControl and
kMGPipeSubsystemMagmaVertexInput — so the arm arms itself on the integrated tree.) Integrator
action: D.2's "red before" log has to be taken after D lands the knob and before D enables its
re-key; it is not producible from E alone, and E's merge must not be read as having produced it.
D-7 (unchanged) — pipe-gates now runs a flag that does not exist yet.
gen_pipe_dirty_surface.py --check / --self-test are package B's. Do not run
gh workflow run test.yml on a tree that has gates without tracker.
New this round:
D-10 — an uncommitted, restored write to package A's files. To run the G7 control's real path
(review minor 5) I applied ~/w7/p2-spans's diff into this tree, built, ran the control and
restored. Nothing was committed; the five files hash identically before and after; git status
shows only ?? build-retrace/. I record it because C.5 gives those files to A and the rule is
about edits, not only about commits. ~/w7/p2-spans itself was not written to (only
git diff was read out of it), and no other package's tree was modified — the two files copied in
for the arming simulation (§2) were copies, removed afterwards.
D-11 — profile.sh did not gain the verified-profile guard the two new .env files claimed it
had. It pins nothing (it records a simpleperf profile), so the claim was corrected instead of the
guard added. Review minor 2 offered either.
6. Where the tree contradicted the brief or the review
C-1 — ~/w7/p2-before-ctest-names.txt is not comparable with any pull build (unchanged from
v1): it holds 2363 names; ctest -N reports 1364 in ~/w7/pipe/build-linux, 1368 in
~/w7/p2-contract/build-linux, 1402 here, 2230 in ~/w7/p2-gates/build-verify. comm -23
against it reports 999 "removed" for the untouched contract tree too. The integrator must
re-capture it from a pull build at 48268068. G14 was evaluated against the contract tree instead.
C-2 — the pull build's resized set is four symbols, not D15's three. _GLOBAL__sub_I_DirectGLES.cpp
is −9 bytes at the contract commit. G1 as written is already violated by the contract alone; this
package builds no library source.
C-3 — the tag p2/contract is ambiguous with a branch of the same name; use
refs/tags/p2/contract or the SHA.
C-4 — D19 says the control patches MGPipeRenderStateSpans.cpp; the landed chunk table is a
constexpr boundary array in the header (D-4). D6's offset table also differs from the landed
header in one row (StencilStates[0].Func) — package A's business.
C-5 — ARCHITECTURE.md:504's tools/bench.sh is tools/device_bench/bench.sh (the brief's
own correction 5); the doc citation is the integrator's to fix.
C-6 — test.yml runs integration-gpu serially, not -j 4; §3.2's flake is only reachable in
a parallel local run.
C-7 (new) — the D14 Fatal{PipeLegacyMemosDisabled} is push-only in both implementations, so
the review's third consequence of major 1 would have been a silent ignore, not an abort. Detail and
citations in §2.
C-8 (new) — v1's 918 integration-gpu entries was stale; the number is 912 in both the
pull and the push build (contract 878 + E's 34), and build-verify is 1740 of 2230.
7. Notes the integrator will want
- Measured CI cost of the new steps:
ctest -L uniton the verify runtime 14.3 s / 1489 entries; the two negative-control lanes ~1.8 s / 44 entries;DriverBenchStateToggle0.24 s. Serial-L integration-gpuis 251 s (pull) / 235 s (push) on this box, 912 entries. - The CSO control's numeric contract (unchanged, so package B can meet it deliberately): 8
toggle pairs = 16 draws in one frame; content-addressed arm
csom <= 4andcsom < csob; bit-63 armcsom == csob; both armscsob >= 16; the readback all-green and byte-identical across two consecutive toggle frames. The counters must be emitted throughPipeStats::AddCalls(CallClass::RenderStateCsoMints/Binds, …)— and now the arming probe reads the same two names, so an emitter that used a different channel would both fail the assertion and leave the entry skipped, which is the honest pair. MOBILEGL_PIPE_STATS_PERIOD=1is what makes the control readable: the summary window is "since the previous line".DriverBenchStateToggleis a "does this case still run" gate, not the measurement; D.4.4's numbers still come fromrun_driver_bench.sh {native,espryt,magma}.- §3.2's
-jflake is worth a follow-up of its own; the fix shape is "a log-reading case owns its lane", in three scenarios E does not own. - Do not run
gh workflow run test.ymlongateswithouttracker(D-7).
8. Unfinished
- D.2's "red before" log (D-1) — integrator action, after package D lands the knob.
- G3 / G4 not run here. This package builds no library source, so the 40-trace SSIM corpus and the verify divergence lane would be measuring the contract commit. Integrator's D.3.
- G6 / G10 / G11 unreachable here — A's and B's tests, and G11 needs two devices. (G6's test was exercised transiently by §3.1's simulation and is green there, but that is A's evidence, not E's.)
- The Android build of the CPU series is compile-unverified.
trace_benchmark.cppandtrace_replay_core.cppare shared with the Android trace app; only the desktop CLI was built and run.apk.ymlis where the NDK build first runs it. - The two device profiles are unverified by construction (D-6) and cannot be finished without the devices. No device lock was taken by this package; no on-device measurement (D.4.2, D.4.3, D.4.5) was attempted.
ctest -L benchmarkwas run only for the twoDriverBenchentries; the other five benchmark targets reportNot Runbecause onlyDriverBenchwas built inbuild-bench.