.cognition/skills/debug-windows-ci/SKILL.md
# Debug PerlOnJava Windows CI Failures ## ⚠️⚠️⚠️ CRITICAL: NEVER USE `git stash` ⚠️⚠️⚠️ **DANGER: Changes are SILENTLY LOST when using git stash/stash pop!** - NEVER use `git stash` to temporarily revert changes - INSTEAD: Commit to a WIP branch or use `git diff > backup.patch` - This warning exists because completed work was lost during debugging ## Overview This skill helps debug test failures that occur specifically in the Windows CI/CD environment but pass locally on macOS/Linux. ## Wh
npx skillsauth add fglock/perlonjava .cognition/skills/debug-windows-ciInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
git stash ⚠️⚠️⚠️DANGER: Changes are SILENTLY LOST when using git stash/stash pop!
git stash to temporarily revert changesgit diff > backup.patchThis skill helps debug test failures that occur specifically in the Windows CI/CD environment but pass locally on macOS/Linux.
The CI runs on windows-latest using:
make ci runs mvn clean test)# List recent CI runs
gh run list --branch <branch-name> --limit 5
# View failed test logs
gh run view <run-id> --log-failed
# Filter for specific errors
gh run view <run-id> --log-failed 2>&1 | grep -E "FAILURE|error|not ok"
# Get test count summary
gh run view <run-id> --log-failed 2>&1 | grep "Tests run:"
Symptom: "Cannot chdir back to : 2" or "Undefined subroutine &Cwd::cwd called"
Root Cause: The Perl Cwd.pm uses shell backticks (`cd`) on Windows which doesn't work in PerlOnJava.
Solution: PerlOnJava provides Internals::getcwd which uses Java's System.getProperty("user.dir"). The Cwd.pm has been modified to use this when available.
Key Files:
src/main/perl/lib/Cwd.pm - Perl module with platform-specific fallbackssrc/main/java/org/perlonjava/runtime/perlmodule/Internals.java - Java implementation of getcwdSymptom: "Cannot open/create <filename>: open failed"
Root Cause:
\ vs /)Debugging:
# Check temp path in error message
gh run view <run-id> --log-failed 2>&1 | grep "open failed"
PerlOnJava sets $^O based on the Java os.name property:
MSWin32darwinlinuxKey File: src/main/java/org/perlonjava/runtime/runtimetypes/SystemUtils.java
Windows CI may fail when Perl code uses:
system() calls assuming Unix shell# Get list of failing tests
gh run view <run-id> --log-failed 2>&1 | grep "testUnitTests.*FAILURE"
# List tests in order (tests are numbered alphabetically)
ls -1 src/test/resources/unit/*.t | sort | nl | grep "<number>"
# Get full context around error
gh run view <run-id> --log-failed 2>&1 | grep -A10 "unit\\<test>.t"
# Compare with master branch CI
gh run list --branch master --limit 3
gh run view <master-run-id> --log-failed
if ($^O eq 'MSWin32') {
# Windows-specific code
}
if (SystemUtils.osIsWindows()) {
// Windows-specific code
}
# In Cwd.pm, use Internals::getcwd if available
if (eval { Internals::getcwd(); 1 }) {
*getcwd = \&Internals::getcwd;
}
src/test/resources/unit/*.tperl5_t/t/src/test/java/org/perlonjava/.github/workflows/gradle.yml - CI workflow definitionMakefile - Build targets including cisrc/main/java/org/perlonjava/runtime/perlmodule/Cwd.java - Java Cwd stubsrc/main/perl/lib/Cwd.pm - Perl Cwd implementation$^O being checked correctly?defined &Subroutine checks that might behave differently?To debug CI issues, you can temporarily add print statements to Perl modules:
# Add to Cwd.pm to debug
warn "DEBUG: \$^O = $^O";
warn "DEBUG: Internals::getcwd available: " . (eval { Internals::getcwd(); 1 } ? "yes" : "no");
Then check CI logs:
gh run view <run-id> --log-failed 2>&1 | grep "DEBUG:"
Remember to remove debug output before final commit.
development
# PerlOnJava Debugging Skills and Architecture Knowledge This document captures key knowledge about PerlOnJava internals learned during debugging sessions. ## Variable Storage and Scoping ### Three Types of Variable Declarations 1. **`my` variables** - Lexical scope - Stored in JVM local variable slots during normal execution - When captured by closures: stored as closure fields or in GlobalVariable with IDs - Symbol table entry: `decl = "my"`, has `index` (JVM slot number) 2. **`o
development
# PerlOnJava Interpreter Developer Guide - name all test files /tmp/test.pl ## Quick Reference **Performance:** 46.84M ops/sec (1.75x slower than compiler ✓) **Opcodes:** 0-157 (contiguous) for JVM tableswitch optimization **Runtime:** 100% API compatibility with compiler (zero duplication) ### Testing Modes **JPERL_EVAL_USE_INTERPRETER=1** - Forces all eval STRING to use the interpreter - Used for testing interpreter implementation of operators in eval context - Compiler still used for mai
development
# Profile PerlOnJava ## ⚠️⚠️⚠️ CRITICAL: NEVER USE `git stash` ⚠️⚠️⚠️ **DANGER: Changes are SILENTLY LOST when using git stash/stash pop!** - NEVER use `git stash` to temporarily revert changes - INSTEAD: Commit to a WIP branch or use `git diff > backup.patch` - This warning exists because completed work was lost during debugging Profile and optimize PerlOnJava runtime performance using Java Flight Recorder. ## Git Workflow **IMPORTANT: Never push directly to master. Always use feature bra
development
# Port CPAN Module to PerlOnJava ## ⚠️⚠️⚠️ CRITICAL: NEVER USE `git stash` ⚠️⚠️⚠️ **DANGER: Changes are SILENTLY LOST when using git stash/stash pop!** - NEVER use `git stash` to temporarily revert changes - INSTEAD: Commit to a WIP branch or use `git diff > backup.patch` - This warning exists because completed work was lost during debugging This skill guides you through porting a CPAN module with XS/C components to PerlOnJava using Java implementations. ## When to Use This Skill - User as