Commit Graph
157 Commits
Author SHA1 Message Date
swung0x48 cfe830cf44 [MG_Remote, MG_Test, MG_IntegrationTest, scripts] (P7): a spawned server reports SurfaceProgress while its apply thread runs a surface op, so the client's reply budget bounds silence and a cold bring-up past 20 s is waited for 2026-09-23 18:17:02 -04:00
swung0x48 a23ae93753 [MG_Remote, MG_Test, scripts] (P7): the latch comments say the check before every pop narrows the control-thread window to check-to-pop and the session ends at the next check 2026-09-23 17:45:57 -04:00
swung0x48 9eb798a60e [MG_Backend, MG_Test, MG_IntegrationTest, scripts] (P7): a private image placeholder is keyed by (shape, unit) and capped, and the depth-resolve identity is built by a tested helper 2026-09-23 17:45:57 -04:00
swung0x48 02db0e4d9d [scripts] (P7): spawn_lane_parity names the two ImageUnitPrivate knob entries by one tail each 2026-09-23 17:04:14 -04:00
swung0x48 a7848f0a03 [MG_Backend, MG_IntegrationTest, scripts] (P7): an invalid or empty image unit on the wire arm binds a null storage descriptor (VK_EXT_robustness2 nullDescriptor), else a placeholder private to its (binding, unit) 2026-09-23 17:04:13 -04:00
swung0x48 03bcf5e7fb [MG_Remote, MG_Test, scripts] (P7): DrainRing checks the session latch immediately before every pop, so a latch the control thread stores between two records stops the next one 2026-09-23 17:04:13 -04:00
swung0x48 431bda67dc [MG_Backend, MG_IntegrationTest] (P7): a real-probe negative control proves the depth-resolve measurement can see a broken render-pass arm on the host 2026-09-23 15:20:17 -04:00
swung0x48 e83581c3c4 [MG_Backend, MG_Test, MG_IntegrationTest, scripts] (P7): choose the multisample depth/stencil resolve arm by a device probe with a shader-arm control instead of the Qualcomm vendor id 2026-09-23 15:13:44 -04:00
swung0x48 23be55e477 [MG_Backend, MG_IntegrationTest, scripts] (P7): pin the Qualcomm depth/stencil resolve arm order on the split and spawn arms 2026-09-23 15:13:44 -04:00
swung0x48 efc899a1b0 [MG_Remote, MG_Test, scripts] (P7): bound the pre-auth cap and pause accepting when out of descriptors 2026-09-23 13:45:00 -04:00
swung0x48 bc62b17b0c [MG_Remote, scripts] (P7): refuse queued DataBinds on every pre-Accept exit and route DataBinds without a reap wait 2026-09-23 13:45:00 -04:00
swung0x48 5411180288 [MG_Remote, scripts] (P7): name every single-session first-frame outcome and pin its token-first order 2026-09-23 13:45:00 -04:00
swung0x48 04229e62d4 [MG_Remote, MG_Test, scripts] (P7): share the pre-auth queue between addresses and back off silent slot holders 2026-09-23 13:45:00 -04:00
swung0x48 6628674d72 [MG_Remote, scripts] (P7): refuse DataBinds queued on the session hand-off before it closes 2026-09-23 13:45:00 -04:00
swung0x48 3d7cc9592b [MG_Remote, MG_IntegrationTest, CI, scripts] (P7): add Ph fuzz arm 1 for malformed control frames 2026-09-23 13:45:00 -04:00
swung0x48 7bb1da73d4 [MG_Remote, MG_Test, scripts] (P7): authenticate TCP peers before fork with bounded pre-auth work and backoff 2026-09-23 13:44:38 -04:00
swung0x48 7aee3e2105 [ci] (P7): ph_latch_sites --table names each mechanics control by its gtest suite, not its file 2026-09-23 13:44:37 -04:00
swung0x48 8848ee6ccf [MG_Remote, MG_Test, ci] (P7): red-once controls for the latch's decline-and-close half, a control pump that declines after the latch, the pre-gate ahead of the applier's stamp, and a PH-5 raw-peer row that discriminates 2026-09-23 13:44:37 -04:00
swung0x48 ec3758d088 [MG_Remote, MG_Test, ci] (P7): one raw-peer row per latch site and the D11 bounds against a --serve supervisor, each followed by a rendering next session (PH-1 (4), fuzz arm 2) 2026-09-23 13:44:37 -04:00
swung0x48 d681d9b1bf [MG_Remote, MG_Test, ci] (P7): peer-byte faults latch the session child and decline the rest; inproc keeps Fatal (PH-1 (3)) 2026-09-23 13:44:37 -04:00
swung0x48 d49df3549f [MG_Backend, MG_State, scripts] (P7): retire the texture legacy-arm scope and tag the p7-magma remainder P13 2026-09-23 13:23:09 -04:00
swung0x48 e751b07baa [scripts] (P7): restore the executable bit the CI fix package dropped from junit_tally.py and stub_ctest.sh 2026-09-23 13:23:09 -04:00
swung0x48 877c531a0d [CI] (P7): tighten renamed CI titles 2026-09-23 13:23:09 -04:00
swung0x48 072ea1b832 [android-plugin, scripts] (P7): a passed APK replay whose device went offline before its logs were copied asks for the infrastructure retry 2026-09-23 13:23:09 -04:00
swung0x48 b13045918a [CI, scripts, tools] (P7): the pull control strips ctest -V's line prefix, retrace-split pins lavapipe, and the retrace summary reads role logs 2026-09-23 13:23:09 -04:00
swung0x48 f1ce655b42 [MG_IntegrationTest, scripts] (P7): the Tcp TextureUploadShape entry holds the mobilegl-tcp lock, and the lane tools refuse any supervisor entry that does not 2026-09-23 13:23:09 -04:00
swung0x48 d1549cba57 [scripts] (P7): the TCP lane supervisor starts headless like every other server the harness reaches 2026-09-23 13:23:09 -04:00
swung0x48 9fd768d493 [MG_Backend, MG_IntegrationTest] (P7): bound wire descriptor sets within long frames 2026-09-23 01:35:20 -04:00
swung0x48 1ab62ece4c [ci] (P7): the parity exception list names M2 round 2's fourth Reclaim case
- ADrawAfterTheEarlyReclaimFollowsTheNewStoreNotTheMemoizedHandle rides the same split/spawn
  fixture as the three gauge cases and the tcp arm does not carry it (magma-m2.md §9.3); the
  integration tree keys this list by exact tail, so the fourth name goes in beside the three
2026-09-22 22:56:43 -04:00
swung0x48 3b8bf9ec25 [scripts] (P7): the pull-library control refuses an empty grep -F pattern in EVIDENCE, and the stub ctest is executable again
- every line of EVIDENCE is a grep -F pattern and an empty line matches everything: a trailing
  newline or a blank line between the two sentences would turn hole 2 into "any red will do".
  The smoke's "red without the transport-resolution message" case catches that (22/23), but
  only when somebody runs it; a `case` after the assignment now refuses a blank line or a
  leading/trailing newline with ::error:: and rc 1, before the selection is counted or the
  library is swapped. The red-check's perturbation line is untouched; smoke 23/23
- scripts/ci/testdata/stub_ctest.sh went 100755 -> 100644 in the round-2 commit that added
  its retrace-evidence-nolog mode (a Windows-mount artefact); restored with
  `git update-index --chmod=+x`. The smoke copies it and chmods the copy, so nothing ran
  differently
2026-09-22 22:03:23 -04:00
swung0x48 bd849b2821 [tools] (P7): the audit's block walk is fail-open only for the disaggregated guard, and an indented #else stops it
- stepping over `#endif` accepted a log that is compiled out: `#if 0` / `MGLOG_W(...)` /
  `#endif` / `Count(...)` read as logged, and so did a log under `#ifdef
  MOBILEGL_VERBOSE_DECLINES` - a Count that counts every time and logs in no shipped build
- the walk now counts the `#endif`s it crosses; a same-indent log met with one outstanding
  counts only if every opener enclosing it, reached by continuing upward, is the whole-line
  `#if MOBILEGL_BUILD_DISAGGREGATED` (`&& X` is not it). `#if`/`#ifdef`/`#ifndef` with no
  `#endif` outstanding is the Count's own guard and is still stepped over, so the column-0
  `#if/#endif` fixture stays green; the comment says the walk is fail-open for that one
  guard and nothing else
- `#else`/`#elif` stopped the walk only at column 0, as a line of lesser indentation; one at
  the Count's own indentation walked straight through to the log above it. PP_STOP now
  returns False at any indentation, before the indent test
- two red fixtures, both green on the round-2 audit: "log only under a #if 0 above the
  Count" and "log only on the other side of an INDENTED #else at the Count's indentation";
  16/16, the tree stays 53 / 53 / 0
2026-09-22 22:03:23 -04:00
swung0x48 8c8fc31952 [MG_Remote, MG_Test, ci] (P7): the token compare runs a fixed 64-byte width, an ignored window ask is logged once, a nonce that could not be minted is refused by name, and a garbage first frame while busy is MalformedHello rather than Busy
- AuthToken.h: ConstantTimeTokenMatch loops kAuthTokenCompareBytes (64) iterations with both operands read as zero past their ends - its trip count no longer tells a peer the configured token's length; a token longer than 64 is still compared to its last byte (SocketTransportTest pins the 70-byte case)
- ServerSession.cpp: an ask in Hello.linkTerms above the granted terms logs one MGLOG_W naming both sides ("the ask is ignored and the session is server-sized"); the production client asks for nothing, so a session that was never mis-configured never logs it; SessionHandshakeTest's 64 GiB case requires the line (red before: absent)
- ServerSession.cpp: a MintNonce failure sends Refuse{LinkTerms} "stream data plane unavailable: the server could not mint a data nonce" before returning the fault it is (still exit 67, still counted) instead of a bare close
- ServerMain.cpp: a first frame with the wrong magic or over 1 MiB while a session is live is Refuse{MalformedHello} "first frame is not a control frame", drained before the close so the refusal is not RST away; Busy stays the answer for a well-formed frame that is not a DataBind
- tcp_supervisor_smoke.py: garbage_first_frame_while_busy (magic XXXX on a live session -> code 8; red before: code 7)
- fatal census unchanged: 79 abort sites, 3 refusal words (the new refusals go through the enum, not a literal)
2026-09-22 21:54:46 -04:00
swung0x48 c69d8dfdc8 [MG_Remote, MG_Test, ci] (P7): sha256(protocol.fbs) is pinned to MOBILEGL_PROTOCOL_CONTROL_REVISION, so a control-schema edit without a bump is red in the unit lane and in flatc-check instead of a silently absent field
- the revision is a hand-bumped integer mixed into wireFingerprint and nothing tied it to protocol.fbs's content; scripts/ci/protocol_revision_pin.py holds {revision -> sha256(protocol.fbs)} in protocol_revision_pins.json and refuses a schema whose digest is not the current revision's, or a revision with no row
- registered as ProtocolSchema.RevisionPinsDigest (label unit, MG_Test/Wire/CMakeLists.txt, --self-test proves both perturbations red before it says green) and as a step of CI's flatc-check job, the one that regenerates the header on every schema edit
- --write records a bump's row and refuses to re-pin an existing revision to a different digest, which is what a schema edit without a bump looks like
- mg_protocol_base.h says where the pin lives beside the revision it pins
- red-once: protocol.fbs touched with one trailing comment, revision left at 1 -> "protocol.fbs has sha256 a7b5c7fb... but MOBILEGL_PROTOCOL_CONTROL_REVISION is still 1, which is pinned to 7fc859f7..." rc=1; restored, green
2026-09-22 21:54:46 -04:00
swung0x48 0293aebb17 [MG_Remote, ci] (P7): a bound session closes its data-connection source, so a later DataBind is refused by name instead of queued into a child that stopped reading, and the single-session listener closes with it
- ServerMain.cpp: RunSession takes the descriptor its data-connection source reads from (the child's hand-off end under --serve, the listener itself without it) and closes it the moment Accept returns; the source object goes with it
- the supervisor's hand-off send is MSG_DONTWAIT (FdPassing::SendFd dontWait), so a peer that stopped reading answers at once; "peer gone" on a datagram pair (ECONNREFUSED, ENOTCONN) is an answer the caller names, not a logged fault
- before: every DataBind after the bind sat in the child's receive queue with no reply, its TCP connection held open until the session ended, and past the queue limit (net.unix.max_dgram_qlen 10 on the phone; ~288 datagrams of sender buffer on this host) the supervisor blocked in sendmsg for the rest of the session - no accepts, no Busy, no reaping
- before, without --serve: the listener stayed open after the data connection bound, so a second client or a retry completed a TCP handshake nobody would accept and waited out its 20 s connect budget instead of the ECONNREFUSED it got before PH-7 (4)
- tcp_supervisor_smoke.py: data_bind_after_bound (12 extra DataBinds on a bound session each get Refuse{Authentication} "data connection could not be handed to the live session", and a fresh control connection is still Busy) and single_session_listener (a connect after `ready` is ECONNREFUSED); connect_control retries ECONNREFUSED at startup for pair() and held_session() alike
- red-once at da313010: smoke TimeoutError on the first extra's receive; probe with qlen+2 fire-and-forget DataBinds: 288 queued silently, then the supervisor stopped accepting (fresh control: connect timed out) while still alive; single-session connect after ready succeeded
2026-09-22 21:54:46 -04:00
swung0x48 9328bdc735 [MG_Backend, MG_Util, MG_Test, MG_IntegrationTest, scripts] (P7): integration-magma-split and -spawn carry MagmaWireReclaimScenario, which reads the server's wbuf[] gauges and reds on a wire arm that keeps orphaned buffer stores until the frame ends
Rule J's red-once for M2. The server role's VkBufferManager publishes four PipeStats gauges
(push builds only, so the pull image is untouched): wire buffer records alive, and the run
maxima of live wire VkBuffers and of parked bytes, plus the watermark's forced-sync count -
maxima because the defect lived inside one frame and a swap-time sample reads after the frame
boundary's own sweep. Two cases, each inside a single frame: 1024 undrawn respecifies of one
4 KiB buffer (live peak <= 4 x wire buffers), and 48 respecify-and-draw rounds of a 1 MiB store
under the lane's MOBILEGL_IPC_WIRE_DEFERRED_MB=8 (parked peak <= budget + one store, every strip
its own colour). Red at base (ec46a550's defer path, counted): 1025 vs 4 live, 49,287,168 vs
9,437,184 bytes and 49 vs 11 live, on both arms; green after: 1 live, 9,437,184 bytes / 9 live
with 5 forced syncs. The knob's negative control (=0) reds the second case with the same
49,287,168 bytes. Inproc and spawn only: the tcp server is the lane-wide fixture supervisor,
whose environment and log the entry cannot reach - named in spawn_lane_parity.py as
MAGMA_NOT_ON_TCP (the ID-P7-14 shape), and PipeStatsTest pins the four short names.
2026-09-22 21:46:08 -04:00
swung0x48 46bda06226 [scripts] (P7): the pull-library control accepts the no-client-log sentence a pull build has produced since the per-role log rename
- retrace_pull_library_control.sh required run_trace_case.cmake's "never reported resolving
  it", the marker-search sentence. Since P6's one-log-per-role rename a pull library never
  reaches that search: it has one role and writes MOBILEGL_LOG_FILE_PATH unchanged
  (output/mobilegl.log, Log.h's pull arm of RoleLogPath), the runner reads
  output/mobilegl.client.log and stops one check earlier with "the run wrote no <client log>,
  so there is no evidence the transport ever resolved" - so the control's hole-2 check
  refused its own red and the step exited 1 on every pull-library run
- measured on this tree with the real ctest, build-linux's pull library over build-split's
  frozen split library, SPLIT_TRANSPORT=inproc: control rc 1, "::error::the split retrace
  went red (ctest exit 8) ... never says the library did not resolve the transport", the
  runner's fatal at the no-client-log check. With this change the same run passes for its
  own reason on both inproc and spawn
- EVIDENCE carries both sentences as grep -F's newline-separated patterns, so the evidence
  line the red-check perturbs is unchanged; both are the transport-identity assertion
  refusing the same library for the same reason, and neither is a loader failure, a missing
  fixture, a timeout or an SSIM drop
- stub_ctest.sh gains retrace-evidence-nolog, the no-client-log fatal CMake-wrapped across
  lines the way the real one arrives; control_smoke_test.sh expects it to PASS (23/23); the
  red-check still reds "red without the transport-resolution message"
2026-09-22 21:28:02 -04:00
swung0x48 b0d4d730ba [tools] (P7): the audit's block walk stops at a same-indent exit and steps over a column-0 #if
- a same-indent `case`/`default:`/`break;`/`return`/`continue;`/`goto`/`throw` line between a
  log and a bare Count ends the walk: control cannot flow from that log to the Count, so it
  is not the Count's log. A `case 1: MGLOG_W; break; case 2: Count` switch with its labels at
  statement indentation, and a log above a `return` with the Count under a same-indent label,
  both read as logged before
- `#if`/`#ifdef`/`#ifndef`/`#endif` lines are passed over: a log and its Count that straddle a
  `#if MOBILEGL_BUILD_DISAGGREGATED` are one block on both sides of the preprocessor, and the
  column-0 line ended the walk for no defect. `#else`/`#elif` still end it - a log on the other
  side of one is in a different build, not this one
- four fixtures: same-indent return (red), same-indent switch (red), log across a #else (red,
  and red on the previous audit too - it pins that #else still stops), Count under its log
  across #if/#endif (green; a false red before). 14/14 fixtures; the tree stays 53 / 53 / 0
2026-09-22 21:28:02 -04:00
swung0x48 576fc09a31 [tools] (P7): the audit's strip reads a prefixed character literal as a character, not as a digit separator
- L'"', u'"', U'"' and u8'"': the `'` after an identifier character was taken for a C++14
  digit separator, the `"` inside it opened a phantom string, and the rest of the line was
  blanked - a site on that line vanished and its row read as NO SITE (fail-closed: a false red)
- CHAR_PREFIX accepts a u8/u/U/L prefix before `'` the way RAW_PREFIX does before `"`, with
  a non-identifier character (or the start of the text) in front of it, so a real separator
  (0xAB'CD, 1'000) is untouched
- self-test fixture with L'"' and u8'"' ahead of two AT sites on their own lines: rc 0; it
  was rc 1 on the previous audit. The tree has no prefixed character literal today (53 / 53 / 0)
2026-09-22 21:28:01 -04:00
swung0x48 9d5f5012c7 [tools] (P7): a site's log is a statement that begins with MGLOG_W/E, not a line that mentions one
- the wire declines audit's LOGGED pattern was unanchored, so a guarded one-liner at the
  Count's indentation (`if (g) MGLOG_W("x");`, `g ? MGLOG_W("x") : (void)0;`) counted as
  the site's own log and the site read as logged - a decline counted every time but logged
  only sometimes, which is the unlogged site the check exists to refuse
- anchored to the statement start; the block walk matches the line, not searches it
- self-test fixture "guarded one-liner log at the Count's indentation" (both shapes) reds
  with the NO_LOG sentence; it was green on the previous audit. The tree stays 53 / 53 / 0
2026-09-22 21:28:01 -04:00
swung0x48 ce83651349 [MG_Remote, MG_Test, ci] (P7): a Hello asking for 64 GiB windows is welcomed with the server's own terms and its session child never reaches 64 GiB, pinned in process and on the TCP supervisor 2026-09-22 21:00:57 -04:00
swung0x48 20ab14daf8 [MG_Remote, MG_Test, ci] (P7): a TCP session's data connection is bound to its authenticated control connection by a 128-bit Welcome.dataNonce instead of by arrival order, so a reordered or stale data connection is refused by name and the wire fingerprint moves with the control schema 2026-09-22 21:00:57 -04:00
swung0x48 8fa1821ab2 [MG_Remote, MG_Test, ci] (P7): one constant-time token comparison serves both server policy sites, a configured token shorter than 16 bytes refuses the listen by name, and CI builds flatc so the TCP supervisor smoke runs and must pass 2026-09-22 21:00:57 -04:00
swung0x48 266d6a32f8 [tools] (P7): the wire declines audit carries a self-test whose fixtures must red, and the CI step runs it before the tree audit
Fable review of the B3 rework, should-fix: the audit had no negative
control, so a green run could not say it would have been red. It now takes
--self-test, which writes each inline fixture as a one-file renderer tree in
a temp dir, runs the audit on it and checks both the rc and the line the
audit must print (so a red is red for the fixture's reason):

  comment-only site (//)                -> rc 1, "has NO SITE"
  comment-only site (/* */)             -> rc 1, "has NO SITE"
  string-literal site                   -> rc 1, "has NO SITE"
  other-branch log                      -> rc 1, "with no MGLOG_W/E in its own block"
  nested-branch log                     -> rc 1, same
  log only in a /* */ comment above     -> rc 1, same
  nearest log is MGLOG_D                -> rc 1, same
  good sites (AT form, bare Count under
    its own MGLOG_E_ONCE, def row with a
    trailing comment)                   -> rc 0, "0 unlogged, 0 unknown"

8/8, rc 0. Mutants: with the strip disabled 5 of 8 fail (the four
comment/string reds go green and the good fixture's commented row is
lost); with the old 8-line window in place of the block walk 2 of 8 fail
(other-branch, nested-branch). Against the audit as it stood at aab01275,
six of the seven red fixtures passed and the good one failed.

.github/workflows/test.yml: the "Wire declines audit (B3)" step runs
--self-test and then the tree audit, the way the next step runs
trace_cases.py --self-test-transport-matrices before it computes matrices.
2026-09-22 20:49:45 -04:00
swung0x48 78269b2677 [tools] (P7): a bare decline count is logged only by a warning-or-error line in its own block, and a def row with a trailing comment is still a row
Fable review of the B3 rework, should-fix: the 8-lines-above MGLOG_W/E window
was branch-blind - a Count() in `if (x == 2) { ... }` whose only log sat in a
preceding `if (x == 1) { ... }` passed, as did a log in a nested branch just
above. All 12 bare sites in the tree are under their own line today, so this
was a gate hole, not a present defect.

has_own_log() walks upwards from the Count line (still capped at 8 lines):
blank and deeper-indented lines (a log's continuation lines, a nested block)
are passed over, only a line at the Count's own indentation can be its log,
and the first line indented less than the Count - the block's opening, a
sibling's `} else {` - ends the walk.

WireDeclines.def is now read through the same comment/string strip, and ROW
tolerates spaces inside the parentheses: `MGL_WIRE_DECLINE(Name) // note`
used to fail `\)\s*$`, dropping the row, and its real site was then
reported as naming no row.

Tree: 53 rows, 53 with sites, 53 sites, 0 unlogged, rc 0 (unchanged).
Fixtures the previous commit passed and this one reds: other-branch log,
nested-branch log (rc 0 -> 1); a def row with a trailing comment plus its
site (rc 1 -> 0).
2026-09-22 20:49:45 -04:00
swung0x48 88599fc6f6 [tools] (P7): the wire declines audit matches sites and logs on code alone, so a commented-out or quoted site is no site
Fable review of the B3 rework, must-fix: a row was "sited" by any line the
AT_SITE / COUNT_SITE regex matched, including a // comment, a /* */ block or
a string literal - `// MGL_WIRE_DECLINE_AT(GhostRow, "...");` satisfied the
audit for a row nothing counts, and an MGLOG_W inside a comment above a bare
Count() satisfied the log rule.

wire_declines_audit.py now blanks //...$ (with backslash-newline
continuation), /* ... */, "..." and '...' (raw strings R"d(...)d" and
C++14 digit separators handled) out of each source before any match. Every
character but the newline becomes a space, so the text keeps its length and
line count and each report still cites the real line.

Tree: 53 rows, 53 with sites, 53 sites, 0 unlogged, rc 0 (unchanged).
Fixtures that the previous audit passed and this one reds (rc 1): a
comment-only site (//), a comment-only site (/* */), a string-literal site,
a log only in a /* */ comment above a bare Count. The branch-blind window
and the .def trailing-comment row are the next commit.
2026-09-22 20:49:45 -04:00
swung0x48 4db17d58c6 [MG_Backend, MG_IntegrationTest, scripts] (P7): a declined multisample depth/stencil shape is decided once before any aspect runs, so an erroring blit writes nothing, and the shader resolve arm gets a flipped knob twin
- BlitWireFramebuffers runs colour first. A scaled COLOR|DEPTH blit out of a multisample framebuffer scaled and wrote its colour and then recorded INVALID_OPERATION on its depth, and an X-mirrored one mirrored its colour and left its depth alone - partial effects GL 18.3.1 does not allow. The shape decline (scale, X mirror, cross-format Y mirror) moves into DeclineWireDepthStencilResolveShape, which BlitWireFramebuffers asks for every depth/stencil aspect that would take the multisample resolve arm before any aspect runs; ResolveWireDepthStencil asks it too for any other caller. Default read/draw framebuffers are left to the lambda (a default read is never multisampled; a default draw behind one is the region Fatal, and resolving it early would move its write index).
- The X decline and the cross-format Y decline get their own MGLOG_E_ONCE sites; one site used to cover both, so after the first X decline a cross-format Y decline logged nothing.
- An empty rectangle on one side only (64x48 onto 0x48) is a size mismatch and now takes the scale decline (INVALID_OPERATION) instead of returning silently; empty on both sides stays a silent no-op.
- DirectVulkan.{Split,Spawn}.MsFlip1. forces MGITEST_MAGMA_FORCE_SHADER_DEPTH_RESOLVE=1, so the shader arm min-corner rectangle under a flip runs on this host; split+spawn only and named in MAGMA_SERVER_ENV_KNOB_NO_TCP.
- spawn_lane_parity.py: every server-env-knob tail must match exactly one split key, so a dead or over-broad tail fails the gate instead of riding silently.
- The flipped-resolve case gains a COLOR|DEPTH scale leg (error, colour untouched, depth untouched) and an empty-destination leg (error, depth untouched).
- Red-once, each on split + spawn (+ tcp MsFlip.) and restored: pre-pass disabled -> all five MsFlip/MsFlip1 entries fail "the declined COLOR|DEPTH scale must not have written its colour either" (read {255,0,0,255}, want {0,0,255,255}); round-1 silent empty-side return -> all five fail the empty-destination leg (error 0, want 1282); shader arm handed sx0/sy0 instead of the min corner -> MsFlip1 fails on both arms ("768 of 768 depth values differ from 0.75", "928 of 3072 stencil values are wrong; first at (20, 4): got 255, want 99") while MsFlip. stays green; a dead ".MsFlip2." tail -> parity rc 1 "matches 0 split entrie(s)".
- The split once-sites have no lane red-once: the cross-format Y decline needs a device whose renderbuffer and texture D24S8 map to different VkFormats, which lavapipe is not.
2026-09-22 20:49:45 -04:00
swung0x48 75a64ce0da [tools, docs] (P7): the parity script keeps one server-side-knob list after the B3 rework merge, and magma-b3.md names it
The B3 rework's parity hunk and B2's round-1 hunk described the same asymmetry
under two names; the merge kept B2's compare_arms(no_tcp=) and added .StaleSerial.
to MAGMA_SERVER_ENV_KNOB_NO_TCP. One line of the package tree's other mechanism
(`not_on_arm = not_on_arm or {}`) survived outside the conflict hunks and would
have been a NameError on the first run; it goes, and the note's two mentions of
MAGMA_NOT_OVER_TCP now name the list that exists.
2026-09-22 20:25:48 -04:00
swung0x48 b0c6af3168 [MG_IntegrationTest, tools] (P7): the stale-serial red-once is registered on split and spawn only, and the parity gate names it with the other server-side knobs
MGITEST_MAGMA_FORCE_STALE_BUFFER_SERIAL is read by the server. The tcp
arm's server is the lane fixture (scripts/ci/tcp_server_fixture.py),
started once from its own environment, so an entry-level ENVIRONMENT never
reaches it: DirectVulkan.Tcp.StaleSerial.* ran the unforced case under a
name that claimed the knob and could never red (review ID-P7-34, item 1).

The entry is now registered only when the arm is Split or Spawn, and
spawn_lane_parity.py grows a second named asymmetry beside
MAGMA_INPROC_ONLY: MAGMA_NOT_OVER_TCP, key prefixes the reference arm has
and the tcp arm does not by name. It comes off the reference for the tcp
arm alone, so the same entry missing from spawn is still an error. B2 adds
its own knob entries to the same tuple in its tree.

integration-magma-tcp 71 -> 70 entries (68 cases + the two fixture
entries); split 90, spawn 69 unchanged. spawn_lane_parity.py build-split
rc 0; tcp_lane_tools_test.py 6/6.

Integrator merge onto pipe: B2's round-1 mechanism (`mglItestServerEnvKnobArm` in
CMake, `compare_arms(no_tcp=)` in the parity script) already covers this shape, so
`.StaleSerial.` joins MAGMA_SERVER_ENV_KNOB_NO_TCP instead of the separate
MAGMA_NOT_OVER_TCP the package tree introduced.
2026-09-22 20:25:11 -04:00
swung0x48 b8d10d0730 [MG_Backend, tools] (P7): every WireDeclines.def row has a site and every site a warning-or-error line, and a tree-only audit fails the job when one does not
The B3 review (ID-P7-34) counted 12 of the 52 rows with no site at all -
TexViewFormat, TexNoApplierRecord, TexRecordDeadOrStale and the nine Shape*
rows were declared and never counted - and ten sites that counted with no (MGLOG_D included)
line, so "a name, a tally and a decline line" did not describe the tree.

- SyncWireTextureShape: all nine Shape* exits now count; the ViewOf exit
  and the preserve-flush exit were bare `return false` and are now
  MGL_WIRE_DECLINE_AT; the image-flags exit logged only MGLOG_D, which a
  Release build compiles away, and is promoted likewise.
- The preserve-copy exit was the one Shape exit with no row: appended as
  ShapePreserveCopyFailed (rows are append-only), 53 rows.
- SyncTextureResourceByHandle / UploadPendingWireLevels: the count-only
  sites without a log of their own are promoted to MGL_WIRE_DECLINE_AT;
  the ones already under a W/E _ONCE line keep that line and gain the count.
- scripts/ci/wire_declines_audit.py: fails on a row with no site, a site
  naming no row, or a bare Count() with no MGLOG_W/E within 8 lines above
  it. WireDeclineTally.h (the macro's definition) is not a site. Wired into
  the job that runs the fatal census.

Audit before: 52 rows, 40 with sites, 10 unlogged under the W/E rule (rc 1). After: 53 rows,
53 with sites, 0 unlogged (rc 0). Forced red (ShapeNoVkFormat made true for
1x1 textures, reverted): Split.Fm.F1WireScenario.VertexIdSampler... fails on
pixels with ShapeNoVkFormat=2 / TexShapeSync=2 in the shutdown tally.
2026-09-22 20:24:00 -04:00
swung0x48 cc3c18c578 [scripts, docs] (P7): magma-b2.md counts the baseline as 73 + 11 + 2 + 2, carries the review round's §12 lines and gates, and the ratchet baseline names the tree that measured 173
ID-P7-31 review, note 3 and nits.

  * §0's preamble: the +4 over package B's 84/63/65 is not "package A landing after
    B" - A landed BEFORE B and is +2 (magma-a.md:151-153); package C is the other +2
    (magma-c.md:59-61). 73 + 11 (B) + 2 (A) + 2 (C) = 88/67/69.
  * §2.3 / §2.5: MsResolve1 is split+spawn only; the day-of +3 on tcp is marked as
    superseded.
  * §2.7 (the server-side knob has no tcp arm, measured) and §2.8 (flip mirrored,
    scale declined, X / cross-format mirror declined; three red-once lines).
  * §6: the lines for CONTRACT-P7 §12 - the scaled second leg is unclipped
    (VUID-vkCmdBlitImage-dstOffset-00248/00249, shared with the monolith);
    MagmaWireFatal("multisample-resolve-region") for a source rect outside the read
    buffer, where GL promises undefined values rather than an error; the 1->N
    identical-rect decline declines a legal shape (18.3.1 sample replication) because
    the monolith's own observable is a VU violation; the tcp lane cannot carry a
    server-side knob; X and cross-format Y mirrors of a depth/stencil resolve decline.
  * §7: the review round's gates - magma 94/73/70, full-split 525, unit 2423, parity
    RC 0 naming the five MAGMA_SERVER_ENV_KNOB_NO_TCP entries, census 79, ratchet 173,
    G1 .text 0xa52203 with 0/0 symbol drift, @P7 19 comment lines.
  * link_ratchet_baseline.txt: `base commit` points at 6af422b3, the tree that
    measured 173, not 4bee1313.

The "@P7 = 24 lines" nit needed no edit: the note already reads 19 at 6af422b3, which
is what the tree measures.
2026-09-22 20:05:28 -04:00