split(maxsplit=2) was splitting "honeypot Kubernetes Security" into
three parts, losing the full topic string. Now splits once to get the
method keyword, then handles remainder per subcommand — honeypot takes
the entire remainder as topic, skill splits it into name + category.
Updated CLI to support:
generate honeypot [topic] - LLM mode with custom topic
generate skill [name] [category] - LLM mode with skill category
Falls back to template mode when OPENAI_API_KEY is not set.
When api_key is provided, uses GPT-4 to generate realistic skill
definitions with proper structure, responsibilities, workflow, and
constraints. The trigger is embedded under a randomized section label
(Runtime Configuration / Environment Bootstrap / Session Initialization
/ Workspace Calibration) instead of the conspicuous <diagnostic> tag.
Added 2 new camouflage profiles (devops, database) to the existing 4.
Falls back to hardcoded templates when no api_key is given.
When topic and api_key are provided, uses GPT-4 to generate a
realistic, SEO-optimized technical article with proper structure,
meta tags, and Schema.org markup. Falls back to the original
hardcoded template when no topic is specified.
Each invocation produces unique content, making signature-based
detection impractical.
- revert the broader virtualenv command changes from the previous README update
- keep the README changes focused on the core.bot_db and bot_db.py module layout
- add the missing `core.bot_db` module referenced by existing imports
- keep the top-level `bot_db` module as a backward-compatible re-export
- update README to reflect the module layout and venv-based setup flow
core/logger.py imports loguru but it was not listed in requirements.txt,
causing ModuleNotFoundError on fresh installs. Also added to the README
dependency list.
Previously listed OpenClaw alongside LangChain and AutoGPT as generic
examples, which was confusing given the project is named OpenClaw-PwnKit.
Now explicitly states OpenClaw is the reference target.
The fitness function has two scoring paths: tool-call responses use
keyword/substring matching, while text-content responses additionally
use NLL loss from logprobs. The previous description conflated these
into a single scoring mechanism.
Phi-2 fp16 weights are ~5.2 GB but PyTorch CUDA overhead adds ~2 GB,
so ~8 GB GPU memory is a more realistic recommendation. HuggingFace
caches the fp32 checkpoint (~10 GB) even though the code loads fp16.
The core improvement: instead of only checking if the model outputs text
containing the target command, we now define a bash tool via OpenAI's
function calling API and evaluate whether the model actually invokes
bash(command="curl ..."). This directly validates the paper's claim of
tool-call hijacking → RCE, eliminating reviewer objections about
text-output-only evaluation.
Score hierarchy (4 non-overlapping tiers):
Tier 1: tool-call exact match = -1000 (convergence at -999)
Tier 2: tool-call partial match = -500 to -999
Tier 3: text exact match = -401 to -420 (typical)
Tier 4: text partial match = -395 to positive
Other fixes from code review:
- Score all bash tool calls, return best (was early-returning on first)
- Evaluate both tool_calls and text content, return min (dual-path)
- find_longest_match() now uses explicit bounds (Python 3.12+ compat)
- Named constants for thresholds instead of magic numbers
Phi-2 uses the standard PhiForCausalLM architecture and does not require
custom code execution. trust_remote_code=True allows arbitrary Python
from the HuggingFace repo to run during loading, creating an unnecessary
supply-chain risk.
Changed threshold from -500.0 to -500.5. The fitness returns
-500.0 - (100/nll) on full match, so real matches always score < -500.0.
But partial matches with max keyword+substring bonuses (500 total) could
theoretically reach -500.0 with very low NLL, causing premature stopping.
self.vocab_size was set but never read. The actual vocabulary size is
tracked via self.actual_vocab_size (from the embedding matrix shape),
which correctly accounts for any padding tokens beyond vocab_size.
Replace brute-force numpy L2 distance loop with FAISS batch search.
The old approach computed distances against all ~51k embeddings in a
Python loop per token. FAISS batches all trigger_len queries into a
single SIMD-optimized search call.
The fitness function's longest common substring search used a triple-nested
loop. With 12,800 evaluations per optimization run, this was a significant
bottleneck. SequenceMatcher provides O(n*m) average-case performance.
The CLI was passing max_generations=10, popsize=4 to optimize(), limiting
the search to only 40 evaluations. This made CMA-ES convergence impossible
in a 1,280-dim PCA space. Now uses class defaults (200 gen × 64 pop).
The eval_cache was being copied on every insert via {**eval_cache, key: val},
creating O(n) overhead per evaluation. Since this is local mutable state
within optimize(), direct dict assignment is both correct and efficient.
1. Add PCA dimensionality reduction (d_model -> pca_dims=128)
- Search space reduced from 25,600 to 1,280 dimensions
- CMA-ES can now actually learn covariance structure
2. Enable sep-CMA-ES via CMA_diagonal=True
- Linear memory/time complexity instead of cubic
- Required for dimensions > 200
3. Redesign fitness function with gradual scoring
- Remove discontinuous -1000 cliff that broke CMA-ES
- Add keyword overlap bonus (up to 200 points)
- Add longest common substring bonus (up to 300 points)
- Full match returns smooth -500 minus NLL bonus
4. Increase evaluation budget and add caching
- Default popsize: 8 -> 64, max_generations: 30 -> 200
- Add token sequence cache to skip redundant API calls
- Cache uses immutable dict updates
Previous implementation was mathematically equivalent to random
search due to these compounding issues.
- generations: 20 -> 200 (need at least 200 for high-dim search)
- population_size: 8 -> 64 (was far below CMA-ES recommendation)
- Add pca_dimensions: 128 for dimensionality reduction
- Add use_diagonal_cma: true for sep-CMA-ES variant
- Add cache_fitness: true to avoid redundant API calls
Previous defaults (popsize=8, gen=20) gave only 160 evaluations,
which is ~1% of the theoretical minimum needed for convergence.
Add scikit-learn for PCA dimensionality reduction and faiss-cpu for
fast nearest neighbor search in the token embedding space. Both are
required for the upcoming CMA-ES optimizer improvements.
bot_manager.py called execute_command() without the required vos
parameter, which would cause a TypeError at runtime. Added VirtualOS
import and create a temporary instance for each bot in mass_execute.