mirror of
https://github.com/alirezarezvani/claude-skills.git
synced 2026-08-28 04:24:58 +00:00
Addresses the second automated review on PR #941. All three code findings verified against the actual behaviour, not just patched. [Medium] shutil.copytree dereferenced symlinks the validator never saw. The validator checks SKILL.md, the three supporting files and chapters/*.md; the copy then followed a link anywhere else in the tree (assets/, any subdirectory) and baked the target's real content into a package that can go out as --distribution shareable. _assert_no_symlinks() now walks the whole tree and refuses, and runs BEFORE the validation branch so --skip-validation cannot bypass it. copytree also passes symlinks=True so loosening that check later cannot silently reintroduce dereferencing. Verified: a symlink in assets/ pointing at a secret file is refused both with and without --skip-validation, the secret never lands in a package, and a clean tree still emits. [Medium] The DOCX XXE/entity guard did not extend to EPUB's ebooklib path. Upstream hardened DOCX only. EPUB is the same zip-of-XML shape and ebooklib — one of the packages this skill recommends installing — parsed container.xml, the OPF and content docs with no equivalent pre-check. The guard moved to a new book_to_skill/zip_safety.py and now runs for both formats. Verified: an EPUB whose OPF declares an entity is refused; a clean EPUB still extracts and detects its chapter. [Low] No size cap before decompressing zip members. Every archive read now goes through safe_read(), which checks the declared uncompressed size and the compression ratio against the central directory before decompressing, and charges actual bytes against a per-archive budget so a lying directory cannot get past it either. Verified: a 200 MB / 1029x bomb is refused at ~14 MB peak RSS instead of being materialized. [Low] The PR body's "12 numbered items" was stale against README's list. Fixed in the PR description; the in-repo count is synced to 18 across plugin.json, CLAUDE.md and CHANGELOG. Recorded as deviations 17 and 18. Counters: tools 662 -> 663 (zip_safety.py); that module is allowlisted in smoke_exceptions.txt like its siblings. All gates green: compileall, check_paths --all, check_dual_publish, smoke_scripts (0 failed), derive_counters --check, check_plugin_json --all (0 FAIL). Security auditor unchanged at 0 critical / 4 high. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017zu9Gmm9S78c2t3kDLnpPX
91 lines
7 KiB
Text
91 lines
7 KiB
Text
# By-design exceptions for scripts/smoke_scripts.py (gate G8).
|
|
# Format: <path relative to repo root> # reason
|
|
# These scripts intentionally do not implement a CLI `--help` contract.
|
|
|
|
# Fixed-contract evaluators: argv contract is fixed by engineering/autoresearch-agent
|
|
# (called as `evaluator.py <target-file>`; exit code IS the metric channel).
|
|
engineering/autoresearch-agent/evaluators/benchmark_size.py # fixed-contract autoresearch evaluator
|
|
engineering/autoresearch-agent/evaluators/benchmark_speed.py # fixed-contract autoresearch evaluator
|
|
engineering/autoresearch-agent/evaluators/build_speed.py # fixed-contract autoresearch evaluator
|
|
engineering/autoresearch-agent/evaluators/llm_judge_content.py # fixed-contract autoresearch evaluator
|
|
engineering/autoresearch-agent/evaluators/llm_judge_copy.py # fixed-contract autoresearch evaluator
|
|
engineering/autoresearch-agent/evaluators/llm_judge_prompt.py # fixed-contract autoresearch evaluator
|
|
engineering/autoresearch-agent/evaluators/memory_usage.py # fixed-contract autoresearch evaluator
|
|
engineering/autoresearch-agent/evaluators/test_pass_rate.py # fixed-contract autoresearch evaluator
|
|
|
|
# Claude Code hooks: invoked by the hook runner with a JSON payload on stdin,
|
|
# not as CLI tools (exit 2 is a signaling channel for PreToolUse).
|
|
engineering/security-guidance/hooks/security_reminder_hook.py # PreToolUse stdin hook
|
|
productivity/handoff/hooks/session_start.py # SessionStart stdin hook
|
|
productivity/handoff/hooks/session_end.py # SessionEnd stdin hook
|
|
|
|
# skillopt_sleep engine (engineering/skillopt-sleep, vendored from
|
|
# microsoft/SkillOpt): internal package modules, not standalone CLI scripts.
|
|
# The real entry point is `python -m skillopt_sleep` (verified: exits 0 on
|
|
# --help). Running any single file directly breaks two ways: (1)
|
|
# skillopt_sleep/types.py shadows the stdlib `types` module once the file's
|
|
# own directory is prepended to sys.path, which cascades into
|
|
# "cannot import name 'GenericAlias'/'asdict' from partially initialized
|
|
# module" for every sibling that (transitively) imports dataclasses/typing;
|
|
# (2) experiments/*.py use absolute `from skillopt_sleep.x import y` imports
|
|
# that require the package's parent dir on sys.path, which standalone
|
|
# execution doesn't provide.
|
|
engineering/skillopt-sleep/skillopt_sleep/__main__.py # python -m skillopt_sleep entry point only
|
|
engineering/skillopt-sleep/skillopt_sleep/backend.py # internal module, types.py shadow
|
|
engineering/skillopt-sleep/skillopt_sleep/budget.py # internal module, types.py shadow
|
|
engineering/skillopt-sleep/skillopt_sleep/config.py # internal module, types.py shadow
|
|
engineering/skillopt-sleep/skillopt_sleep/consolidate.py # internal module, types.py shadow
|
|
engineering/skillopt-sleep/skillopt_sleep/cycle.py # internal module, types.py shadow
|
|
engineering/skillopt-sleep/skillopt_sleep/dream.py # internal module, types.py shadow
|
|
engineering/skillopt-sleep/skillopt_sleep/experiments/gbrain_bench.py # requires skillopt_sleep on sys.path
|
|
engineering/skillopt-sleep/skillopt_sleep/experiments/personas.py # requires skillopt_sleep on sys.path
|
|
engineering/skillopt-sleep/skillopt_sleep/experiments/run_experiment.py # requires skillopt_sleep on sys.path
|
|
engineering/skillopt-sleep/skillopt_sleep/experiments/run_gbrain.py # requires skillopt_sleep on sys.path
|
|
engineering/skillopt-sleep/skillopt_sleep/experiments/run_transfer.py # requires skillopt_sleep on sys.path
|
|
engineering/skillopt-sleep/skillopt_sleep/experiments/sweep.py # requires skillopt_sleep on sys.path
|
|
engineering/skillopt-sleep/skillopt_sleep/gate.py # internal module, types.py shadow
|
|
engineering/skillopt-sleep/skillopt_sleep/harvest.py # internal module, types.py shadow
|
|
engineering/skillopt-sleep/skillopt_sleep/harvest_codex.py # internal module, types.py shadow
|
|
engineering/skillopt-sleep/skillopt_sleep/harvest_sources.py # internal module, types.py shadow
|
|
engineering/skillopt-sleep/skillopt_sleep/judges.py # internal module, types.py shadow
|
|
engineering/skillopt-sleep/skillopt_sleep/llm_miner.py # internal module, types.py shadow
|
|
engineering/skillopt-sleep/skillopt_sleep/memory.py # internal module, types.py shadow
|
|
engineering/skillopt-sleep/skillopt_sleep/mine.py # internal module, types.py shadow
|
|
engineering/skillopt-sleep/skillopt_sleep/replay.py # internal module, types.py shadow
|
|
engineering/skillopt-sleep/skillopt_sleep/rollout.py # internal module, types.py shadow
|
|
engineering/skillopt-sleep/skillopt_sleep/scheduler.py # internal module, types.py shadow
|
|
engineering/skillopt-sleep/skillopt_sleep/slow_update.py # internal module, types.py shadow
|
|
engineering/skillopt-sleep/skillopt_sleep/staging.py # internal module, types.py shadow
|
|
engineering/skillopt-sleep/skillopt_sleep/state.py # internal module, types.py shadow
|
|
engineering/skillopt-sleep/skillopt_sleep/tasks_file.py # internal module, types.py shadow
|
|
engineering/skillopt-sleep/skillopt_sleep/types.py # internal module; module itself IS the stdlib-name collision
|
|
|
|
# book_to_skill extraction library (engineering/book-to-skill, vendored from
|
|
# virgiliojr94/book-to-skill): internal package modules imported as
|
|
# `book_to_skill.*`, not standalone CLI scripts.
|
|
#
|
|
# Listed here are the modules that FAIL the G8 probe — those with absolute
|
|
# `book_to_skill.*` imports, which raise `No module named 'book_to_skill'` before
|
|
# they could parse a flag. The package's remaining modules (config.py,
|
|
# exceptions.py, sanitize.py, parsers/__init__.py, parsers/pdf.py,
|
|
# parsers/text.py) are equally not-CLIs; they pass G8 only because they have no
|
|
# argv handling at all, so `--help` no-ops and exits 0. This list is therefore
|
|
# "modules the probe trips on", not "modules that aren't CLIs" — the latter is
|
|
# the whole package.
|
|
#
|
|
# The four real entry points DO implement the CLI contract and are smoke-tested
|
|
# normally:
|
|
# scripts/extract_document.py, book_skill_validator.py,
|
|
# token_budget_estimator.py, skill_plugin_emitter.py (--help + --sample, exit 0)
|
|
# Unlike the skillopt_sleep case below, no module here shadows a stdlib name:
|
|
# upstream's parsers/html.py was renamed to parsers/html_text.py precisely so
|
|
# `import html.parser` cannot resolve to a sibling.
|
|
engineering/book-to-skill/skills/book-to-skill/scripts/book_to_skill/__init__.py # package init, not a CLI
|
|
engineering/book-to-skill/skills/book-to-skill/scripts/book_to_skill/dependencies.py # internal module
|
|
engineering/book-to-skill/skills/book-to-skill/scripts/book_to_skill/utils.py # internal module
|
|
engineering/book-to-skill/skills/book-to-skill/scripts/book_to_skill/zip_safety.py # internal module
|
|
engineering/book-to-skill/skills/book-to-skill/scripts/book_to_skill/parsers/calibre.py # internal module
|
|
engineering/book-to-skill/skills/book-to-skill/scripts/book_to_skill/parsers/docx.py # internal module
|
|
engineering/book-to-skill/skills/book-to-skill/scripts/book_to_skill/parsers/epub.py # internal module
|
|
engineering/book-to-skill/skills/book-to-skill/scripts/book_to_skill/parsers/html_text.py # internal module
|
|
engineering/book-to-skill/skills/book-to-skill/scripts/book_to_skill/parsers/rtf.py # internal module
|