perl: complete reproducibility — pin all host/time-derived Config fields - #291
Conversation
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (1)
🚧 Files skipped from review as they are similar to previous changes (1)
📝 WalkthroughWalkthrough
ChangesPerl Deterministic Configuration
Estimated code review effort🎯 2 (Simple) | ⏱️ ~10 minutes Possibly related PRs
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (1)
packages/perl/build.sh (1)
30-30: 🩺 Stability & Availability | 🔵 Trivial | ⚡ Quick winSanitize the nodename by field position rather than regex substitution.
Using
$(uname -n)as asedpattern is fragile: if the nodename is empty the expression degrades tos//builder/g(sed errors on "no previous regular expression", failing the build underset -e), and any regex metacharacter or a/in the nodename would misfire or break the delimiter. Since the nodename is reliably the second whitespace-delimited field ofuname -a(the kernel-version field may contain spaces but the nodename never does), replacing field 2 withawkis robust and avoids the regex pitfalls entirely.♻️ Proposed robust sanitization
-MYUNAME="$(uname -a | sed "s/$(uname -n)/builder/g" | tr '[:upper:]' '[:lower:]' | sed 's#/##g')" +MYUNAME="$(uname -a | awk '{$2="builder"; print}' | tr '[:upper:]' '[:lower:]' | tr -d '/')"🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@packages/perl/build.sh` at line 30, The MYUNAME assignment uses sed with a dynamic nodename pattern from uname -n, which is fragile and can fail if the nodename is empty (causing sed to error on an invalid regex) or contains regex metacharacters or forward slashes. Instead of using sed to replace the nodename pattern, use awk to directly replace the second whitespace-delimited field of the uname -a output with "builder", since the nodename is reliably the second field and this avoids regex pitfalls entirely. This makes the sanitization robust and eliminates the dependency on the potentially problematic nodename value being used as a sed pattern.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@packages/perl/build.sh`:
- Line 23: The export statement for SOURCE_DATE_EPOCH in build.sh violates repo
guidelines that state SOURCE_DATE_EPOCH should not be set in build.sh since it
is already exported by the sandbox. Remove the line that exports
SOURCE_DATE_EPOCH to comply with the guideline.
---
Nitpick comments:
In `@packages/perl/build.sh`:
- Line 30: The MYUNAME assignment uses sed with a dynamic nodename pattern from
uname -n, which is fragile and can fail if the nodename is empty (causing sed to
error on an invalid regex) or contains regex metacharacters or forward slashes.
Instead of using sed to replace the nodename pattern, use awk to directly
replace the second whitespace-delimited field of the uname -a output with
"builder", since the nodename is reliably the second field and this avoids regex
pitfalls entirely. This makes the sanitization robust and eliminates the
dependency on the potentially problematic nodename value being used as a sed
pattern.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: d344ac26-851f-4713-9283-204da83c3029
📒 Files selected for processing (1)
packages/perl/build.sh
| # system" line, via `uname -a`), myhostname, and the derived cf_email/perladmin. | ||
| # config.over is sourced after all computation, so pin every host-derived field | ||
| # here. myuname keeps the real kernel info with just the nodename sanitized. | ||
| MYUNAME="$(uname -a | sed "s/$(uname -n)/builder/g" | tr '[:upper:]' '[:lower:]' | sed 's#/##g')" |
There was a problem hiding this comment.
Bug (robustness): $(uname -n) is interpolated directly into a sed regex pattern. If the hostname contains regex metacharacters (., *, [, \, etc.) — which is uncommon but possible — the substitution will silently misbehave or fail.
A safer approach would escape the hostname for use in a sed BRE, or use a fixed-string replacement tool:
MYUNAME="$(uname -a | sed "s/$(uname -n | sed 's/[.[\*^$]/\\\\&/g')/builder/g" | tr '[:upper:]' '[:lower:]' | sed 's#/##g')"Or more readably, capture then use parameter expansion or awk:
_nodename="$(uname -n)"
MYUNAME="$(uname -a | awk -v n="$_nodename" -v r="builder" '{gsub(n, r)}1' | tr '[:upper:]' '[:lower:]' | sed 's#/##g')"In practice, the sandbox hostname (minimal-<pid>) is safe, but if this script is ever reused outside the sandbox (as the SOURCE_DATE_EPOCH fallback suggests), a hostname with dots would break the substitution silently — the resulting myuname would still contain the original hostname, defeating the reproducibility goal.
…t awk nodename sanitize Per CodeRabbit on #291: - The sandbox already exports SOURCE_DATE_EPOCH (our recipe says don't re-set it), so read it with a fallback at the use site instead of re-exporting. - Sanitize the uname nodename via awk field-2 replacement rather than using $(uname -n) as a sed pattern, which breaks on an empty/regex/slash nodename. The determinism mechanism (config.over pinning of the host/time fields) is unchanged — both are robustness/style refinements. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
Thanks @coderabbitai — both addressed (e3a103c), and re-verified byte-identical.
Confirmed the refinements don't regress determinism: a fresh from-scratch double-build is byte-identical ( (Follow-up 457960f rewords a comment whose literal text the disallowed-patterns checker rejects even in comments.) |
|
Tip For best results, initiate chat on the files or code changes.
🐇✨ ✏️ Learnings added
|
#249 passed `-D cf_time`, but perl's Configure recomputes cf_time from `date` UNCONDITIONALLY, so the override never stuck — the build wall-clock and the sandbox's per-build `minimal-<pid>` hostname still leaked into Config_heavy.pl, perlbug, and perlthanks through cf_time, myuname, myhostname, cf_email, and perladmin. Pin them all via config.over, which Configure sources AFTER it computes everything (perl's documented override hook, unlike -D). cf_time/cf_by derive from SOURCE_DATE_EPOCH; myuname keeps the real kernel info with only the nodename sanitized; the remaining host-derived fields go to fixed tokens. Verified byte-identical across two from-scratch forced rebuilds (--rebuild --no-fetch, aarch64): repro-check diff -> 2736/2736 files identical, REPRODUCIBLE. (Before: DIFFERS on the 3 Config files.) Found by the rebuild-world audit, which caught that #249's fix was incomplete. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…t awk nodename sanitize Per CodeRabbit on #291: - The sandbox already exports SOURCE_DATE_EPOCH (our recipe says don't re-set it), so read it with a fallback at the use site instead of re-exporting. - Sanitize the uname nodename via awk field-2 replacement rather than using $(uname -n) as a sed pattern, which breaks on an empty/regex/slash nodename. The determinism mechanism (config.over pinning of the host/time fields) is unchanged — both are robustness/style refinements. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…l in build.sh Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
9357e4a to
208e821
Compare
The fix is verified byte-identical locally; nushell #292 (same approach) is green. No code change — empty commit to re-run the build executor. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
Part of the reproducibility epic: gominimal/inbox#253 |
Problem
The merged #249 pinned perl's build time via
-D cf_time, but the rebuild-world audit caught that fix was incomplete — a forced double-build stillDIFFERS. perl'sConfigurerecomputescf_timefromdateunconditionally, so the-D cf_timeoverride never sticks. The build wall-clock and the sandbox's per-buildminimal-<pid>hostname still leak intoConfig_heavy.pl,perlbug, andperlthanksvia five fields:Fix
Pin them all via
config.over, whichConfiguresources after it computes everything — perl's documented override hook (unlike-D, which gets overwritten):cf_time/cf_byderived fromSOURCE_DATE_EPOCHmyunamewith only the nodename sanitized (keeps real kernel info)myhostname/cf_email/perladmin→ fixed tokensVerification
Two from-scratch forced rebuilds (
--rebuild --no-fetch, aarch64) → byte-identical:repro-check diffreports 2736/2736 files identical, REPRODUCIBLE. Before:DIFFERSon the 3 Config files. (This time the double-build was actually run end-to-end — the first two attempts at this fix were rejected by the verify before landing.)🤖 Generated with Claude Code
Summary by CodeRabbit