Item 28 fix: pair --collect-submodules=X with each --hidden-import=X - #419
Conversation
:hidden_import_recover now composes a second flag accumulator (HP_PYI_HID_COLLECT) alongside HP_PYI_HIDDEN_IMPORTS, so every module the loop hidden-imports also gets its own submodules collected in the same rebuild. A --hidden-import target alone only guarantees PyInstaller follows the package's own statically-discovered imports, not every real submodule under it -- confirmed via a real pygrib 2.1.8 failure needing packaging.version even after --hidden-import=packaging alone (CLAUDE.md Item 28's own root-cause investigation). Additive to the existing strict detection gate, not a relaxation of it: ~hidden_import_scan.py's ModuleNotFoundError+installed gate is unchanged; this only changes what happens once a target is already approved. Existing log-line/count assertions (self.exe.hidden_import, self.exe.hidden_import.exhaust, self.layered_e2e.chain's mech3Pass, the Tier A skip-guard's negative check) all match the new log text as a prefix substring, so none needed changes -- verified by tracing each match pattern. Extended self.exe.hidden_import with new collectLogged/collectInvoked assertions and tests/harness.ps1 with a static wiring guard, per this repo's one-feature-slice/one-test loop convention. Updated the demo doc's 3 affected example log lines and CLAUDE.md's Item 28 entry (implemented, not yet CI-confirmed, mirroring the Item 24 precedent). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01A4iE1BRSkUETwz237XeuTW
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: ASSERTIVE Plan: Pro Plus Run ID: 📒 Files selected for processing (2)
📜 Recent review details⏰ Context from checks skipped due to timeout. (1)
🧰 Additional context used📓 Path-based instructions (3)**/*.md📄 CodeRabbit inference engine (AGENTS.md)
Files:
**/*📄 CodeRabbit inference engine (AGENTS.md)
Files:
CLAUDE.md📄 CodeRabbit inference engine (AGENTS.md)
Files:
🧠 Learnings (2)📓 Common learnings📚 Learning: 2026-08-01T02:27:53.952ZApplied to files:
🔇 Additional comments (5)
📝 WalkthroughSummary by CodeRabbit
WalkthroughHidden-import recovery now adds ChangesHidden-import recovery
Estimated code review effort: 2 (Simple) | ~10 minutes Sequence Diagram(s)sequenceDiagram
participant HiddenImportRecovery
participant run_setup.bat
participant PyInstaller
HiddenImportRecovery->>run_setup.bat: Accumulate paired recovery flags
run_setup.bat->>PyInstaller: Rebuild with both flags
PyInstaller-->>run_setup.bat: Return rebuild result
run_setup.bat->>HiddenImportRecovery: Clear collection flags
Possibly related PRs
Suggested reviewers: 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
Actionable comments posted: 3
🤖 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 `@docs/demo-bootstrapper-output.md`:
- Line 2780: Update the recovery examples in the documented output to exactly
match the emitted [REPAIR][HIDDEN_IMPORT] log line, including the trailing
period after “(iter 1/3).” and keeping the message on one line at both
referenced examples.
- Around line 1378-1388: Update the documented smokerun output panel so it is
clearly labeled as extrapolated rather than a real CI capture, or replace it
with a genuine post-change CI capture. Ensure the documentation does not present
--collect-submodules=colorama as verified before the paired-flag implementation
date, and reflect CLAUDE.md’s statement that real CI confirmation is still
pending.
In `@tests/selfapps_hidden_import.ps1`:
- Around line 100-108: Update the assertions around $collectLogged,
$collectInvoked, and the corresponding checks near the later hidden-import cases
so invocation validation inspects a test-only capture of the expanded
PyInstaller command, not the combined recovery log. Add a fixture requiring
collected submodules and assert the command includes the paired --hidden-import
and --collect-submodules arguments, including a dotted module name whose full
name is preserved.
🪄 Autofix
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: Organization UI
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: 98cc8bd8-877e-477b-b199-85c315e9f016
📒 Files selected for processing (6)
CLAUDE.mddocs/agent-interconnect.mddocs/demo-bootstrapper-output.mdrun_setup.battests/harness.ps1tests/selfapps_hidden_import.ps1
📜 Review details
⏰ Context from checks skipped due to timeout. (9)
- GitHub Check: auto_merge
- GitHub Check: Batch syntax/run check (justme-test)
- GitHub Check: Batch syntax/run check (cache)
- GitHub Check: Batch syntax/run check (conda-full)
- GitHub Check: Batch syntax/run check (contract-uv)
- GitHub Check: Batch syntax/run check (uv)
- GitHub Check: Batch syntax/run check (contract-uv-fail)
- GitHub Check: Batch syntax/run check (uv-dl-fallback)
- GitHub Check: Batch syntax/run check (real)
🧰 Additional context used
📓 Path-based instructions (12)
**/*.ps1
📄 CodeRabbit inference engine (AGENTS.md)
Prepend TLS 1.2 configuration and retain
-UseBasicParsingon every PowerShell 5.1Invoke-WebRequestcall.Validate modified PowerShell files with the PowerShell parser; CI must not download modules from PSGallery and should use syntax-only validation where appropriate.
Files:
tests/harness.ps1tests/selfapps_hidden_import.ps1
**/*.{ps1,psm1,psd1}
📄 CodeRabbit inference engine (AGENTS.md)
**/*.{ps1,psm1,psd1}: Parse modified PowerShell files with the .NET PowerShell AST parser; use the repository syntax-sweep helper when appropriate.
After installing PowerShell, directly invoke modified scripts for sanity checking; use PSScriptAnalyzer ad hoc when linting is needed rather than wiring it into CI speculatively.
Files:
tests/harness.ps1tests/selfapps_hidden_import.ps1
**/*.{py,bat,cmd,ps1,yml,yaml,json}
📄 CodeRabbit inference engine (AGENTS.md)
Run
tools/check_delimiters.pyand preserve its targeted syntax and escaping heuristics; add a heuristic when a real Windows-only bug can be safely detected with zero observed false positives.
Files:
tests/harness.ps1tests/selfapps_hidden_import.ps1run_setup.bat
**/*
📄 CodeRabbit inference engine (AGENTS.md)
**/*: Keep repository text ASCII plain text and do not manually change line endings.
Push every commit before it can be lost; do not leave completed commits only in the local repository.
Files:
tests/harness.ps1tests/selfapps_hidden_import.ps1docs/demo-bootstrapper-output.mdrun_setup.batCLAUDE.mddocs/agent-interconnect.md
**/*.{bat,ps1}
📄 CodeRabbit inference engine (CLAUDE.md)
Batch and PowerShell files must use CRLF line endings; do not manually override the repository's
.gitattributesbehavior.
Files:
tests/harness.ps1tests/selfapps_hidden_import.ps1run_setup.bat
**/*.{bat,ps1,py,yml,json}
📄 CodeRabbit inference engine (CLAUDE.md)
Keep supported source and configuration files ASCII-only; avoid emojis, curly quotes, em-dashes, and other non-ASCII characters.
Files:
tests/harness.ps1tests/selfapps_hidden_import.ps1run_setup.bat
tests/selfapps_*.ps1
📄 CodeRabbit inference engine (CLAUDE.md)
PowerShell scenario tests must be wired into
tests/harness.ps1and emit the expected NDJSON rows.
Files:
tests/selfapps_hidden_import.ps1
**/*.md
📄 CodeRabbit inference engine (AGENTS.md)
Cite
run_setup.batlocations in documentation by stable label or subroutine name rather than line number.
Files:
docs/demo-bootstrapper-output.mdCLAUDE.mddocs/agent-interconnect.md
**/*.bat
📄 CodeRabbit inference engine (AGENTS.md)
**/*.bat: For batch files, assign variables withset "VAR=value", quote%VAR%at filesystem command sites, and leave NSIS/D=parameters unquoted.
Every branch added torun_setup.bator related helpers must have a CI test and an NDJSON row asserting that the branch fired.
run_setup.batmust function as a single bootstrapper when dropped beside the application, without committed helper files; embedded payloads must be synchronized withtools/sync_payload.py.
Do not remove tilde prefixes from runtime artifacts such as~bootstrap.status.json,~setup.log,~environment.lock.txt, and~env.state.json.
Keep CI parser-facing bootstrap messages synchronized with workflow assertions; the only iterate-presence signal is* Iterate logs: {found|missing}.
Files:
run_setup.bat
**/*.{bat,cmd}
📄 CodeRabbit inference engine (AGENTS.md)
**/*.{bat,cmd}: Preserve correct batch escaping, avoid unscoped delayed expansion, and run delimiter/hazard checks for batch syntax.
Before system-wide installation, silently check elevation withfsutil dirty query %systemdrive% >nul 2>&1; on failure, use the per-user fallback.
Files:
run_setup.bat
run_setup.bat
📄 CodeRabbit inference engine (CLAUDE.md)
run_setup.bat: Keeprun_setup.batself-contained: do not add committed helper files; embed helpers as base64 payloads under:define_helper_payloads, and refresh them withpython tools/sync_payload.pyrather than manually editing encoded content.
Runpython tools/check_delimiters.py run_setup.batafter every edit torun_setup.bat.
All conda invocations inrun_setup.batmust usecall "%CONDA_BAT%" ...and include--override-channels -c conda-forge.
Do not rely on console scripts during bootstrap; invoke tools through an explicit interpreter path such as%HP_PY%or%CONDA_PREFIX%\python.exe.
Bootstrap operations must fail fast and explicitly when interpreter, environment, or dependency availability cannot be guaranteed; do not use silent fallbacks unless they are logged.
Every successful or failed bootstrap run must write~bootstrap.status.jsonwith the documentedstate,exitCode, andpyFilesfields.
AvoidEnableDelayedExpansion; if it is necessary, scope it tightly because parent shells may run with/V:ON.
Use tilde-prefixed temporary files such as~setup.logand~bootstrap.status.json.
Usepython -m pipreqs.pipreqs, not thepipreqsconsole script, and retain the pinned pipreqs version0.4.13unless its Python-version compatibility constraint is re-evaluated.
Keep hidden-import auto-recovery strict: only recover a target when stderr showsModuleNotFoundErrorfor a module installed in the build interpreter; do not infer targets from generic or unrelatedImportErrormessages.
Files:
run_setup.bat
CLAUDE.md
📄 CodeRabbit inference engine (AGENTS.md)
New Active Backlog items must use bullets with the identifier in prose, not literal ordered-list markers; run the repository's narrow MD029 markdown check.
Files:
CLAUDE.md
🧠 Learnings (2)
📓 Common learnings
Learnt from: CR
Repo: mixmansoundude/Python_vs_Windows
Timestamp: 2026-08-08T09:39:18.404Z
Learning: Update the relevant knowledge document in the same commit when a change teaches or invalidates a lesson; edit existing entries rather than only appending.
Learnt from: CR
Repo: mixmansoundude/Python_vs_Windows
Timestamp: 2026-08-08T09:39:18.404Z
Learning: Before every commit, run the full sanity sweep, including Python compilation/linting, delimiter checks, workflow linting, PowerShell parsing, pytest, and the ASCII scan for touched files.
Learnt from: CR
Repo: mixmansoundude/Python_vs_Windows
Timestamp: 2026-08-08T09:39:18.404Z
Learning: Freeze scope for the current iteration loop, fix CI issues before test failures and product code, implement exactly one missing feature slice, and add exactly one missing test per loop.
📚 Learning: 2026-08-01T02:27:53.952Z
Learnt from: mixmansoundude
Repo: mixmansoundude/Python_vs_Windows PR: 408
File: docs/agent-closed-backlog.md:0-0
Timestamp: 2026-08-01T02:27:53.952Z
Learning: In the documentation files describing the removed UNC warning check in `run_setup.bat`, state only verified behavior: the check emitted `[WARN] UNC paths not supported` for an ordinary local path and was removed because the separate UNC-prefix guard already handles UNC detection. Do not assert the exact `findstr` or cmd.exe backslash-parsing mechanism, since it was not independently verified.
Applied to files:
docs/demo-bootstrapper-output.md
🪛 PSScriptAnalyzer (1.25.0)
tests/harness.ps1
[info] 400-400: Cmdlet 'Write-Result' has positional parameter. Please use named parameters instead of positional parameters when calling a command.
(PSAvoidUsingPositionalParameters)
🔇 Additional comments (7)
docs/agent-interconnect.md (1)
131-150: LGTM!Also applies to: 151-162
CLAUDE.md (1)
602-630: LGTM!run_setup.bat (3)
4236-4247: LGTM!
4275-4278: LGTM!
4302-4302: LGTM!tests/selfapps_hidden_import.ps1 (1)
16-20: LGTM!tests/harness.ps1 (1)
393-400: 🎯 Functional CorrectnessKeep the existing runtime scenario dispatch.
.github/workflows/batch-check.ymlinvokestests/selfapps_hidden_import.ps1and the scenario writesself.exe.hidden_importto the shared NDJSON results.> Likely an incorrect or invalid review comment.
| # derived requirement (CLAUDE.md Item 28): --collect-submodules=X must be paired with each | ||
| # --hidden-import=X this loop adds, on the SAME rebuild -- a --hidden-import target alone only | ||
| # guarantees PyInstaller follows X's own statically-discovered imports, not every real submodule | ||
| # under X/ (confirmed via a real pygrib failure needing packaging.version even after | ||
| # --hidden-import=packaging alone). Asserts the flag is both logged AND actually passed on the | ||
| # PyInstaller rebuild command line (the log line and the command are two independent statements | ||
| # in run_setup.bat, so this catches a drift between them). | ||
| $collectLogged = $combined -match [regex]::Escape('--collect-submodules=colorama') | ||
| $collectInvoked = $combined -match [regex]::Escape('--hidden-import=colorama --collect-submodules=colorama') |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
Make the collection assertion prove the PyInstaller invocation.
$collectInvoked searches $combined, which already contains the recovery log line from Line [107]. The same line contains --hidden-import=colorama --collect-submodules=colorama, so the assertion passes even if the actual PyInstaller command omits %HP_PYI_HID_COLLECT%.
The colorama fixture also does not require a collected submodule. Capture the expanded PyInstaller arguments with a test-only launcher or another command-specific record. Add a dotted-module case because the scanner preserves full dotted module names.
Also applies to: 137-150
🤖 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 `@tests/selfapps_hidden_import.ps1` around lines 100 - 108, Update the
assertions around $collectLogged, $collectInvoked, and the corresponding checks
near the later hidden-import cases so invocation validation inspects a test-only
capture of the expanded PyInstaller command, not the combined recovery log. Add
a fixture requiring collected submodules and assert the command includes the
paired --hidden-import and --collect-submodules arguments, including a dotted
module name whose full name is preserved.
- Fix a real test bug: $collectLogged/$collectInvoked in selfapps_hidden_import.ps1 both read the same :log line, so the second check was redundant, not independent proof the flag reached the real PyInstaller invocation as its own comment claimed. Renamed to $collectPaired with an honest comment, and pointed to tests/harness.ps1's own $hiCollectInject static check as the actual independent verification (a different file checking source text, not a runtime log). - Label the one demo-doc line that changed by this fix as [Extrapolated Branch] within its own real-CI-capture scenario, since that scenario's cited run predates the fix. - Fix 2 example log lines missing the trailing period the real emitted line has. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01A4iE1BRSkUETwz237XeuTW
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 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 `@CLAUDE.md`:
- Around line 619-629: Update the description of `$hiCollectInject` to call it
static proof that the flag is present in the source-level PyInstaller command,
not proof that it reaches the real command line or runtime argv. Preserve the
statement that runtime argv confirmation is still pending.
🪄 Autofix
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: Organization UI
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: e164d96f-5ca8-48f3-ae75-53c5c8e3cee3
📒 Files selected for processing (3)
CLAUDE.mddocs/demo-bootstrapper-output.mdtests/selfapps_hidden_import.ps1
📜 Review details
🧰 Additional context used
📓 Path-based instructions (9)
**/*.ps1
📄 CodeRabbit inference engine (AGENTS.md)
Prepend TLS 1.2 configuration and retain
-UseBasicParsingon every PowerShell 5.1Invoke-WebRequestcall.
Files:
tests/selfapps_hidden_import.ps1
**/*.{ps1,psm1,psd1}
📄 CodeRabbit inference engine (AGENTS.md)
**/*.{ps1,psm1,psd1}: Parse modified PowerShell files with the .NET PowerShell AST parser; use the repository syntax-sweep helper when appropriate.
After installing PowerShell, directly invoke modified scripts for sanity checking; use PSScriptAnalyzer ad hoc when linting is needed rather than wiring it into CI speculatively.
Files:
tests/selfapps_hidden_import.ps1
**/*.{py,bat,cmd,ps1,yml,yaml,json}
📄 CodeRabbit inference engine (AGENTS.md)
Run
tools/check_delimiters.pyand preserve its targeted syntax and escaping heuristics; add a heuristic when a real Windows-only bug can be safely detected with zero observed false positives.
Files:
tests/selfapps_hidden_import.ps1
**/*
📄 CodeRabbit inference engine (AGENTS.md)
**/*: Keep repository text ASCII plain text and do not manually change line endings.
Push every commit before it can be lost; do not leave completed commits only in the local repository.
Files:
tests/selfapps_hidden_import.ps1CLAUDE.mddocs/demo-bootstrapper-output.md
**/*.{bat,ps1}
📄 CodeRabbit inference engine (CLAUDE.md)
Use CRLF line endings for
.batand.ps1files; do not edit line endings manually because.gitattributescontrols them.
Files:
tests/selfapps_hidden_import.ps1
**/*.{bat,ps1,py,yml,json}
📄 CodeRabbit inference engine (CLAUDE.md)
Keep supported source and configuration files ASCII-only; avoid emojis, curly quotes, em-dashes, and other non-ASCII characters.
Files:
tests/selfapps_hidden_import.ps1
tests/**/*.ps1
📄 CodeRabbit inference engine (CLAUDE.md)
Place PowerShell scenario tests in
tests/selfapps_<scenario>.ps1and wire new scenarios intotests/harness.ps1and the relevant CI job steps.
Files:
tests/selfapps_hidden_import.ps1
**/*.md
📄 CodeRabbit inference engine (AGENTS.md)
Cite
run_setup.batlocations in documentation by stable label or subroutine name rather than line number.
Files:
CLAUDE.mddocs/demo-bootstrapper-output.md
CLAUDE.md
📄 CodeRabbit inference engine (AGENTS.md)
New Active Backlog items must use bullets with the identifier in prose, not literal ordered-list markers; run the repository's narrow MD029 markdown check.
Files:
CLAUDE.md
🧠 Learnings (2)
📓 Common learnings
Learnt from: CR
Repo: mixmansoundude/Python_vs_Windows
Timestamp: 2026-08-08T09:50:15.548Z
Learning: Run the full mandatory sanity sweep before every commit, including compilation, linting, delimiter checks, YAML and PowerShell parsing, ASCII checks, and pytest.
Learnt from: CR
Repo: mixmansoundude/Python_vs_Windows
Timestamp: 2026-08-08T09:50:15.548Z
Learning: Keep knowledge documents current in the same commit when a change teaches or invalidates a lesson; move fully resolved backlog items to `docs/agent-closed-backlog.md`.
Learnt from: CR
Repo: mixmansoundude/Python_vs_Windows
Timestamp: 2026-08-08T09:50:15.548Z
Learning: Follow the iteration loop: freeze scope, fix CI before tests and product code, verify no false positives, implement exactly one feature slice, and add exactly one missing test per loop.
Learnt from: CR
Repo: mixmansoundude/Python_vs_Windows
Timestamp: 2026-08-08T09:50:15.548Z
Learning: Do not duplicate requirements from `README.md`, `AGENTS.md`, or `CONTRIBUTING.md`; reference those authoritative sources instead.
Learnt from: CR
Repo: mixmansoundude/Python_vs_Windows
Timestamp: 2026-08-08T09:50:15.548Z
Learning: Only `tools/inline_model_fix.py` in the designated CI job may commit automatic fixes; no other agent or CI job may create auto-fix commits.
📚 Learning: 2026-08-01T02:27:53.952Z
Learnt from: mixmansoundude
Repo: mixmansoundude/Python_vs_Windows PR: 408
File: docs/agent-closed-backlog.md:0-0
Timestamp: 2026-08-01T02:27:53.952Z
Learning: In the documentation files describing the removed UNC warning check in `run_setup.bat`, state only verified behavior: the check emitted `[WARN] UNC paths not supported` for an ordinary local path and was removed because the separate UNC-prefix guard already handles UNC detection. Do not assert the exact `findstr` or cmd.exe backslash-parsing mechanism, since it was not independently verified.
Applied to files:
docs/demo-bootstrapper-output.md
🔇 Additional comments (6)
docs/demo-bootstrapper-output.md (2)
3137-3138: Keep the counterfactual recovery log on one line.The previous review comment identified this same issue. The period is now present, but the emitted
:hidden_import_recoverlog line is still split across two documentation lines. Keep the code span on one line so it matchesrun_setup.batexactly.
1374-1393: LGTM!Also applies to: 2784-2784
CLAUDE.md (1)
602-618: LGTM!Also applies to: 630-637
tests/selfapps_hidden_import.ps1 (3)
16-20: LGTM!
100-115: LGTM!
144-157: LGTM!
- CLAUDE.md: describe $hiCollectInject accurately as source-level static proof (a text match against run_setup.bat), not proof it reaches the real command line / runtime argv -- that still needs a real Windows CI run to confirm. - demo doc: keep the Nuitka-skip counterfactual's quoted log line on one source line, matching the single emitted line exactly (the previous fix added the missing period but left the span split across two lines). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01A4iE1BRSkUETwz237XeuTW
…DLL gap (#420) * Close Item 28 (confirmed via real CI), file Item 29 for pyproj DLL gap PR #419's --collect-submodules pairing fix is confirmed working in real CI (cache-lane run 31256064576, on the merge commit): the strict hidden-import gate correctly added --hidden-import=numpy --collect-submodules=numpy, then --hidden-import=pyproj --collect-submodules=pyproj, for a real target never previously observed in this chain -- stronger evidence than reproducing the original packaging.version case verbatim (which this run did not hit). Moved Item 28 to docs/agent-closed-backlog.md as closed. The same run uncovered a new, one-level-deeper blocker: --collect-submodules=pyproj pulled in pyproj's own compiled extensions for the first time, surfacing 8 fresh "Library not found: could not resolve 'proj_9.dll'" build warnings that :dll_bundle_recover never had a chance to react to, since it only runs once, before the first smoke attempt -- before hidden-import recovery ever adds a new package to the build. Filed as CLAUDE.md Active Backlog Item 29. Updated docs/agent-interconnect.md and docs/agent-lessons-learned.md citations to point at Item 28's new closed-backlog location. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01A4iE1BRSkUETwz237XeuTW * Fix proj_9.dll warning count (9, not 8) per CodeRabbit review Both records listed 9 pyproj extension names but said "8 fresh" warnings. Re-verified against the real captured build log: grep -c confirms 9 distinct WARNING lines, one per listed .pyd. Corrected both counts to 9. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01A4iE1BRSkUETwz237XeuTW --------- Co-authored-by: Claude <noreply@anthropic.com>
Summary
Follow-up loop on CLAUDE.md Active Backlog Item 28, implementing the fix direction PR #418's
root-cause investigation recommended.
Item 28's pygrib chain (
self.layered_e2e.chain,cachelane, non-gating) stalled on a 3rd,unfixable hidden-import failure: pygrib's own compiled
_pygrib.pyxdoesfrom packaging import version, needing thepackaging.versionsubmodule even after--hidden-import=packaging(iter 2) already succeeded. A
--hidden-import=Xtarget only guarantees PyInstaller followsX's own statically-discovered imports -- it does not guarantee every real submodule underX/gets bundled.
Fix:
:hidden_import_recovernow composes a second flag accumulator (HP_PYI_HID_COLLECT)alongside the existing
HP_PYI_HIDDEN_IMPORTS. Each loop iteration appends BOTH--hidden-import=%HP_NEXT_HIDDEN%and--collect-submodules=%HP_NEXT_HIDDEN%for the sametarget, and both flag lists reach the same PyInstaller rebuild call. Broader than strictly
necessary (collects every submodule of
X, not just the one actually needed) but structurallysafe --
Xis alreadyfind_spec-confirmed installed by~hidden_import_scan.py's own gate, sothis never targets an unresolvable name and never guesses AT a package the way inferring one from
the failure text would.
This is additive to the existing strict detection gate, not a relaxation of it:
~hidden_import_scan.py'sModuleNotFoundError+ installed-in-build-interpreter gate iscompletely unchanged (see
docs/agent-lessons-learned.md's "must stay STRICT" entry) -- the newflag only changes what happens for a target the gate ALREADY decided to act on.
Log-line format changed:
[REPAIR][HIDDEN_IMPORT] Adding --hidden-import=Xnow readsAdding --hidden-import=X --collect-submodules=X. Traced every existing consumer of that line(
self.exe.hidden_import,self.exe.hidden_import.exhaust's 3-occurrence count,self.layered_e2e.chain'smech3Pass, the Tier A skip-guard's negative check) -- all match itas a prefix substring, so none needed code changes; updated 3 example log lines in the demo doc
that would otherwise go stale.
Test coverage (one new test, per this repo's loop convention): extended
tests/selfapps_hidden_import.ps1withcollectLogged/collectInvokedassertions (checkingboth the log line AND the actual PyInstaller command line, since they're independent statements
that could drift), and
tests/harness.ps1with a static wiring guard for the newaccumulator/append/inject sites.
Not yet CI-confirmed for the actual pygrib chain -- CLAUDE.md's Item 28 entry is updated to
say "implemented, not yet confirmed," mirroring the Item 24 precedent (a fix is documented as
settled only after a real
cache-lane run shows the effect). The nextself.layered_e2e.chainrun should show iteration 2 collecting
packaging.version, letting the chain progress farenough to finally reach colorama's own hidden-import gap.
Test plan
tools/run_sanity_sweep.sh-- all clean, 515 passed / 3 skipped.python tools/check_delimiters.py run_setup.bat-- clean.markdownlint-cli2(not just the sanity sweep's MD029 subset) on all touched docs --clean.
run_setup.bat.Generated by Claude Code