--- name: source-analysis description: Layer 1 skill for source code analysis — decompose any codebase into analyzable units, extract behavioral claims with provenance. Supports three target shapes (source tree, bundle, decompiled binary), with per-language grep patterns and analysis templates. --- # Source Analysis Methodology Extract behavioral intelligence from source code. Decompose the codebase into analyzable units, then systematically analyze each unit for behavioral claims with full provenance. ## When to Use This Mode Source analysis activates when: - The discovery inventory identifies source code files at the target path - Any source code needs behavioral analysis (any language, bundled or not) - Decompiled output exists at `workspace/raw/source/decompiled/` ## General Approach Source analysis takes three shapes depending on what the target looks like: - **Source tree** — a repository with a package manifest and conventional directory layout (Python, Rust, Go, Swift, Java, Node/TS, C++, etc.). Follow the **Source Tree Pipeline** below. - **Bundle** — a single-file minified or packed artifact (JavaScript bundle, Electron asar, webpack/esbuild output). Follow the **Bundle Pipeline** below. - **Decompiled binary** — a compiled artifact where source isn't directly available. Decompile first via the **Decompilation Path**, then analyze the decompiled output using whichever of the above shapes fits. Regardless of shape, the pipeline follows the same logical steps: 1. **Assess the source.** What language? How is it organized? How large is it? 2. **Decompose into analyzable units.** Use the language's natural boundaries (modules, packages, files) when they exist. Split bundled artifacts into chunks when they don't. 3. **Analyze each unit exhaustively.** Read every line. Identify every function, method, class. Understand what each does behaviorally. 4. **Extract behavioral specifications.** Write what the code DOES (observable behavior), not how it's structured (implementation details). Every claim gets a provenance citation. Phases 6-8 (per-unit analysis, per-function deep analysis, targeted extraction) are shape-agnostic and apply to all three paths. ## Decompilation Path When source code isn't directly available, decompile binaries into structured source before analysis. ### Language-Specific Decompilation Tools | Language/Platform | Tools | Notes | |-------------------|-------|-------| | JVM (Java, Kotlin) | cfr, procyon, fernflower | cfr is standalone JAR; fernflower is IntelliJ's built-in decompiler | | .NET (C#, F#) | ilspy, dotPeek CLI | ilspy has a command-line mode suitable for automation | | Python (.pyc, .pyo) | uncompyle6, decompyle3 | decompyle3 targets Python 3.7+; uncompyle6 covers older versions | | JavaScript (bundled/obfuscated) | js-beautify | Also covered by the Bundle Pipeline below | | Native (x86, ARM, etc.) | ghidra headless, radare2 | Produces pseudocode, not true source; useful for behavioral extraction but lower fidelity | ### Process 1. **Identify binary type.** Determine the platform and format (JAR, DLL, .pyc, ELF, Mach-O, etc.). 2. **Check tool availability.** Verify the appropriate decompiler is installed and accessible. If tools are unavailable, warn and fall back to binary analysis (strings, symbols, imports/exports). 3. **Decompile to workspace.** Output decompiled source to `workspace/raw/source/decompiled/`. Preserve directory structure from the binary where possible (e.g., Java package paths). 4. **Treat decompiled output as structured source.** Once decompiled, analyze using the same General Approach above — each decompiled file is an analyzable unit. ```bash mkdir -p workspace/raw/source/decompiled # Example: JVM with cfr java -jar cfr.jar target.jar --outputdir workspace/raw/source/decompiled/ # Example: Python with uncompyle6 uncompyle6 -o workspace/raw/source/decompiled/ target.pyc # Example: .NET with ilspy ilspycmd target.dll -o workspace/raw/source/decompiled/ # Example: Native with Ghidra headless analyzeHeadless /tmp/ghidra_project proj -import target.bin -postScript ExportDecompiled.java workspace/raw/source/decompiled/ ``` ### Quality Notes Decompiled code differs from original source in predictable ways: - **Variable and parameter names are lost.** Decompilers generate synthetic names (e.g., `var1`, `a0`). Focus on behavioral patterns, not identifier semantics. - **Comments are lost.** All inline documentation is gone. Rely on string constants, API calls, and control flow for behavioral understanding. - **Control flow may be less readable.** Optimized bytecode can decompile into awkward `goto`-style structures or deeply nested conditionals. These limitations are acceptable for behavioral extraction. The goal is to understand what the code does, not to recover the original source. ## Source Tree Pipeline Source tree analysis is the common path for Python, Rust, Go, Swift, Java, C++, and similar languages that ship as a repository rather than a single compiled artifact. The target is a directory with a package manifest and a conventional source layout. The Source Tree Pipeline defines Phases ST1-ST3 (survey, enumeration, and unit preparation). After ST3, control flows into the shape-neutral Phases 6-8 shared with the Bundle Pipeline. ```dot digraph source_tree_analysis { rankdir=TB; "Start (source tree)" [shape=doublecircle]; "Phase ST1: Manifest discovery" [shape=box]; "Phase ST2: Module enumeration" [shape=box]; "Phase ST3: Prepare for per-unit analysis" [shape=box]; "→ Phase 6 (shape-neutral)" [shape=box, style=filled, fillcolor="#f0f0f0"]; "Start (source tree)" -> "Phase ST1: Manifest discovery"; "Phase ST1: Manifest discovery" -> "Phase ST2: Module enumeration"; "Phase ST2: Module enumeration" -> "Phase ST3: Prepare for per-unit analysis"; "Phase ST3: Prepare for per-unit analysis" -> "→ Phase 6 (shape-neutral)"; } ``` ### Phase ST1: Manifest Discovery Identify the package manifest and read it. The manifest names the package, declares dependencies, and lists the source roots. | Language | Manifest | Source roots | |----------|----------|--------------| | Python | `pyproject.toml`, `setup.py`, `setup.cfg` | `src/`, `/`, or top-level modules | | Rust | `Cargo.toml` (+ workspace `Cargo.toml`) | `src/`, each crate's `src/` | | Go | `go.mod` | Module root and every directory with `.go` files | | Swift | `Package.swift`, `*.xcodeproj/project.pbxproj` | `Sources//` per target | | Java/Kotlin | `pom.xml`, `build.gradle`, `build.gradle.kts` | `src/main/java/`, `src/main/kotlin/` | | C#/F# | `*.csproj`, `*.fsproj` | project-relative source directories | | C/C++ | `CMakeLists.txt`, `Makefile`, `meson.build` | varies; often `src/` and `include/` | | Node (non-bundled) | `package.json` | `src/`, `lib/`, `index.js` | Write the survey to `workspace/raw/source/analysis/survey.md`: ```markdown # Source Tree Survey **Language:** **Manifest:** **Package name:** **Source roots:** **Dependency count:** **Line count by language:** ``` ### Phase ST2: Module Enumeration Walk the source roots and produce a module list. A "module" in this pipeline is whatever the language's natural unit of organization is — a Python package, a Rust module/crate, a Go package, a Swift target, a Java package. Don't invent your own boundaries; use the language's. ```bash # Python: every directory with __init__.py plus every top-level .py file find -name '__init__.py' -exec dirname {} \; find -maxdepth 1 -name '*.py' -not -name '__init__.py' # Rust: every directory with a mod.rs or every file in src/ find /src -name '*.rs' # Go: every directory with at least one .go file find -name '*.go' -exec dirname {} \; | sort -u # Swift: every directory under Sources/ find Sources -mindepth 2 -maxdepth 2 -type d # Java/Kotlin: every directory with .java or .kt files find src/main -name '*.java' -o -name '*.kt' -exec dirname {} \; | sort -u ``` Write the module inventory to `workspace/raw/source/manifests/module-manifest.json`: ```json { "modules": [ {"path": "src/parser", "files": 7, "lines": 1240, "language": "rust"}, {"path": "src/http", "files": 4, "lines": 680, "language": "rust"} ] } ``` ### Phase ST3: Prepare for Per-Unit Analysis Once Phases ST1-ST2 have produced the survey and module manifest, each module is ready to be treated as the analyzable unit for the shape-neutral Phase 6. The analysis unit differs by target shape: in a bundle, the unit is a chunk from the bundle-splitter; in a source tree, it's a module as the language defines it. Both produce the same per-unit output format. Phases 6-8 (Per-Unit Analysis, Per-Function Deep Analysis, Targeted Extraction), described later in this skill, apply from here on. --- ## Bundle Pipeline The Bundle Pipeline defines Phases B1-B5 (bundle-specific decomposition). After B5, control flows into the shape-neutral Phases 6-8 shared with the Source Tree Pipeline. ```dot digraph bundle_pipeline { rankdir=TB; "Start (bundle target)" [shape=doublecircle]; "Phase B1: Beautify bundle" [shape=box]; "Phase B2: Find module boundaries" [shape=box]; "Phase B3: Extract chunks" [shape=box]; "Phase B4: Extract functions" [shape=box]; "Phase B5: Extract strings" [shape=box]; "→ Phase 6 (shape-neutral)" [shape=box, style=filled, fillcolor="#f0f0f0"]; "Start (bundle target)" -> "Phase B1: Beautify bundle"; "Phase B1: Beautify bundle" -> "Phase B2: Find module boundaries"; "Phase B2: Find module boundaries" -> "Phase B3: Extract chunks"; "Phase B3: Extract chunks" -> "Phase B4: Extract functions"; "Phase B4: Extract functions" -> "Phase B5: Extract strings"; "Phase B5: Extract strings" -> "→ Phase 6 (shape-neutral)"; } ``` Phases B1-B5 are bundle decomposition infrastructure (bundle-splitter). Phases 6-7 produce behavioral analysis (chunk-analyzer, function-analyzer) and are shape-neutral. Phase 8 is optional targeted extraction (targeted-extractor). For non-bundled targets, run the Source Tree Pipeline's Phases ST1-ST3 instead of this section's B1-B5, then flow into the same shape-neutral Phases 6-8. ## Phase B1: Bundle Preparation ### 1.1 Beautify if Needed Check if the bundle is minified by comparing line count to byte count. A file with few lines but many bytes is minified. ```bash LINE_COUNT=$(wc -l < "$BUNDLE") BYTE_COUNT=$(wc -c < "$BUNDLE") if [ "$LINE_COUNT" -lt 100 ] && [ "$BYTE_COUNT" -gt 100000 ]; then echo "Minified - needs beautification" mkdir -p workspace/raw/source BEAUTIFIED="workspace/raw/source/target.js" if [ ! -f "$BEAUTIFIED" ]; then npx js-beautify --type js -f "$BUNDLE" -o "$BEAUTIFIED" fi TARGET="$BEAUTIFIED" else TARGET="$BUNDLE" fi ``` Always check for an existing beautified version before re-beautifying. Multiple agents may operate on the same bundle. ### 1.2 Initial Survey ```bash # Size and line count ls -lh "$TARGET" wc -l "$TARGET" # Detect bundler type head -100 "$TARGET" > workspace/raw/source/analysis/bundle-header.txt grep -m1 "webpack\|esbuild\|rollup\|parcel" "$TARGET" || echo "Unknown bundler" ``` Write the survey to `workspace/raw/source/analysis/survey.md`. ## Phase B2: Find Module Boundaries ### 2.1 Bundler-Specific Markers #### Webpack ```bash # Module ID markers grep -n "^/\*\*\*\*\*\*/ \"" "$TARGET" > manifests/webpack-modules.txt # Export declarations grep -n "__webpack_require__\.d\|__webpack_exports__" "$TARGET" | head -100 > manifests/webpack-exports.txt ``` #### esbuild ```bash # esbuild source comments grep -n "^// " "$TARGET" | grep -v "^// $" > manifests/esbuild-markers.txt ``` #### Generic IIFE Boundaries ```bash # Function expression boundaries grep -n "^(function\|^!function\|^var [a-z]* = function" "$TARGET" > manifests/iife-boundaries.txt ``` ### 2.2 Heuristic Boundaries When no bundler-specific markers are found, fall back to heuristics: ```bash # Long comment separators grep -n "^/\*\*\*\*\*\*\*\*" "$TARGET" > manifests/separator-comments.txt # Export clusters grep -n "^exports\.\|^module\.exports" "$TARGET" > manifests/export-points.txt # Large gaps (blank lines often separate modules) awk 'NF==0 {if(++blank>=3) print NR": --- blank section ---"} NF>0 {blank=0}' "$TARGET" | head -100 ``` ## Phase B3: Extract Chunks ### 3.1 Split by Module Markers ```bash mkdir -p workspace/raw/source/chunks # Webpack-style split csplit -f workspace/raw/source/chunks/chunk- -n 4 "$TARGET" '/^\/\*\*\*\*\*\*\//' '{*}' 2>/dev/null # Fall back to line-count splitting if no clear markers if [ $(ls workspace/raw/source/chunks/ | wc -l) -lt 5 ]; then rm workspace/raw/source/chunks/* split -l 2000 "$TARGET" workspace/raw/source/chunks/chunk- fi # Rename to .js for f in workspace/raw/source/chunks/chunk-*; do [ "${f%.js}" = "$f" ] && mv "$f" "${f}.js" done ``` ### 3.2 Generate Chunk Manifest ```bash echo '{"chunks": [' > workspace/raw/source/manifests/chunk-manifest.json for chunk in workspace/raw/source/chunks/*.js; do name=$(basename "$chunk") lines=$(wc -l < "$chunk") size=$(wc -c < "$chunk") # Extract first meaningful identifier first_func=$(grep -oP "function [a-zA-Z_][a-zA-Z0-9_]*" "$chunk" | head -1) first_class=$(grep -oP "class [a-zA-Z_][a-zA-Z0-9_]*" "$chunk" | head -1) echo " {\"file\": \"$name\", \"lines\": $lines, \"bytes\": $size, \"first_func\": \"$first_func\", \"first_class\": \"$first_class\"}," done >> workspace/raw/source/manifests/chunk-manifest.json echo ']}' >> workspace/raw/source/manifests/chunk-manifest.json ``` ## Phase B4: Extract Functions ### 4.1 Find Function Definitions ```bash mkdir -p workspace/raw/source/functions # Named functions grep -n "function [a-zA-Z_][a-zA-Z0-9_]*\s*(" "$TARGET" > workspace/raw/source/manifests/function-locations.txt # Arrow function assignments grep -n "const [a-zA-Z_][a-zA-Z0-9_]* = (" "$TARGET" >> workspace/raw/source/manifests/function-locations.txt grep -n "const [a-zA-Z_][a-zA-Z0-9_]* = async" "$TARGET" >> workspace/raw/source/manifests/function-locations.txt ``` ### 4.2 Extract Individual Functions Extract each significant function (more than 10 lines) to its own file: ```bash cat > /tmp/extract_funcs.js << 'EOF' const fs = require('fs'); const code = fs.readFileSync(process.argv[2], 'utf8'); const funcPattern = /function\s+([a-zA-Z_][a-zA-Z0-9_]*)\s*\([^)]*\)\s*\{/g; let match; let funcId = 0; const outDir = process.argv[3] || 'workspace/raw/source/functions'; while ((match = funcPattern.exec(code)) !== null) { const name = match[1]; const start = match.index; let depth = 1; let i = code.indexOf('{', start) + 1; while (depth > 0 && i < code.length) { if (code[i] === '{') depth++; if (code[i] === '}') depth--; i++; } const funcCode = code.slice(start, i); if (funcCode.split('\n').length > 10) { fs.writeFileSync( `${outDir}/func-${String(funcId++).padStart(4, '0')}-${name}.js`, funcCode ); } } EOF node /tmp/extract_funcs.js "$TARGET" workspace/raw/source/functions ``` ### 4.3 Generate Function Manifest ```bash echo '{"functions": [' > workspace/raw/source/manifests/function-manifest.json for func in workspace/raw/source/functions/*.js; do name=$(basename "$func" .js) lines=$(wc -l < "$func") params=$(grep -oP "function[^(]*\([^)]*\)" "$func" | head -1) echo " {\"file\": \"$name\", \"lines\": $lines, \"signature\": \"$params\"}," done >> workspace/raw/source/manifests/function-manifest.json echo ']}' >> workspace/raw/source/manifests/function-manifest.json ``` ## Phase B5: String Extraction ### 5.1 Catalog All Strings ```bash mkdir -p workspace/raw/source/manifests # Extract all strings with line numbers (minimum 5 chars) grep -noP '"[^"]{5,}"' "$TARGET" > workspace/raw/source/manifests/strings-raw.txt # Categorize grep -P '"https?://' workspace/raw/source/manifests/strings-raw.txt > workspace/raw/source/manifests/strings-urls.txt grep -P '"[A-Z][A-Z_]{3,}"' workspace/raw/source/manifests/strings-raw.txt > workspace/raw/source/manifests/strings-constants.txt grep -P '"--[a-z]' workspace/raw/source/manifests/strings-raw.txt > workspace/raw/source/manifests/strings-cli-flags.txt grep -P '"Error|Failed|Warning' workspace/raw/source/manifests/strings-raw.txt > workspace/raw/source/manifests/strings-errors.txt ``` ### 5.2 Map Strings to Chunks ```bash echo '{"string_locations": [' > workspace/raw/source/manifests/string-manifest.json for chunk in workspace/raw/source/chunks/*.js; do name=$(basename "$chunk") echo " {\"chunk\": \"$name\", \"strings\": [" >> workspace/raw/source/manifests/string-manifest.json grep -oP '"[^"]{10,}"' "$chunk" | head -20 | while read str; do echo " $str," >> workspace/raw/source/manifests/string-manifest.json done echo " ]}," >> workspace/raw/source/manifests/string-manifest.json done echo ']}' >> workspace/raw/source/manifests/string-manifest.json ``` ## Phase 6: Per-Unit Analysis (all source shapes) The chunk-analyzer agent runs once per analyzable unit. What counts as a "unit" depends on target shape: - **Bundle target:** a chunk file from Phase 3, e.g. `workspace/raw/source/chunks/chunk-0042.js` - **Source tree:** a source file or small module from Phase 3, e.g. `src/parser/lexer.py` or `src/http/handler.go` - **Decompiled binary:** a decompiled source file from the Decompilation Path `$UNIT` in the examples below is the path to the unit being analyzed. Grep patterns use conventions common in several languages; adjust to the target language's idioms. ### Exhaustive Reading Requirement (CRITICAL) **You MUST read every single line of the unit. No exceptions.** - Do NOT skim. Do NOT skip sections that "look like boilerplate." - The grep patterns below are for INDEXING, not for UNDERSTANDING. - After running greps, you MUST read the full unit file. - Every routine (function, method, class) must be identified and catalogued. - Every line must be accounted for. **Verification checklist before writing analysis:** - [ ] I read the ENTIRE unit, not just samples - [ ] I identified EVERY function/method/class in the unit - [ ] I understand what EVERY section of code does ### 6.1 Initial Survey (Then Read in Full) ```bash wc -l "$UNIT" # Know the size head -50 "$UNIT" # Get oriented tail -20 "$UNIT" # See the end cat "$UNIT" # READ THE ENTIRE FILE ``` ### 6.2 Identify Behaviors ```bash # Domain indicators (informative strings are clues in any language) grep -oE '"[a-zA-Z]{5,}"' "$UNIT" | sort | uniq -c | sort -rn | head -20 # Error messages grep -oE '"[^"]*[Ee]rror[^"]*"' "$UNIT" | sort -u # Common action verbs in method/function invocations grep -oE '\.(read|write|send|receive|parse|validate|handle|process|create|delete|update)\(' "$UNIT" | sort | uniq -c ``` ### 6.3 Catalog Capabilities Use language-appropriate declaration patterns. Read the matches; don't rely on the grep counts alone. ```bash # JavaScript / TypeScript grep -oE "function [a-zA-Z_][a-zA-Z0-9_]*" "$UNIT" grep -oE "(const|let|var) [a-zA-Z_][a-zA-Z0-9_]* = (async )?(function|\()" "$UNIT" grep -oE "class [A-Z][a-zA-Z0-9_]*" "$UNIT" grep -oE "exports\.[a-zA-Z_]+|export (const|function|class|default)" "$UNIT" # Python grep -oE "^(async )?def [a-zA-Z_][a-zA-Z0-9_]*" "$UNIT" grep -oE "^class [A-Z][a-zA-Z0-9_]*" "$UNIT" # Go grep -oE "^func (\([^)]+\) )?[A-Za-z_][A-Za-z0-9_]*" "$UNIT" grep -oE "^type [A-Z][a-zA-Z0-9_]* " "$UNIT" # Rust grep -oE "^(pub )?fn [a-z_][a-z0-9_]*" "$UNIT" grep -oE "^(pub )?(struct|enum|trait) [A-Z][a-zA-Z0-9_]*" "$UNIT" # Swift grep -oE "^(public |private |internal )?func [a-z_][a-zA-Z0-9_]*" "$UNIT" grep -oE "^(public |private |internal )?(class|struct|enum|protocol|actor) [A-Z][a-zA-Z0-9_]*" "$UNIT" # Java / Kotlin grep -oE "^(public |private )?(class|interface|enum) [A-Z][a-zA-Z0-9_]*" "$UNIT" ``` ### 6.4 Find Dependencies ```bash # JavaScript / TypeScript grep -oE "require\(['\"][^'\"]+['\"]\)|from ['\"][^'\"]+['\"]" "$UNIT" # Python grep -oE "^(from [a-zA-Z_][a-zA-Z0-9_.]* )?import [a-zA-Z_][a-zA-Z0-9_., ]*" "$UNIT" # Rust grep -oE "^use [a-zA-Z_][a-zA-Z0-9_:]+" "$UNIT" # Swift grep -oE "^import [A-Z][A-Za-z0-9_]*" "$UNIT" # Java / Kotlin grep -oE "^import [a-z][a-zA-Z0-9_.]+" "$UNIT" # Go: import blocks span multiple lines; read them from the file header head -50 "$UNIT" | awk '/^import [(\"]/,/^\)$/' ``` ### 6.5 Data Flow Look for I/O, state mutations, and event/signal interaction. The specific idioms vary by language and framework: ```bash # I/O operations — common verbs across many languages grep -nE "\.(read|write|get|set|load|save|fetch|send)\b" "$UNIT" | head -20 # Event / signal / pub-sub shapes (varies by language and framework): # Node EventEmitter: .on('name', ...), .emit('name', ...) # Python pyee / blinker: .connect(...), .send(...) # Rust tokio / crossbeam: .notify(...), .subscribe(...) # Swift NotificationCenter: .post(name:...), .addObserver(...) # Generic pub/sub: .publish(...), .subscribe(...), .dispatch(...) grep -nE "\.(on|emit|connect|notify|subscribe|publish|post|dispatch)\(" "$UNIT" | head -20 ``` ### 6.6 Output Template Write the analysis to a path that mirrors the unit's origin: - Bundle target → `workspace/raw/source/analysis/.md` - Source tree → `workspace/raw/source/analysis/.md` ```markdown # Unit Analysis: ## Behavioral Summary [1-2 sentences: What does this unit DO from a user/system perspective?] ## Key Behaviors Identified ### [Behavior 1 Name] - **What it does**: [behavioral description] - **Inputs**: [what it accepts] - **Outputs**: [what it produces] - **Evidence**: [function names, strings that indicate this] ### [Behavior 2 Name] - **What it does**: [behavioral description] - **Inputs**: [what it accepts] - **Outputs**: [what it produces] - **Evidence**: [function names, strings that indicate this] ## Data Handled - Reads: [what data it reads] - Writes: [what data it writes] - Transforms: [what transformations it performs] ## Error Conditions - [Error 1]: "[exact error message]" - when [condition] - [Error 2]: "[exact error message]" - when [condition] ## Dependencies - External: [third-party packages or libraries] - Internal: [other units it references] ## Domain Indicators Key strings that reveal purpose: [informative strings] ## Module Guess This unit likely belongs to the **[module name]** module because: - [reason 1] - [reason 2] ## Needs Deep Dive? - [ ] Yes - complex behavior requiring full spec - [ ] No - utility code, can be summarized ## Key Claims | Claim | Source Location | Confidence | |-------|----------------|------------| | [behavioral claim] | :{line} | inferred | ``` ## Phase 7: Per-Function Deep Analysis (all source shapes) The function-analyzer agent runs once per significant function or method. Each invocation analyzes a single routine exhaustively. `$FUNC` is the path to a file containing the routine: - **Bundle target:** an extracted-function file from Phase B4, e.g. `workspace/raw/source/functions/func-0007-parseConfig.js`. - **Source tree:** either the containing source file (if small) or a single-routine extraction. For long source files, slice out the routine into a tmp file before analysis so that greps scope to the routine and not to the whole module. - **Decompiled binary:** same options as source tree — decompiled code lives on disk as files, so treat it accordingly. ### Exhaustive Reading Requirement (CRITICAL) **You MUST read every single line of the function. No exceptions.** - Do NOT skim. Read every statement. - The grep patterns help you INDEX what you find -- they are NOT a substitute for reading. - Every line of code must be understood. - Every conditional branch must be traced. - Every side effect must be identified. **Verification checklist before writing analysis:** - [ ] I read the ENTIRE function, line by line - [ ] I understand what EVERY statement does - [ ] I traced EVERY conditional branch - [ ] I identified EVERY side effect ### 7.1 Identify Signature and Parameters Read the routine's first lines; the signature is in the declaration. Common shapes: - JavaScript/TypeScript: `function name(params)`, `const name = (params) =>`, `async name(params) {` - Python: `def name(params):`, `async def name(params):` - Go: `func name(params) returns`, `func (receiver) name(params) returns` - Rust: `fn name(params) -> Return`, `pub fn name(params) -> Return` - Swift: `func name(params) -> Return`, `public func name(params) async throws -> Return` - Java/Kotlin: `public Return name(params)`, `fun name(params): Return` ### 7.2 Trace Data Flow ```bash # Parameter identifiers (lowercase tokens are often variables/params) grep -oE '\b[a-z][a-zA-Z0-9_]*\b' "$FUNC" | sort | uniq -c | sort -rn | head -20 # Return points grep -nE "^\s*return\b" "$FUNC" # Call sites (invocations — reads across most languages) grep -oE "[a-zA-Z_][a-zA-Z0-9_]*\s*\(" "$FUNC" | sort | uniq -c | sort -rn | head -20 ``` ### 7.3 Identify Side Effects Idioms are language-specific; adapt: ```bash # File I/O — common names across languages grep -nE "\b(read|write|open|close|unlink|remove|mkdir|makedirs|rename)_?[A-Za-z]*\(" "$FUNC" # Network I/O grep -nE "\b(fetch|request|Get|Post|Send|httpGet|urlopen|reqwest|URLSession)\b" "$FUNC" # State mutations grep -nE "\.(set|push|append|insert|splice|extend|add|update)\(|^\s*[a-zA-Z_][a-zA-Z0-9_.]*\s*=[^=]" "$FUNC" # Logging grep -nE "\b(console\.|log\.|logger\.|println!|eprintln!|log\.Printf|logrus\.|zap\.)" "$FUNC" ``` ### 7.4 Error Handling Idioms differ by language — error values in Go and Rust; exceptions in Python, Java, JavaScript, Swift: ```bash # Exception-based (JS/Python/Java/Swift) grep -nE "\b(throw|raise)\b" "$FUNC" grep -cE "\b(try|catch|except|finally)\b" "$FUNC" # Error-value-based (Go, Rust) grep -nE "\breturn .*err\b|\\?$|\\?;" "$FUNC" grep -nE "\bif err != nil\b|\\bResult<|\\bOption<" "$FUNC" # Guard clauses / precondition checks grep -nE "\bif\s+(err|e|not|!|.*is None|.*== nil)\b" "$FUNC" ``` ### 7.5 Control Flow ```bash # Conditionals grep -c "if (" "$FUNC" grep -c "else" "$FUNC" # Loops grep -c "for (\|while (\|\.forEach\|\.map\|\.filter" "$FUNC" # Early returns grep -n "return" "$FUNC" | head -10 ``` ### 7.6 Output Template Write to `workspace/raw/source/functions//.md`: ```markdown # Function: [name] ## Signature [function signature with parameters] ## Purpose [1-2 sentences: What does this function do?] ## Parameters | Name | Inferred Type | Purpose | |------|---------------|---------| | param1 | string | [what it's used for] | ## Return Value - Type: [inferred] - Description: [what it returns] ## Behavior ### Normal Path 1. [First thing it does] 2. [Second thing it does] 3. [Returns X] ### Error Paths - If [condition]: throws [error] / returns [value] - If [condition]: [behavior] ## Side Effects - [ ] Modifies parameters - [ ] Writes to files - [ ] Makes network calls - [ ] Mutates external state - [ ] Logs output Details: - [specific side effect 1] - [specific side effect 2] ## Dependencies Calls these functions: - `funcName()` - [purpose] - `otherFunc()` - [purpose] ## Key Strings [strings that reveal purpose] ## Complexity - Lines: [X] - Conditionals: [X] - Loops: [X] - Nested depth: [estimate] ## Behavioral Specification **Given:** [preconditions] **When:** function is called with [inputs] **Then:** [outputs and side effects] ## Key Claims | Claim | Source Location | Confidence | |-------|----------------|------------| | [behavioral claim] | :{line} | inferred | ``` ## Phase 8: Targeted Module Extraction When you need focused analysis of a specific component of the target (e.g., "HTTP parser", "error handling", "configuration loader"), rather than analyzing everything in depth. In a bundle, the component is a module identified in Phase B2. In a source tree, it's a named package or directory. In a decompiled binary, it's whichever decompiled files correspond to the focus area. This phase is driven by the targeted-extractor agent. ### 8.1 Scope Assessment Get a rough sense of how much code relates to the focus area: ```bash # Count matches for focus-related terms grep -c "$FOCUS_TERMS" "$TARGET" # Find which line ranges contain clusters of matches grep -n "$FOCUS_TERMS" "$TARGET" | awk -F: '{print int($1/100)*100}' | sort -n | uniq -c | sort -rn | head -20 ``` This reveals which 100-line regions are most relevant. ### 8.2 String Constant Discovery Strings are NEVER minified and reveal the most about behavior: ```bash grep -oE '"[^"]{3,80}"' "$TARGET" | grep -i "$FOCUS_PATTERN" | sort -u ``` Write immediately to `$OUTPUT_DIR/strings.md`. ### 8.3 Identifier Discovery Named identifiers (functions, classes, properties) often survive minification: ```bash # Named functions grep -oE "function [a-zA-Z_]\w*" "$TARGET" | grep -i "$FOCUS_PATTERN" | sort -u # Property assignments (method definitions) grep -oE "\.[a-zA-Z_]\w*\s*=" "$TARGET" | grep -i "$FOCUS_PATTERN" | sort -u # Class definitions grep -oE "class [a-zA-Z_]\w*" "$TARGET" | grep -i "$FOCUS_PATTERN" | sort -u ``` Write immediately to `$OUTPUT_DIR/identifiers.md`. ### 8.4 Code Section Extraction For each cluster of focus-area matches, extract surrounding code with enough context to understand the logic (50-100 lines around matches): ```bash grep -n "$FOCUS_TERM" "$TARGET" | head -30 | while read match; do LINE=$(echo "$match" | cut -d: -f1) START=$((LINE - 50)) END=$((LINE + 50)) [ "$START" -lt 1 ] && START=1 sed -n "${START},${END}p" "$TARGET" echo "--- END EXTRACT (lines $START-$END) ---" done ``` For each extracted section, read and understand it, then write a summary to `$OUTPUT_DIR/sections/section-NNN.md` with: - Line range in beautified file - What this section does (behavioral description) - Key identifiers and strings found - Connections to other sections - Open questions ### 8.5 URL and API Endpoint Extraction ```bash grep -oE '"https?://[^"]*"' "$TARGET" | sort -u grep -oE '"wss?://[^"]*"' "$TARGET" | sort -u grep -oE '"/[a-z][a-z0-9/._-]*"' "$TARGET" | grep -v '\.(js|css|html|png|svg)' | sort -u ``` Write immediately to `$OUTPUT_DIR/endpoints.md`. ### 8.6 Data Structure Extraction ```bash # Object literals with focus-area properties grep -oE '\{[^{}]{10,200}\}' "$TARGET" | grep -i "$FOCUS_PATTERN" | head -30 # Property chains revealing structure grep -oE '\.\w+\.\w+\.\w+' "$TARGET" | grep -i "$FOCUS_PATTERN" | sort | uniq -c | sort -rn | head -30 ``` Write immediately to `$OUTPUT_DIR/data-structures.md`. ### 8.7 Error Messages and States Extraction ```bash # Error strings grep -oE '"[^"]*[Ee]rror[^"]*"' "$TARGET" | grep -i "$FOCUS_PATTERN" | sort -u grep -oE '"[^"]*[Ff]ail[^"]*"' "$TARGET" | grep -i "$FOCUS_PATTERN" | sort -u # Status/state strings grep -oE '"[^"]*[Ss]tatus[^"]*"' "$TARGET" | grep -i "$FOCUS_PATTERN" | sort -u ``` Write immediately to `$OUTPUT_DIR/errors-and-states.md`. ### 8.8 Contextual Analysis After extraction, read the extracted sections and produce a synthesis covering: - **Connection map** -- which sections reference each other; trace call flows and data flows between sections - **State machine** -- if the module manages state, document the states and transitions observed - **Protocol/message catalog** -- if the module involves communication, catalog all message types, their fields, and when they are sent/received - **Configuration points** -- what settings, constants, or configuration values affect this module's behavior Write synthesis to `$OUTPUT_DIR/analysis.md`. ### 8.9 Findings Report Write comprehensive findings to `$OUTPUT_DIR/findings.md`: ```markdown # Targeted Extractor Findings: [Focus Area] ## Target - Source: [path or module identifier] - Focus: [area] ## Summary [2-3 paragraph overview of what was found] ## Key Components ### [Component 1] - Purpose: [what it does] - Location: [file:line range or module/package path] - Key identifiers: [list] - Key strings: [list] ## Data Model [Key data structures and their fields] ## Protocol / API [If applicable: endpoints, message types, wire format] ## State Management [If applicable: states, transitions, persistence] ## Configuration [Settings that affect behavior] ## Error Conditions [What can go wrong and how it's handled] ## Open Questions [Things that need further investigation] ## Cross-References [How this component relates to others in the target] ``` ## Provenance Rules ### Source Type All claims from source code analysis use `source=source-code`: ```markdown - Sessions expire after 30 minutes of inactivity ``` ### Layer 1 Agents -- Single Source Targeted-extractor, chunk-analyzer, and function-analyzer are Layer 1 agents. They examine a single source (the source code). Confidence is typically `inferred` because there is only one source to draw from. ### Confidence Levels - **confirmed** -- exact literal or API call visible in source, OR corroborated by a second independent source (e.g., runtime observation agrees with source reading) - **inferred** -- derived from code logic; single authoritative source provides direct evidence - **assumed** -- based on naming convention, comment text, or structural reasoning; not verified against observable behavior ### Cite As You Go Every behavioral claim gets an inline citation immediately after the claim. Do NOT batch citations at the end of analysis. The moment you write a behavioral assertion, the very next thing you write is the `` comment. ### Key Claims Table End each analysis file with a Key Claims table: ```markdown ## Key Claims | Claim | Source Location | Confidence | |-------|----------------|------------| | Handles session timeout at 30 min | :145 | inferred | | Uses AES-256-GCM for encryption | :302 | confirmed | | Salt length is a fixed 16 bytes | :{line} | inferred | ``` This table is how downstream verification agents trace claims back to source. ## Output Structure Output layout varies by target shape. ### Bundle target ``` workspace/raw/source/ target.js # Original (beautified) bundle chunks/ # Split modules chunk-0001.js chunk-0002.js ... functions/ # Extracted individual functions (>10 lines each) func-0001-processMessage.js func-0002-handleRequest.js ... manifests/ # Inventories chunk-manifest.json function-manifest.json string-manifest.json strings-raw.txt strings-urls.txt strings-constants.txt strings-cli-flags.txt strings-errors.txt function-locations.txt analysis/ # Per-chunk behavioral analysis survey.md chunk-0001.md chunk-0002.md ... functions/ # Per-function behavioral analysis func-0001.md func-0002.md ... exploration/ # Targeted explorations by focus area {focus-area}/ strings.md identifiers.md sections/ section-001.md section-002.md ... endpoints.md data-structures.md errors-and-states.md analysis.md findings.md ``` ### Source tree target ``` workspace/raw/source/ manifests/ module-manifest.json # List of modules, files, lines, language analysis/ # Per-module behavioral analysis survey.md .md # e.g. src-parser-lexer.md .md ... functions/ # Per-function analyses, grouped by module / .md ... exploration/ # Targeted explorations by focus area {focus-area}/ findings.md ``` The module-path convention flattens the source tree into filenames (e.g., `src/parser/lexer.py` → `src-parser-lexer.md`) so the analysis directory stays flat and greppable. ### Decompiled binary target Decompiled binaries are handled by first writing decompiled source to `workspace/raw/source/decompiled/` (preserving the decompiler's output layout), then running the shape-appropriate pipeline above: if the decompiled output is a single large file, treat it as a bundle; if the decompiler produced a tree of files, treat it as a source tree. ## Rules 1. **WRITE AS YOU GO** -- every finding goes to a file immediately. Do not accumulate findings in your head. Use the Write tool the moment you have something to record. 2. **Focus on BEHAVIOR not IMPLEMENTATION** -- write "handles authentication" not "calls authLib.verify()". Describe what the code DOES, not how it is structured. 3. **No raw source code excerpts longer than one line** -- behavioral output must not contain multi-line code snippets. Single-line references are acceptable as evidence. 4. **Flag behavioral complexity** -- note what needs deep-dive analysis. Mark chunks and functions that exhibit complex state management, protocol handling, or multi-step workflows. 5. **Reuse beautified code** -- before beautifying, check if a beautified version already exists at `workspace/raw/source/target.js`. Multiple agents share this file. 6. **Exhaustive reading is mandatory** -- grep patterns are for indexing, not understanding. After running greps, you MUST read the full source. Every function, method, class, and code path must be identified. 7. **Cite as you go** -- every behavioral claim gets an inline `` comment immediately after the claim. Never defer citation to a later step. 8. **One chunk/function per invocation** -- chunk-analyzer processes one chunk. function-analyzer processes one function. Stay focused. 9. **Be targeted in exploration** -- the targeted-extractor stays focused on the requested component. Do not analyze the entire target when only one component is needed. 10. **Note line numbers** -- in the beautified file, so sections can be found again by downstream agents and verification.