skills/code-analysis/module-level-code-translator/SKILL.md
Translates an entire module or package between languages, handling imports, file layout, visibility, and cross-function dependencies that single-function translation misses. Use when porting a library, when a migration spans multiple files, or when the user hands you a directory and a target language.
npx skillsauth add santosomar/general-secure-coding-agent-skills module-level-code-translatorInstall 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.
Single-function translation (→ code-translation) is clean. Module translation is messy: imports, circular deps, visibility, file boundaries, and the build system all get involved. This is about the glue.
| Concern | Why it matters |
| ------------------------ | --------------------------------------------------------------------------- |
| Import/export structure | Python __init__.py ≠ Java package ≠ Go package ≠ Rust mod. What's public? |
| File ↔ unit mapping | Java: one public class per file. Python: anything goes. Go: package = dir. |
| Circular imports | Python tolerates them at runtime. Go/Rust don't compile. Java barely does. |
| Visibility | Python _private convention. Java private/package/protected/public. Go capitalization. Rust pub/pub(crate). |
| Module-level state | Python module-level vars are singletons. Java needs a class. Go var. Rust static/lazy_static. |
| Build integration | setup.py/pyproject.toml → pom.xml/build.gradle → go.mod → Cargo.toml |
Before translating anything, map out what depends on what within the module:
util.py ──────────┐
│ ▼
└──────► parser.py ──► api.py
▲ │
config.py ───────┘ │
▼
__init__.py (re-exports)
This tells you:
util, config), then dependents.parser imports api and vice versa — break the cycle first, it won't compile in Go/Rust.__init__.py exports is your API contract. Everything else can be restructured freely.Don't mirror the source layout blindly — match the target language's conventions:
| Source (Python) | Java | Go | Rust |
| ------------------------- | --------------------------------------- | ----------------------------------- | --------------------------------- |
| mymod/__init__.py | Package com.x.mymod (no file) | Package mymod (dir) | mymod/mod.rs or mymod/lib.rs |
| mymod/util.py (5 funcs) | 5 files? Or one Util.java static class| util.go in package mymod | util.rs as mod util |
| mymod/_internal.py | Package-private classes | Lowercase names (unexported) | No pub — crate-private |
| Module-level CACHE = {} | Static field in a class | Package-level var cache = ... | static CACHE: Lazy<...> = ... |
In Go: everything in one directory is one package. Your five Python files might become five .go files — but they all share one namespace. No import between them.
In Java: one public class per file is enforced. Multi-class Python files split.
Walk the dep graph bottom-up. For each file:
code-translation.Function-level tests pass. Now test cross-function behavior:
init(). Different timing.B now returns error instead of raising, every A-calls-B site changed.→ test-guided-migration-assistant if you have tests for the original: they become the oracle.
Source structure:
retry/
__init__.py # from .policy import *; from .backoff import exponential
policy.py # class RetryPolicy; uses backoff
backoff.py # def exponential(n), def linear(n)
Dep graph: backoff (leaf) ← policy ← __init__.
Target Go layout:
retry/
backoff.go # Exponential(n), linear(n) — linear unexported
policy.go # RetryPolicy struct + methods
retry.go # package doc comment — no re-exports needed (one package)
All three files are package retry. No imports between them — they share a namespace. linear becomes lowercase linear (was only used by policy, not in __init__'s public exports). exponential → Exponential (exported).
Gotcha found during translation: RetryPolicy.__init__ takes backoff=exponential — a function default arg. Go has no default args. Options: zero-value meaning "use exponential," or functional options pattern. Chose zero-value — simpler, matches RetryPolicy{} idiom.
_foo in Python is convention; in Go, lowercase is enforced. Decide what's actually API.## Source → target
<src lang/version> → <target lang/version>
## Dependency graph
<ascii or list — who imports whom>
## File layout mapping
| Source file | Target file(s) | Notes |
| ----------- | -------------- | ----- |
## Public API (preserved)
<what callers see — unchanged>
## Internal restructuring
<what moved/renamed internally, and why>
## Per-file translation
### <file>
<code>
Deltas: <semantic notes>
## Integration checklist
- [ ] Builds
- [ ] Cross-function tests pass
- [ ] Init order verified
development
Extracts human-readable pseudocode from a verified formal artifact (Dafny, Lean, TLA+) while preserving the verified properties as annotations, so the proof-carrying logic can be reimplemented in a production language. Use when porting verified code to an unverified target, when documenting what a formal spec actually does, or when handing a verified algorithm to an implementer.
development
Translates natural-language or pseudocode descriptions of concurrent and distributed systems into TLA+ specifications ready for the TLC model checker. Identifies state variables, actions, type invariants, safety properties, and liveness properties from the description. Use when formalizing a protocol, when the user describes a distributed algorithm to verify, when designing a consensus or locking scheme, or when starting formal verification of a concurrent system.
testing
Reduces a TLA+ model so TLC can actually check it — shrinks constants, adds state constraints, abstracts data, or applies symmetry — when the state space is too large to enumerate. Use when TLC runs out of memory, when checking takes hours, or when a spec works at N=2 and you need confidence at larger scale.
development
TLA+-specific instance of model-guided repair — reads a TLC error trace, identifies the enabling condition that should have been false, strengthens the corresponding action, and maps the fix to source code. Use when TLC reports an invariant violation or deadlock and you have the code-to-TLA+ mapping from extraction.