Issue #19 (CWE-C-312): AgentskillsAdaptor.install() passed the full
os.environ to the subprocess running setup.sh, including
ANTHROPIC_API_KEY, OPENAI_API_KEY, GITHUB_TOKEN, WORKSPACE_AUTH_TOKEN,
etc. A malicious or compromised plugin's setup.sh could exfiltrate them.
Fix: _scrubbed_env() builds a copy of os.environ with sensitive keys
removed, matching the same _SCRUB_KEYS list used in skill_loader/loader.py
so the scrubbing policy is consistent. CONFIGS_DIR is still passed via
the extra dict. Non-secret vars (PATH, HOME, etc.) are preserved.
Add 6 regression tests (30/30 passing).
Co-Authored-By: Infra-Runtime-BE <infra-runtime-be@molecule.ai>
The TRUE root cause of recurring CRLF: shutil.copy2() in
_copy_dir_files() copies hook files byte-for-byte from /plugins/
(mounted from Windows host) into /configs/.claude/hooks/. Windows
git checkout introduces \r\n regardless of .gitattributes.
Previous fixes were band-aids:
- .gitattributes eol=lf (only works for files IN git, not host disk)
- entrypoint.sh sed strip (runs at boot but after plugin install)
- provisioner CopyTemplateToContainer strip (wrong code path — hooks
come through the Python plugin installer, not the Go template copier)
This fix strips CRLF at the single point where ALL plugin hooks enter
a container: _copy_dir_files() in builtins.py. read_bytes() + replace
+ write_bytes for .sh/.py files. Other file types pass through unchanged.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Extracts shared workspace runtime from molecule-monorepo/workspace-template
into a publishable PyPI package.
- molecule_runtime/ package with all shared infrastructure modules
- Adapter discovery via ADAPTER_MODULE env var (standalone repos) + built-in scan
- molecule-runtime console script entry point (main_sync)
- CI workflow to publish on version tags
- Published to PyPI as molecule-ai-workspace-runtime==0.1.0
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>