SessionLog-2026-09-04.md #1

  • //
  • test-install_sdp/
  • dev/
  • ai_dev_support/
  • SessionLog-2026-09-04.md
  • Markdown
  • View
  • Commits
  • Open Download .zip Download (19 KB)

Session Log -- 2026-09-04

Summary

Picked up from yesterday's first real Streams-native release rehearsal. Found and fixed several real bugs while exercising the process further: a README.md link-rendering regression (root-caused to a missed Copy Up), a stale/wrong "Directory Structure Changes" section in sdp_upgrade.sh's embedded docs, and -- the big one -- an unescaped quote that had been silently truncating upgrade.sh -man's entire ~580 lines of documentation down to an 8-line stub for as long as the SBD feature text existed. Wrote up the "Merge Down, Copy Up" mantra as an explicit process rule after the second regression traced to the same root cause. Ran the full SDP+P4D upgrade exercise for real on a BSW Gen6 lab, found and fixed a real, long-standing naive-lexicographic-version-comparison bug in both upgrade.sh and sdp_upgrade.sh (confirmed it also explains a known, years-old internal-P4D-build pain point the user described). Filled in the HMS URL. Adopted a new SDP Version-file format (YYYY.N.P[.SUFFIX]) on the r26.1.0.BETA rehearsal stream. Set up a new Jenkins job and a new standing Gen7 QA lab for //p4-sdp/main (in progress/partially blocked, see below).

README.md link regression, root cause, and the "Merge Down, Copy Up" mantra

User reported the Swarm rendering fix from 2026-09-03 (site-relative /view/ links) had "come back" broken on both r26.1.0.BETA and main. Root cause: main never actually received that fix -- it was made in dev (and manually patched into r26.1.0.BETA) but never Copied Up into main; the only main-side README.md edit since then (change 33463) was an unrelated platform-support text fix. When r26.1.0.BETA was later refreshed from main (to catch it up on unrelated changes, change 33471), that Copy-Up-from-main step faithfully propagated main's stale, never-fixed content right over BETA's previously-good copy -- a real regression caught by the user re-testing a link they'd already confirmed fixed. Fixed via Copy Up from dev into main (33478) and re-synced into BETA (33480).

This is the second time this exact class of bug has bitten this cycle (the first was doc/ReleaseNotes.adoc's Jobs-Fixed list, found and fixed 2026-09-03/04 morning). Wrote up an explicit "Merge Down, Copy Up" mantra -- always Merge Down before a Copy Up, in either direction, with rare exceptions for deliberate cherry-picking -- as a new callout in doc/ReleaseProcessOverview.md (change 33482/33483) and as a feedback memory (feedback_merge_down_before_copy_up.md).

sdp_upgrade.sh EDITME fix (change 33485/33487)

The "Directory Structure Changes" section described a not-yet-implemented /opt/perforce/ p4-sdp OS-package migration (SDP-1158, deferred to 2026.2, 0% implemented) as if it were current 2026.1 behavior. Replaced with an accurate description of the two structures that actually exist today (legacy/depot-mount, and the install_sdp.sh-created /opt/perforce/helix-sdp structure since 2024.2). Also removed an orphaned EDITME - END marker and filled in a blank FILES AND DIRECTORIES table entry.

The upgrade.sh -man truncation bug (change 33492/33493/33494-33496)

While fixing an unrelated wording nit (user asked to drop "at least" from "unconditionally raises 'security' to at least 4" -> "to 4", to avoid drawing attention to security levels above 4 which SDP doesn't support), regenerating doc/gen/upgrade.sh.man.txt turned up something serious: the file was suspiciously short (8 lines vs. 34-676 for every other script). Root cause: an unescaped double-quote inside the -opt-out-of-security-update help text ('p4d -r <P4ROOT> "-cset security=<value>"') broke bash's parsing of the entire multi-hundred-line DESCRIPTION+OPTIONS msg() call in the -man handler -- confirmed via bash -x showing the parser choking right at the broken quote, producing a bash runtime error that gen_script_man_pages.sh silently swallows (2>/dev/null, only checks the output file is non-empty). Net effect: upgrade.sh -man had been producing almost no real content since the SBD text was added, and since SDP_Guide.Unix.html includes that generated man page via include::, the customer-facing Developer/SDP Guide was silently missing nearly all of upgrade.sh's documented content, including the -Os/ -opt-out-of-security-update section itself.

Fixed the quote escaping; verified upgrade.sh -man now produces its full ~580 lines. Systematically checked all 15 other scripts in gen_script_man_pages.sh's list (both by actually running each with the same minimal environment the generator uses, capturing stderr instead of discarding it, and via a textual pattern search) -- confirmed this was an isolated incident, nothing else affected. Also found and deleted an orphaned doc/gen/get_helix_binaries.sh.man.txt (leftover from before the get_p4_binaries.sh rename; dev only, main never had it).

Filed SDP-1387 (deferred, not urgent, per the user): make gen_script_man_pages.sh flag non-empty stderr from a script's -man/-h invocation as an error, instead of silently discarding it -- this exact check would have caught the bug immediately, since the bash runtime error was going to stderr the whole time.

Real Gen6 upgrade exercise, twice, and the version-comparison bug (change 33502/33503)

Wrote a new skill, bsw-gen6-lab-create (//BattleSchool/main/ai/skills/), documenting how to spin up a BSW Gen6 lab via genlab.sh, including a first-run lab 0 idiosyncrasy (run it twice; a topology-role misconfiguration self-corrected on a third attempt on the second lab, cause not fully understood, not pursued further tonight) and a real -u Usage-tag bug in genlab.sh itself (UserDefinedResourceUsageTag vs. UserDefinedResourceTag mismatch -- fixed in //BattleSchool/main, change 2764053, merged down cleanly into //BattleSchool/ Gen7, change 2764055).

Ran the full outer-to-inner SDP-then-P4D upgrade exercise for real on lab bsw-sdp-upgrade-test (SDP 2023.2->2026.1, P4D 2023.1->2026.1). Hit the new SDP-1350 Secure By Default guard for real (every host at security=0, the lab's intentional low-friction config) -- used -Os on non-master hosts and -Os -opt-out-of-security-update together on the commit server (found that -opt-out-of-security-update is commit-server-only and doesn't bypass the abort by itself, needing -Os alongside it). All verification passed: p4 upgrades (60/60 steps completed after allowing ~1 minute settling time), p4 pull -ljv before/after, p4 servers -J full-topology checks, security configurable correctly restored to 0.

User then asked to make the SDP Version-file format decision real (2026.1.0.BETA instead of 2026.1) and asked what else besides Release Notes/generating tools might depend on the exact format. Investigation found a real, confirmed break: sdp_upgrade.sh's downgrade- detection logic does a naive lexicographic string comparison, and a longer/differently- shaped version string (more dot-components) sorts as less than a shorter one sharing the same prefix -- would misclassify the exact 2026.1 -> 2026.1.0.BETA transition as a downgrade. Real customers are safe (the actual prior release, 2025.2, differs in the year digit early enough to save the old comparison by luck), but our own rehearsal/testing environments already stamped 2026.1 are not. The user then revealed this is the same long-standing bug class behind a real, years-old pain point: Perforce's internal-only P4D builds use a deliberately different version scheme (e.g. 2025.1.PREP-TEST_ONLY) to make it obvious you're not on an official release, and upgrade.sh's own downgrade check has the identical naive-comparison problem with those strings.

Fixed both scripts with a new, numeric-aware compare_versions() / _leading_numeric_ version_core() function pair (duplicated identically in each file -- they don't share a library) that separates a trailing numeric changelist/build number from the "core" release number, takes only the leading numeric run of the core (silently ignoring any non-numeric internal/pre-release suffix), zero-pads to a fixed width, and compares numerically rather than lexicographically -- fixing both the suffix-insertion bug and a related digit-width bug (9 vs 10-style misordering) in one pass. Verified against 12 hand-built scenarios (including the real 2025.2->2026.1.0 GA transition, same-version equality despite differing suffix/CL-embedding shape, and internal-build-vs-internal-build ordering both directions) before touching the real scripts. Propagated dev->main->r26.1.0.BETA, repackaged and republished main's live tarball, and re-verified the entire upgrade exercise end-to-end a second time on a brand-new lab (bsw-sdp-upgrade-test2) with all fixes in place -- clean pass, identical to the first run.

Then made the Version-format change for real on r26.1.0.BETA (change 33519): Rev. SDP/ MultiArch/2026.1/33441 (...) -> Rev. SDP/MultiArch/2026.1.0.BETA/33441 (...). Real GA on 2026-09-08 will naturally get 2026.1.0 (no suffix) from the normal Step 15 tooling; no code changes needed for that, this was purely a data/rehearsal decision. Did not touch main's or dev's current Version file.

HMS URL filled in (change 33507/33508)

User supplied the one URL needed for both README.md and doc/SDP_Legacy_Upgrades.Unix.adoc's EDITME-UpdateThisURL placeholders: https://swarm.workshop.perforce.com/projects/ perforce_software-hms (the P4 Code Review project home page for HMS -- still pointing at HMS's own Classic depot home today, but will be silently retargeted, no SDP-side update needed, whenever HMS moves its own "main branch" to a //p4-hms/main stream).

Release Notes: called out the new -Os/-opt-out-of-security-update options (33489-33491)

Expanded the SBD "What's New" bullet to explicitly describe -Os and -opt-out-of-security- update, when each is needed, and the commit-server-only restriction -- prompted directly by hitting this for real during the Gen6 upgrade exercise above.

Two disposable EC2 test VMs from 2026-09-02 terminated

i-0dac4107629a1c421 (disposable-test-u24-1) and i-0160e0ab72d868a67 (disposable-test-r9-1), both in us-east-2, terminated per the user's request.

New Jenkins job for //p4-sdp/main, blocked by a pre-existing host issue

Created p4-sdp-build_main (cloned virtual stream //p4-sdp/build_main off //p4-sdp/main, cloned job config from p4-sdp-build_dev, reloaded Jenkins) per the sdp-jenkins-build-check skill's documented procedure. Every trigger attempt (4 total, including one after a full host reboot at the user's request) hit a rootless-podman/systemd container crash -- three different failure signatures across attempts (container state improper, OCI runtime error: crun: read pipe failed), with Failed to set RLIMIT_CORE: Operation not permitted and failed to write to /proc/self/oom_score_adj: Permission denied present in every crash log. The existing p4-sdp-build_dev job's container also crashed once (exit 137) during this, real evidence the RAM-contention risk flagged before creating the job was legitimate. The skill's documented "remove bad images, let them rebuild" fix did not reliably resolve it (matching the skill's own caveat that this fix is provisional). User manually retriggered (build #4, no changes) -- failed again, same signature, ruling out simple flakiness/timing. A fork then researched this further: found the exact same crash class already happened 2026-08-24/25 (a multi-day investigation at the time, exhaustively eliminated parallel-sync settings, stream-mode vs view-mode, virtual-stream remapping, checkout size, and a host package regression -- never cleanly attributed to one cause, eventually resolved via a Dockerfile fix plus Robert's own podman updates and a full container-store wipe). Confirmed no package drift since then, cgroup delegation (Delegate=) and loginctl linger for jenkins both still correctly in place, disk/inodes fine, podman info clean, and main's image genuinely builds successfully (ruling out the historical "silently falls through to a stale cached image" bug). Per instruction, did a full container/image wipe (all containers and images, including the base image) -- got past the previous crash signature entirely on the rebuild, but the container now dies within ~2 seconds of podman run --detach (confirmed via a manual retry-loop, not just Jenkins) with no kernel OOM-killer event logged, so exit 137 here isn't real memory pressure either. Also found (untouched) a real, unrelated gap: test/run_docker_tests.sh does podman exec immediately after podman run --detach with no readiness check at all -- worth fixing regardless, but wouldn't explain this near-instant crash. Not resolved tonight; see "Open / carried forward" for the Robert-handoff writeup.

New standing Gen7 QA lab for //p4-sdp/main

Per the user's guidance (separate //BattleSchool/Gen7-stream workspace, still aws/vpc relative to root, no license-fix or double-lab 0 needed for Gen7, -r us-east-1 only), stood up a second Gen7 lab (bsw-SDP-QA-main) alongside the existing standing dev-targeted one, without touching the latter. Created //p4-sdp/main_insitu (cloned from the dev_insitu template) and a new locked client bot_SDP_QA.p4c-bos-01.SDP_QA_main, following the naming convention the team designed specifically for this parallel-stream scenario (see docs/SDP-QA-LabEnvironment.adoc's "Insitu Workspace Naming Convention" section). Copied credentials from the existing lab; verified a real, correct sync of //p4-sdp/main content. New SSH wrapper scripts at ~/ppn/7c_main/sdp_qa/ (separate directory, existing dev lab's wrappers untouched).

Running lab qa_build surfaced that the actual CLI test suite installs from a different piece of infrastructure than the insitu client: a DVCS clone at /opt/perforce/.dev/sdp, baked into the AMI and (on this fresh lab) still bound to a stale, pre-rebrand snapshot (Version file said 2025.1/dev_rebrand) under the user's personal P4 identity, which I don't have credentials for. Per the user ("just blast and re-clone"), wiped it and did a fresh p4 clone -f //p4-sdp/main/... as bot_Claude_Anthropic -- confirmed correct content (2026.1/33441) afterward. Re-ran lab qa_build: the stale-content symptoms (a helix-sdp- named backup path, a stale r25.1 doc URL -- both false alarms from testing old content, not real bugs in current main, a correction made to the user after initially flagging them) were gone, but a new failure appeared (Root directory ... invalid: chdir: /opt/perforce/ p4-sdp/p4/sdp/.p4root: No such file or directory) -- looks like leftover partial /opt/perforce/p4-sdp structure from the first (stale-content) failed install attempt that wasn't fully cleaned before the second attempt. Not chased further tonight given the hour; see "Open / carried forward."

Open / carried forward

  • Jenkins podman crash: still unresolved. User manually kicked off a 4th build attempt ("try try again," no changes made) -- crashed again with the familiar container state improper signature. Same failure class as 2026-08-24/25, recurring with no config/package drift since the last confirmed-working state. After a full container/image wipe, the container now dies within ~1-2 seconds of podman run --detach (not a stale-image or slow-startup issue), no kernel OOM event logged. Two consistent clues in every crash: Failed to set RLIMIT_CORE: Operation not permitted and conmon: failed to write to /proc/self/oom_score_adj: Permission denied. A research fork raised an untracked SELinux/systemd-policy change as one possible explanation for the capability/policy-denial flavor of these clues, but the user is skeptical ("Nothing would have changed with SELinux since our last attempts, so I think we can rule that out???") -- flagged to Robert as a tentative idea, not a confirmed cause. Sent Robert a Slack message (2026-09-04 evening, DM channel) asking him to look at the newly-configured //p4-sdp/main job (p4-sdp-build_main) when he gets a chance -- US is off Monday 2026-09-07 (Labor Day) but it's not a UK holiday, so there's a reasonable chance he gets to it before Tuesday. Jenkins-on-main is generally considered critical path to shipping 2026.1 on Tuesday 2026-09-08, but the user explicitly floated an override: if we're confident nothing Jenkins would have caught has actually regressed since it last worked on //p4-sdp/dev (i.e., if every failure here is purely "that Jenkins box is flaky"), the user may decide to ship Tuesday without a green Jenkins run on main. Longer-term, the user hopes to retire this whole test suite once its unique coverage is ported to the other SDP test suites, so this box's flakiness is a shrinking concern, not a growing one.
  • Gen7 main QA lab: lab qa_build still fails, now on what looks like leftover /opt/perforce/p4-sdp structure from the first (stale-DVCS-clone) attempt. Try a full DANGER_CLEAN.sh (or equivalent) pass, or just re-run lab qa_build once more now that the DVCS clone is correct, before assuming this needs deeper investigation. User has now explicitly put a clean Gen7 test run on main on the critical path to shipping Tuesday 2026-09-08 -- unlike the Jenkins item above, no stated override/flexibility on this one.
  • Gen6 lab-reset (lab 0) retest, post-upgrade: after the first SDP+P4D upgrade exercise on bsw-sdp-upgrade-test, lab 0 started failing quickly and repeatedly on that same lab; not yet known whether the upgrade itself broke the lab-reset mechanism or whether that was a fluke isolated to the first environment (the second exercise, on a fresh lab bsw-sdp-upgrade-test2, was not itself re-tested with a post-upgrade lab 0). User wants to run lab 0 again in a lab, after a successful upgrade, specifically to answer this question before Tuesday.
  • doc/gen/get_helix_binaries.sh.man.txt: confirmed orphaned and deleted from dev; main never had it, nothing further needed.
  • HMS URL: done, both placeholders filled in dev->main.
  • Version-format change: done on r26.1.0.BETA only, as decided. Real GA on 2026-09-08 will get 2026.1.0 naturally from the normal release tooling -- no further action needed unless the user wants main/dev's current Version file updated preemptively too (explicitly not done this session, per the user's framing that this was specifically about "the new environment"/BETA).
  • SDP-1387 (gen_script_man_pages.sh stderr check): filed, deferred, no code changes made.
  • "We've Moved" Classic SDP changes: still staged from 2026-09-04 morning, reviewed and approved by the user, gated on the real GA shipping 2026-09-08 (see project_sdp1170_stale_url_safety memory). Not touched further tonight.
  • The "Hot Fix" glossary entry / 2026.2 Release Notes content / disposable EC2s: no change from earlier status (see 2026-09-04 morning's summary in this same log, or memory).
  • User is wrapping up for the night; plans to pick back up Tuesday morning (2026-09-08, release day) unless time opens up over the weekend. Three items above (Jenkins-on-main, Gen7 main QA lab clean run, Gen6 post-upgrade lab 0 retest) are the specific carry- forwards called out for Tuesday; the Gen7 and lab 0 items are release-blocking, Jenkins is critical-path-with-a-possible-override (see bullet above).
# Session Log -- 2026-09-04

## Summary

Picked up from yesterday's first real Streams-native release rehearsal. Found and fixed
several real bugs while exercising the process further: a README.md link-rendering
regression (root-caused to a missed Copy Up), a stale/wrong "Directory Structure Changes"
section in `sdp_upgrade.sh`'s embedded docs, and -- the big one -- an unescaped quote that
had been silently truncating `upgrade.sh -man`'s entire ~580 lines of documentation down to
an 8-line stub for as long as the SBD feature text existed. Wrote up the "Merge Down, Copy
Up" mantra as an explicit process rule after the second regression traced to the same root
cause. Ran the full SDP+P4D upgrade exercise for real on a BSW Gen6 lab, found and fixed a
real, long-standing naive-lexicographic-version-comparison bug in both `upgrade.sh` and
`sdp_upgrade.sh` (confirmed it also explains a known, years-old internal-P4D-build pain
point the user described). Filled in the HMS URL. Adopted a new SDP Version-file format
(`YYYY.N.P[.SUFFIX]`) on the `r26.1.0.BETA` rehearsal stream. Set up a new Jenkins job and a
new standing Gen7 QA lab for `//p4-sdp/main` (in progress/partially blocked, see below).

## README.md link regression, root cause, and the "Merge Down, Copy Up" mantra

User reported the Swarm rendering fix from 2026-09-03 (site-relative `/view/` links) had
"come back" broken on both `r26.1.0.BETA` and `main`. Root cause: `main` never actually
received that fix -- it was made in `dev` (and manually patched into `r26.1.0.BETA`) but
never Copied Up into `main`; the only `main`-side README.md edit since then (change 33463)
was an unrelated platform-support text fix. When `r26.1.0.BETA` was later refreshed *from*
`main` (to catch it up on unrelated changes, change 33471), that Copy-Up-from-main step
faithfully propagated `main`'s stale, never-fixed content right over BETA's previously-good
copy -- a real regression caught by the user re-testing a link they'd already confirmed
fixed. Fixed via Copy Up from `dev` into `main` (33478) and re-synced into BETA (33480).

This is the second time this exact class of bug has bitten this cycle (the first was
`doc/ReleaseNotes.adoc`'s Jobs-Fixed list, found and fixed 2026-09-03/04 morning). Wrote up
an explicit "Merge Down, Copy Up" mantra -- always Merge Down before a Copy Up, in either
direction, with rare exceptions for deliberate cherry-picking -- as a new callout in
`doc/ReleaseProcessOverview.md` (change 33482/33483) and as a feedback memory
(`feedback_merge_down_before_copy_up.md`).

## `sdp_upgrade.sh` EDITME fix (change 33485/33487)

The "Directory Structure Changes" section described a not-yet-implemented `/opt/perforce/
p4-sdp` OS-package migration (SDP-1158, deferred to 2026.2, 0% implemented) as if it were
current 2026.1 behavior. Replaced with an accurate description of the two structures that
actually exist today (legacy/depot-mount, and the `install_sdp.sh`-created
`/opt/perforce/helix-sdp` structure since 2024.2). Also removed an orphaned `EDITME - END`
marker and filled in a blank FILES AND DIRECTORIES table entry.

## The `upgrade.sh -man` truncation bug (change 33492/33493/33494-33496)

While fixing an unrelated wording nit (user asked to drop "at least" from "unconditionally
raises 'security' to at least 4" -> "to 4", to avoid drawing attention to security levels
above 4 which SDP doesn't support), regenerating `doc/gen/upgrade.sh.man.txt` turned up
something serious: the file was suspiciously short (8 lines vs. 34-676 for every other
script). Root cause: an unescaped double-quote inside the `-opt-out-of-security-update` help
text (`'p4d -r <P4ROOT> "-cset security=<value>"'`) broke bash's parsing of the *entire*
multi-hundred-line DESCRIPTION+OPTIONS `msg()` call in the `-man` handler -- confirmed via
`bash -x` showing the parser choking right at the broken quote, producing a bash runtime
error that `gen_script_man_pages.sh` silently swallows (`2>/dev/null`, only checks the output
file is non-empty). Net effect: **`upgrade.sh -man` had been producing almost no real
content since the SBD text was added**, and since `SDP_Guide.Unix.html` includes that
generated man page via `include::`, the customer-facing Developer/SDP Guide was silently
missing nearly all of `upgrade.sh`'s documented content, including the `-Os`/
`-opt-out-of-security-update` section itself.

Fixed the quote escaping; verified `upgrade.sh -man` now produces its full ~580 lines.
Systematically checked all 15 other scripts in `gen_script_man_pages.sh`'s list (both by
actually running each with the same minimal environment the generator uses, capturing
stderr instead of discarding it, and via a textual pattern search) -- confirmed this was an
isolated incident, nothing else affected. Also found and deleted an orphaned
`doc/gen/get_helix_binaries.sh.man.txt` (leftover from before the `get_p4_binaries.sh`
rename; `dev` only, `main` never had it).

Filed **SDP-1387** (deferred, not urgent, per the user): make `gen_script_man_pages.sh` flag
non-empty stderr from a script's `-man`/`-h` invocation as an error, instead of silently
discarding it -- this exact check would have caught the bug immediately, since the bash
runtime error was going to stderr the whole time.

## Real Gen6 upgrade exercise, twice, and the version-comparison bug (change 33502/33503)

Wrote a new skill, `bsw-gen6-lab-create` (`//BattleSchool/main/ai/skills/`), documenting how
to spin up a BSW Gen6 lab via `genlab.sh`, including a first-run `lab 0` idiosyncrasy (run it
twice; a topology-role misconfiguration self-corrected on a third attempt on the second
lab, cause not fully understood, not pursued further tonight) and a real `-u` Usage-tag bug
in `genlab.sh` itself (`UserDefinedResourceUsageTag` vs. `UserDefinedResourceTag` mismatch --
fixed in `//BattleSchool/main`, change 2764053, merged down cleanly into `//BattleSchool/
Gen7`, change 2764055).

Ran the full outer-to-inner SDP-then-P4D upgrade exercise for real on lab
`bsw-sdp-upgrade-test` (SDP 2023.2->2026.1, P4D 2023.1->2026.1). Hit the new SDP-1350 Secure
By Default guard for real (every host at `security=0`, the lab's intentional low-friction
config) -- used `-Os` on non-master hosts and `-Os -opt-out-of-security-update` together on
the commit server (found that `-opt-out-of-security-update` is commit-server-only *and*
doesn't bypass the abort by itself, needing `-Os` alongside it). All verification passed:
`p4 upgrades` (60/60 steps completed after allowing ~1 minute settling time), `p4 pull -ljv`
before/after, `p4 servers -J` full-topology checks, `security` configurable correctly
restored to 0.

User then asked to make the SDP Version-file format decision real (`2026.1.0.BETA` instead
of `2026.1`) and asked what else besides Release Notes/generating tools might depend on the
exact format. Investigation found a real, confirmed break: `sdp_upgrade.sh`'s downgrade-
detection logic does a naive lexicographic string comparison, and a longer/differently-
shaped version string (more dot-components) sorts as *less than* a shorter one sharing the
same prefix -- would misclassify the exact `2026.1` -> `2026.1.0.BETA` transition as a
downgrade. Real customers are safe (the actual prior release, 2025.2, differs in the year
digit early enough to save the old comparison by luck), but our own rehearsal/testing
environments already stamped `2026.1` are not. The user then revealed this is the *same*
long-standing bug class behind a real, years-old pain point: Perforce's internal-only P4D
builds use a deliberately different version scheme (e.g. `2025.1.PREP-TEST_ONLY`) to make it
obvious you're not on an official release, and `upgrade.sh`'s own downgrade check has the
identical naive-comparison problem with those strings.

Fixed both scripts with a new, numeric-aware `compare_versions()` / `_leading_numeric_
version_core()` function pair (duplicated identically in each file -- they don't share a
library) that separates a trailing numeric changelist/build number from the "core" release
number, takes only the leading numeric run of the core (silently ignoring any non-numeric
internal/pre-release suffix), zero-pads to a fixed width, and compares numerically rather
than lexicographically -- fixing both the suffix-insertion bug and a related digit-width bug
(`9` vs `10`-style misordering) in one pass. Verified against 12 hand-built scenarios
(including the real 2025.2->2026.1.0 GA transition, same-version equality despite differing
suffix/CL-embedding shape, and internal-build-vs-internal-build ordering both directions)
before touching the real scripts. Propagated dev->main->r26.1.0.BETA, repackaged and
republished `main`'s live tarball, and re-verified the entire upgrade exercise end-to-end a
*second* time on a brand-new lab (`bsw-sdp-upgrade-test2`) with all fixes in place -- clean
pass, identical to the first run.

Then made the Version-format change for real on `r26.1.0.BETA` (change 33519): `Rev. SDP/
MultiArch/2026.1/33441 (...)` -> `Rev. SDP/MultiArch/2026.1.0.BETA/33441 (...)`. Real GA on
2026-09-08 will naturally get `2026.1.0` (no suffix) from the normal Step 15 tooling; no code
changes needed for that, this was purely a data/rehearsal decision. Did not touch `main`'s or
`dev`'s current Version file.

## HMS URL filled in (change 33507/33508)

User supplied the one URL needed for both `README.md` and `doc/SDP_Legacy_Upgrades.Unix.adoc`'s
`EDITME-UpdateThisURL` placeholders: `https://swarm.workshop.perforce.com/projects/
perforce_software-hms` (the P4 Code Review project home page for HMS -- still pointing at
HMS's own Classic depot home today, but will be silently retargeted, no SDP-side update
needed, whenever HMS moves its own "main branch" to a `//p4-hms/main` stream).

## Release Notes: called out the new `-Os`/`-opt-out-of-security-update` options (33489-33491)

Expanded the SBD "What's New" bullet to explicitly describe `-Os` and `-opt-out-of-security-
update`, when each is needed, and the commit-server-only restriction -- prompted directly by
hitting this for real during the Gen6 upgrade exercise above.

## Two disposable EC2 test VMs from 2026-09-02 terminated

`i-0dac4107629a1c421` (disposable-test-u24-1) and `i-0160e0ab72d868a67` (disposable-test-r9-1),
both in us-east-2, terminated per the user's request.

## New Jenkins job for `//p4-sdp/main`, blocked by a pre-existing host issue

Created `p4-sdp-build_main` (cloned virtual stream `//p4-sdp/build_main` off `//p4-sdp/main`,
cloned job config from `p4-sdp-build_dev`, reloaded Jenkins) per the `sdp-jenkins-build-check`
skill's documented procedure. Every trigger attempt (4 total, including one after a full host
reboot at the user's request) hit a rootless-podman/systemd container crash -- three
different failure signatures across attempts (`container state improper`, `OCI runtime
error: crun: read pipe failed`), with `Failed to set RLIMIT_CORE: Operation not permitted`
and `failed to write to /proc/self/oom_score_adj: Permission denied` present in every crash
log. The existing `p4-sdp-build_dev` job's container also crashed once (exit 137) during
this, real evidence the RAM-contention risk flagged before creating the job was legitimate.
The skill's documented "remove bad images, let them rebuild" fix did not reliably resolve
it (matching the skill's own caveat that this fix is provisional). User manually retriggered
(build #4, no changes) -- failed again, same signature, ruling out simple flakiness/timing.
A fork then researched this further: found the *exact same crash class* already happened
2026-08-24/25 (a multi-day investigation at the time, exhaustively eliminated parallel-sync
settings, stream-mode vs view-mode, virtual-stream remapping, checkout size, and a host
package regression -- never cleanly attributed to one cause, eventually resolved via a
Dockerfile fix plus Robert's own podman updates and a full container-store wipe). Confirmed
no package drift since then, cgroup delegation (`Delegate=`) and `loginctl` linger for
`jenkins` both still correctly in place, disk/inodes fine, `podman info` clean, and `main`'s
image genuinely builds successfully (ruling out the historical "silently falls through to a
stale cached image" bug). Per instruction, did a full container/image wipe (all containers
and images, including the base image) -- got past the previous crash signature entirely on
the rebuild, but the container now dies within ~2 seconds of `podman run --detach` (confirmed
via a manual retry-loop, not just Jenkins) with no kernel OOM-killer event logged, so `exit
137` here isn't real memory pressure either. Also found (untouched) a real, unrelated gap:
`test/run_docker_tests.sh` does `podman exec` immediately after `podman run --detach` with no
readiness check at all -- worth fixing regardless, but wouldn't explain this near-instant
crash. Not resolved tonight; see "Open / carried forward" for the Robert-handoff writeup.

## New standing Gen7 QA lab for `//p4-sdp/main`

Per the user's guidance (separate `//BattleSchool/Gen7`-stream workspace, still `aws/vpc`
relative to root, no license-fix or double-`lab 0` needed for Gen7, `-r us-east-1` only),
stood up a second Gen7 lab (`bsw-SDP-QA-main`) alongside the existing standing dev-targeted
one, without touching the latter. Created `//p4-sdp/main_insitu` (cloned from the `dev_insitu`
template) and a new locked client `bot_SDP_QA.p4c-bos-01.SDP_QA_main`, following the naming
convention the team designed specifically for this parallel-stream scenario (see
`docs/SDP-QA-LabEnvironment.adoc`'s "Insitu Workspace Naming Convention" section). Copied
credentials from the existing lab; verified a real, correct sync of `//p4-sdp/main` content.
New SSH wrapper scripts at `~/ppn/7c_main/sdp_qa/` (separate directory, existing dev lab's
wrappers untouched).

Running `lab qa_build` surfaced that the actual CLI test suite installs from a *different*
piece of infrastructure than the insitu client: a DVCS clone at `/opt/perforce/.dev/sdp`,
baked into the AMI and (on this fresh lab) still bound to a stale, pre-rebrand snapshot
(`Version` file said `2025.1/dev_rebrand`) under the user's personal P4 identity, which I
don't have credentials for. Per the user ("just blast and re-clone"), wiped it and did a
fresh `p4 clone -f //p4-sdp/main/...` as `bot_Claude_Anthropic` -- confirmed correct content
(`2026.1/33441`) afterward. Re-ran `lab qa_build`: the stale-content symptoms (a `helix-sdp`-
named backup path, a stale `r25.1` doc URL -- both false alarms from testing old content, not
real bugs in current `main`, a correction made to the user after initially flagging them)
were gone, but a *new* failure appeared (`Root directory ... invalid: chdir: /opt/perforce/
p4-sdp/p4/sdp/.p4root: No such file or directory`) -- looks like leftover partial
`/opt/perforce/p4-sdp` structure from the *first* (stale-content) failed install attempt that
wasn't fully cleaned before the second attempt. Not chased further tonight given the hour;
see "Open / carried forward."

## Open / carried forward

- **Jenkins podman crash**: still unresolved. User manually kicked off a 4th build attempt
  ("try try again," no changes made) -- crashed again with the familiar `container state
  improper` signature. Same failure class as 2026-08-24/25, recurring with no config/package
  drift since the last confirmed-working state. After a full container/image wipe, the
  container now dies within ~1-2 seconds of `podman run --detach` (not a stale-image or
  slow-startup issue), no kernel OOM event logged. Two consistent clues in every crash:
  `Failed to set RLIMIT_CORE: Operation not permitted` and `conmon: failed to write to
  /proc/self/oom_score_adj: Permission denied`. A research fork raised an untracked
  SELinux/systemd-policy change as one possible explanation for the capability/policy-denial
  flavor of these clues, but the user is skeptical ("Nothing would have changed with SELinux
  since our last attempts, so I think we can rule that out???") -- flagged to Robert as a
  tentative idea, not a confirmed cause. Sent Robert a Slack message (2026-09-04 evening, DM
  channel) asking him to look at the newly-configured `//p4-sdp/main` job
  (`p4-sdp-build_main`) when he gets a chance -- US is off Monday 2026-09-07 (Labor Day) but
  it's not a UK holiday, so there's a reasonable chance he gets to it before Tuesday.
  Jenkins-on-`main` is generally considered critical path to shipping 2026.1 on Tuesday
  2026-09-08, **but** the user explicitly floated an override: if we're confident nothing
  Jenkins would have caught has actually regressed since it last worked on `//p4-sdp/dev`
  (i.e., if every failure here is purely "that Jenkins box is flaky"), the user may decide to
  ship Tuesday without a green Jenkins run on `main`. Longer-term, the user hopes to retire
  this whole test suite once its unique coverage is ported to the other SDP test suites, so
  this box's flakiness is a shrinking concern, not a growing one.
- **Gen7 `main` QA lab**: `lab qa_build` still fails, now on what looks like leftover
  `/opt/perforce/p4-sdp` structure from the first (stale-DVCS-clone) attempt. Try a full
  `DANGER_CLEAN.sh` (or equivalent) pass, or just re-run `lab qa_build` once more now that
  the DVCS clone is correct, before assuming this needs deeper investigation. **User has now
  explicitly put a clean Gen7 test run on `main` on the critical path to shipping Tuesday
  2026-09-08** -- unlike the Jenkins item above, no stated override/flexibility on this one.
- **Gen6 lab-reset (`lab 0`) retest, post-upgrade**: after the first SDP+P4D upgrade exercise
  on `bsw-sdp-upgrade-test`, `lab 0` started failing quickly and repeatedly on that same lab;
  not yet known whether the upgrade itself broke the lab-reset mechanism or whether that was
  a fluke isolated to the first environment (the second exercise, on a fresh lab
  `bsw-sdp-upgrade-test2`, was not itself re-tested with a post-upgrade `lab 0`). User wants
  to run `lab 0` again in a lab, after a successful upgrade, specifically to answer this
  question before Tuesday.
- **`doc/gen/get_helix_binaries.sh.man.txt`**: confirmed orphaned and deleted from `dev`;
  `main` never had it, nothing further needed.
- **HMS URL**: done, both placeholders filled in dev->main.
- **Version-format change**: done on `r26.1.0.BETA` only, as decided. Real GA on 2026-09-08
  will get `2026.1.0` naturally from the normal release tooling -- no further action needed
  unless the user wants `main`/`dev`'s *current* Version file updated preemptively too
  (explicitly not done this session, per the user's framing that this was specifically about
  "the new environment"/BETA).
- **SDP-1387** (gen_script_man_pages.sh stderr check): filed, deferred, no code changes made.
- **"We've Moved" Classic SDP changes**: still staged from 2026-09-04 morning, reviewed and
  approved by the user, gated on the real GA shipping 2026-09-08 (see
  `project_sdp1170_stale_url_safety` memory). Not touched further tonight.
- **The "Hot Fix" glossary entry / 2026.2 Release Notes content / disposable EC2s**: no
  change from earlier status (see 2026-09-04 morning's summary in this same log, or memory).
- User is wrapping up for the night; plans to pick back up Tuesday morning (2026-09-08,
  release day) unless time opens up over the weekend. Three items above (Jenkins-on-`main`,
  Gen7 `main` QA lab clean run, Gen6 post-upgrade `lab 0` retest) are the specific carry-
  forwards called out for Tuesday; the Gen7 and `lab 0` items are release-blocking, Jenkins
  is critical-path-with-a-possible-override (see bullet above).
# Change User Description Committed
#1 33520 Claude (AI Agent by Anthropic) Add session log for 2026-09-04.

Agent: Claude (Sonnet 5), on behalf of Tom Tyler.